From b2dacf060cca0739e8c1d0b5ea984261ccdd53a4 Mon Sep 17 00:00:00 2001 From: Arif Alam Date: Sat, 26 Jul 2025 23:43:17 -0400 Subject: [PATCH] mt76 update Signed-off-by: Arif Alam --- feeds/mediatek-sdk/mt76/Makefile | 112 ++++- ...i-mt76-fix-incorrect-HE-TX-GI-report.patch | 22 +- ...-add-pc-stack-dump-for-WM-s-coredump.patch | 39 +- ...-move-temperature-margin-check-to-mt.patch | 10 +- ...-wifi-mt76-mt7915-fix-txpower-issues.patch | 10 +- ...-Fixed-null-pointer-dereference-issu.patch | 6 +- ...hannel-time-too-long-on-duty-channel.patch | 10 +- ...-add-post-channel-switch-for-DFS-cha.patch | 8 +- ...-add-support-for-realtime-Rx-rate-up.patch | 8 +- ...-remove-redundant-argument-in-add_be.patch | 12 +- ...-add-support-for-WMM-PBC-configurati.patch | 22 +- ...-statistics-about-tx-retry-and-tx-fa.patch | 8 +- ...sanity-check-to-prevent-kernel-crash.patch | 6 +- ...76-mt7915-limit-per-band-token-count.patch | 29 +- ...mt76-mt7915-update-power-on-sequence.patch | 10 +- ...-add-support-for-IEEE-802.11-fragmen.patch | 9 +- ...-add-dummy-HW-offload-of-IEEE-802.11.patch | 12 +- ...-fix-inconsistent-QoS-mapping-betwee.patch | 103 ---- ...fix-rx-filter-setting-for-bfee-func.patch} | 6 +- ...-fix-inconsistent-QoS-mapping-betwee.patch | 144 ++++++ ...19-wifi-mt76-mt7915-adjust-rx-filter.patch | 58 +++ ...add-additional-chain-signal-info-to.patch} | 10 +- ...remove-unnecessary-register-setting.patch} | 32 +- ...-enable-PPDU-TXS-to-update-data-fram.patch | 163 ++++++ ...-fix-add-ba-issue-on-tid-not-equal-t.patch | 77 +++ ...-refactor-check-for-TX-BA-sesstion-s.patch | 101 ++++ ...-delete-twt-flow-before-remove-stati.patch | 38 ++ ...6-do-not-report-ACK-when-TXS-is-lost.patch | 27 + ...ifi-mt76-mt7915-fix-register-mapping.patch | 30 ++ ...-update-adie-patch-in-mt7986-power-o.patch | 61 +++ ...-build-pass-for-Linux-Kernel-5.4-fix.patch | 66 +-- ...-add-mtk-internal-debug-tools-for-mt.patch | 75 ++- ...t76-mt7915-csi-implement-csi-support.patch | 378 +++++++++++--- ...wifi-mt76-mt7915-air-monitor-support.patch | 52 +- ...t7915-add-support-for-muru_onoff-via.patch | 18 +- ...fi-mt76-mt7915-certification-patches.patch | 38 +- ...5-add-mt76-vendor-muru-onoff-command.patch | 18 +- ...6-mt7915-drop-undefined-action-frame.patch | 6 +- ...tmode-rework-testmode-init-registers.patch | 28 +- ...fi-mt76-testmode-additional-supports.patch | 120 +++-- ...fi-mt76-testmode-add-pre-cal-support.patch | 48 +- ...estmode-add-iBF-command-mode-support.patch | 12 +- ...testmode-add-ZWDFS-test-mode-support.patch | 43 +- ...de-add-iBF-eBF-cal-and-cert-commands.patch | 45 +- ...-airtime-fairness-feature-off-in-mac.patch | 6 +- ...15-add-phy-capability-vendor-command.patch | 25 +- ...-add-vendor-subcmd-EDCCA-ctrl-enable.patch | 37 +- ...-mt76-mt7915-implement-bin-file-mode.patch | 22 +- ...wifi-mt76-mt7915-Add-mu-dump-support.patch | 14 +- ...-add-vendor-subcmd-three-wire-PTA-ct.patch | 31 +- ...76-mt7915-add-ibf-control-vendor-cmd.patch | 16 +- ...7915-add-cal-free-data-merge-support.patch | 30 +- ...-support-on-off-SW-ACI-through-debug.patch | 12 +- ...5-add-bf-backoff-limit-table-support.patch | 33 +- ...t76-mt7915-amsdu-set-and-get-control.patch | 22 +- ...-Add-vendor-command-attribute-for-RT.patch | 16 +- ...-add-vendor-cmd-to-get-available-col.patch | 16 +- ...t76-mt7915-disable-SW-ACI-by-default.patch | 23 +- ...5-add-muru-user-number-debug-command.patch | 18 +- ...6-mt7915-add-debugfs-for-fw-coredump.patch | 20 +- ...ifi-mt76-mt7915-remove-BW160-support.patch | 12 +- ...mt7915-add-txpower-info-dump-support.patch | 12 +- ...-report-tx-and-rx-byte-to-tpt_led-wh.patch | 19 +- ...mt76-mt7915-Establish-BA-in-VO-queue.patch | 8 +- ...-Disable-RegDB-when-enable-single-sk.patch | 22 +- ...-enable-the-mac80211-hw-bmc-ps-buffe.patch | 10 +- ...76-update-debugfs-knob-for-tx-tokens.patch | 10 +- ...-support-enable-disable-spatial-reus.patch | 12 +- ...76-mt7915-add-debug-log-for-SER-flow.patch | 12 +- ...add-debuffs-knob-for-protect-thresh.patch} | 10 +- ...5-add-mt7981-efuse-variants-support.patch} | 12 +- ...ifi-mt76-mt7915-support-scs-feature.patch} | 51 +- ...support-thermal-recal-debug-commnad.patch} | 26 +- ...Add-support-for-lpi-and-duplicate-m.patch} | 47 +- ...i-mt76-testmode-add-cheetah-support.patch} | 6 +- ...add-no_beacon-vendor-command-for-ce.patch} | 22 +- ...support-spatial-reuse-debug-command.patch} | 18 +- ...ore-times-when-send-message-timeout.patch} | 21 +- ...-mt76-mt7915-add-SER-overlap-handle.patch} | 21 +- ...5-add-background-radar-hw-cap-check.patch} | 79 +-- ...add-foolproof-mechanism-for-ZWDFS-d.patch} | 8 +- ...915-assign-DEAUTH-to-ALTX-queue-for.patch} | 8 +- ...set-channel-after-sta-is-associated.patch} | 10 +- ...-Clear-private-driver-data-in-case-o.patch | 28 ++ ...-fix-TX-RX-hang-without-SER-hw-bit-t.patch | 132 +++++ ...-remove-rts-and-cts-protection-enabl.patch | 65 +++ ...de-add-interface-addition-deletion-c.patch | 180 +++++++ ...ifi-mt76-mt7915-rework-radar-rdd-idx.patch | 355 +++++++++++++ ...ifi-mt76-testmode-fix-rx-stats-issue.patch | 470 ++++++++++++++++++ ...i-mt76-mt7915-wed-add-wed-tx-support.patch | 21 +- ...-wed-add-wds-support-when-wed-is-ena.patch | 22 +- ...-wed-add-fill-receive-path-to-report.patch | 10 +- ...-wed-find-rx-token-by-physical-addre.patch | 6 +- ...mt7915-wed-HW-ATF-support-for-mt7986.patch | 74 ++- ...-wed-add-rxwi-for-further-in-chip-rr.patch | 28 +- ...bugfs-knob-to-show-packet-error-rate.patch | 20 +- ...6-mt7915-add-ctxd-support-for-mt7916.patch | 8 +- ...-mt76-connac-wed-add-wed-rx-copy-skb.patch | 8 +- ...fi-mt76-mt7915-enable-wa-log-to-uart.patch | 6 +- ...-add-error-message-when-driver-recei.patch | 6 +- ...-wed-change-wed-token-init-size-to-a.patch | 18 +- ...t7915-wed-add-per-bss-statistic-info.patch | 26 +- ...t76-add-debugfs-for-tx-drop-counters.patch | 14 +- ...t76-add-debugfs-for-rx-drop-counters.patch | 30 +- ...t7915-support-backaward-compatiable.patch} | 27 +- ...mt7915-fix-key-used-after-free-issue.patch | 30 ++ ...76-mt7915-refine-twt-mcu-update-flow.patch | 94 ++++ ...-add-sanity-check-to-prevent-invalid.patch | 31 ++ ...-add-debugfs-knob-to-control-ps-ther.patch | 118 +++++ ...5-do-not-set-key-for-cipher-CMAC-128.patch | 33 ++ ...rt-for-backports-5.15-wireless-stack.patch | 240 +++++---- .../mt76/src/firmware/mt7915_rom_patch.bin | Bin 144544 -> 144544 bytes .../mt76/src/firmware/mt7915_wa.bin | Bin 113792 -> 113712 bytes .../mt76/src/firmware/mt7915_wm.bin | Bin 1260960 -> 1260960 bytes .../mt76/src/firmware/mt7916_rom_patch.bin | Bin 8800 -> 8800 bytes .../mt76/src/firmware/mt7916_wa.bin | Bin 504032 -> 504032 bytes .../mt76/src/firmware/mt7916_wm.bin | Bin 1765616 -> 1767568 bytes .../mt76/src/firmware/mt7981_rom_patch.bin | Bin 9952 -> 9824 bytes .../mt76/src/firmware/mt7981_wa.bin | Bin 494208 -> 494208 bytes .../mt76/src/firmware/mt7981_wm.bin | Bin 2054288 -> 2054528 bytes .../mt76/src/firmware/mt7981_wo.bin | Bin 2454304 -> 2454304 bytes .../mt76/src/firmware/mt7986_rom_patch.bin | Bin 13216 -> 13216 bytes .../src/firmware/mt7986_rom_patch_mt7975.bin | Bin 13216 -> 13216 bytes .../mt76/src/firmware/mt7986_wa.bin | Bin 522416 -> 522416 bytes .../mt76/src/firmware/mt7986_wm.bin | Bin 2229264 -> 2229264 bytes .../mt76/src/firmware/mt7986_wm_mt7975.bin | Bin 2229264 -> 2229264 bytes .../mt76/src/firmware/mt7986_wo_0.bin | Bin 2455072 -> 2455072 bytes .../mt76/src/firmware/mt7986_wo_1.bin | Bin 2455072 -> 2455072 bytes 128 files changed, 3814 insertions(+), 1213 deletions(-) delete mode 100644 feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch rename feeds/mediatek-sdk/mt76/patches/{0016-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch => 0017-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch} (83%) create mode 100644 feeds/mediatek-sdk/mt76/patches/0018-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0019-wifi-mt76-mt7915-adjust-rx-filter.patch rename feeds/mediatek-sdk/mt76/patches/{1038-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch => 0020-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch} (73%) rename feeds/mediatek-sdk/mt76/patches/{1050-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch => 0021-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch} (85%) create mode 100644 feeds/mediatek-sdk/mt76/patches/0022-wifi-mt76-mt7915-enable-PPDU-TXS-to-update-data-fram.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-fix-add-ba-issue-on-tid-not-equal-t.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-refactor-check-for-TX-BA-sesstion-s.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0024-wifi-mt76-mt7915-delete-twt-flow-before-remove-stati.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0025-mtk-mt76-do-not-report-ACK-when-TXS-is-lost.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0026-wifi-mt76-mt7915-fix-register-mapping.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/0027-wifi-mt76-mt7915-update-adie-patch-in-mt7986-power-o.patch rename feeds/mediatek-sdk/mt76/patches/{1039-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch => 1038-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch} (88%) rename feeds/mediatek-sdk/mt76/patches/{1040-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch => 1039-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch} (86%) rename feeds/mediatek-sdk/mt76/patches/{1041-wifi-mt76-mt7915-support-scs-feature.patch => 1040-wifi-mt76-mt7915-support-scs-feature.patch} (90%) rename feeds/mediatek-sdk/mt76/patches/{1042-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch => 1041-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch} (85%) rename feeds/mediatek-sdk/mt76/patches/{1043-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch => 1042-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch} (93%) rename feeds/mediatek-sdk/mt76/patches/{1044-wifi-mt76-testmode-add-cheetah-support.patch => 1043-wifi-mt76-testmode-add-cheetah-support.patch} (93%) rename feeds/mediatek-sdk/mt76/patches/{1045-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch => 1044-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch} (87%) rename feeds/mediatek-sdk/mt76/patches/{1046-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch => 1045-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch} (96%) rename feeds/mediatek-sdk/mt76/patches/{1047-wifi-mt76-try-more-times-when-send-message-timeout.patch => 1046-wifi-mt76-try-more-times-when-send-message-timeout.patch} (90%) rename feeds/mediatek-sdk/mt76/patches/{1048-wifi-mt76-mt7915-add-SER-overlap-handle.patch => 1047-wifi-mt76-mt7915-add-SER-overlap-handle.patch} (88%) rename feeds/mediatek-sdk/mt76/patches/{1049-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch => 1048-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch} (58%) rename feeds/mediatek-sdk/mt76/patches/{1051-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch => 1049-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch} (85%) rename feeds/mediatek-sdk/mt76/patches/{1052-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch => 1050-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch} (85%) rename feeds/mediatek-sdk/mt76/patches/{1053-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch => 1051-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch} (86%) create mode 100644 feeds/mediatek-sdk/mt76/patches/1052-wifi-mt76-mt7915-Clear-private-driver-data-in-case-o.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/1054-wifi-mt76-mt7915-remove-rts-and-cts-protection-enabl.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/1055-wifi-mt76-testmode-add-interface-addition-deletion-c.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-mt7915-rework-radar-rdd-idx.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-testmode-fix-rx-stats-issue.patch rename feeds/mediatek-sdk/mt76/patches/{2999-wifi-mt76-mt7915-support-backaward-compatiable.patch => 2015-wifi-mt76-mt7915-support-backaward-compatiable.patch} (58%) create mode 100644 feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-fix-key-used-after-free-issue.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-refine-twt-mcu-update-flow.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/2017-wifi-mt76-mt7915-add-sanity-check-to-prevent-invalid.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/2018-wifi-mt76-mt7915-add-debugfs-knob-to-control-ps-ther.patch create mode 100644 feeds/mediatek-sdk/mt76/patches/2019-wifi-mt76-mt7915-do-not-set-key-for-cipher-CMAC-128.patch diff --git a/feeds/mediatek-sdk/mt76/Makefile b/feeds/mediatek-sdk/mt76/Makefile index aaa0b7413..328ce46e1 100644 --- a/feeds/mediatek-sdk/mt76/Makefile +++ b/feeds/mediatek-sdk/mt76/Makefile @@ -8,9 +8,9 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/openwrt/mt76 PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-04-03 -PKG_SOURCE_VERSION:=1e336a8582dce2ef32ddd440d423e9afef961e71 -PKG_MIRROR_HASH:=48e787bcf0c526d9511375a8a3a77c850de9deca79f6177d2eeea7ca8bd798e2 +PKG_SOURCE_DATE:=2024-07-13 +PKG_SOURCE_VERSION:=3b47d9df427c4833605a172f2a8f0e0012b04c80 +PKG_MIRROR_HASH:=23c3aaa53fb2e088446eb18148a44d3edcd3a0eda1ee41cf5cbf56064ebbee58 PKG_MAINTAINER:=Felix Fietkau PKG_USE_NINJA:=0 @@ -317,23 +317,54 @@ endef define KernelPackage/mt7996e $(KernelPackage/mt76-default) - TITLE:=MediaTek MT7996/MT7995/MT7919 wireless driver - DEPENDS+=@PCI_SUPPORT +kmod-mt76-core +kmod-mt76-connac +kmod-hwmon-core +kmod-thermal +@DRIVER_11AX_SUPPORT +@DRIVER_11BE_SUPPORT + TITLE:=MediaTek MT7996E wireless driver + DEPENDS+=@PCI_SUPPORT +kmod-mt76-connac +kmod-hwmon-core +@DRIVER_11AX_SUPPORT \ + +@KERNEL_RELAY +@DRIVER_11BE_SUPPORT FILES:= $(PKG_BUILD_DIR)/mt7996/mt7996e.ko AUTOLOAD:=$(call AutoProbe,mt7996e) endef +define KernelPackage/mt7992-firmware + $(KernelPackage/mt76-default) + TITLE:=MediaTek MT7992 firmware + DEPENDS+=+kmod-mt7996e +endef + +define KernelPackage/mt7992-23-firmware + $(KernelPackage/mt76-default) + TITLE:=MediaTek MT7996 firmware (2+3 antenna variant) + DEPENDS+=+kmod-mt7996e +endef + +define KernelPackage/mt7996-firmware-common + $(KernelPackage/mt76-default) + TITLE:=MediaTek MT7996 firmware (common files) + HIDDEN:=1 +endef + define KernelPackage/mt7996-firmware $(KernelPackage/mt76-default) TITLE:=MediaTek MT7996 firmware - DEPENDS+=+kmod-mt7996e + DEPENDS+=+kmod-mt7996e +kmod-mt7996-firmware-common +endef + +define KernelPackage/mt7996-233-firmware + $(KernelPackage/mt76-default) + TITLE:=MediaTek MT7996 firmware (2+3+3 antenna variant) + DEPENDS+=+kmod-mt7996e +kmod-mt7996-firmware-common +endef + +define KernelPackage/mt7925-firmware + $(KernelPackage/mt76-default) + TITLE:=MediaTek MT7925 firmware + DEPENDS+=+kmod-mt7925e endef define KernelPackage/mt7925-common $(KernelPackage/mt76-default) TITLE:=MediaTek MT7925 wireless driver common code HIDDEN:=1 - DEPENDS+=+kmod-mt792x-common +@DRIVER_11AX_SUPPORT +kmod-hwmon-core + DEPENDS+=+kmod-mt792x-common +@DRIVER_11AX_SUPPORT +kmod-hwmon-core +@DRIVER_11BE_SUPPORT FILES:= $(PKG_BUILD_DIR)/mt7925/mt7925-common.ko endef @@ -342,7 +373,7 @@ define KernelPackage/mt7925u TITLE:=MediaTek MT7925U wireless driver DEPENDS+=+kmod-mt792x-usb +kmod-mt7925-common FILES:= $(PKG_BUILD_DIR)/mt7925/mt7925u.ko - AUTOLOAD:=$(call AutoProbe,mt7921u) + AUTOLOAD:=$(call AutoProbe,mt7925u) endef define KernelPackage/mt7925e @@ -350,7 +381,7 @@ define KernelPackage/mt7925e TITLE:=MediaTek MT7925e wireless driver DEPENDS+=@PCI_SUPPORT +kmod-mt7925-common FILES:= $(PKG_BUILD_DIR)/mt7925/mt7925e.ko - AUTOLOAD:=$(call AutoProbe,mt7921e) + AUTOLOAD:=$(call AutoProbe,mt7925e) endef define Package/mt76-test @@ -708,22 +739,78 @@ define KernelPackage/mt7922-firmware/install $(1)/lib/firmware/mediatek endef -define KernelPackage/mt7996-firmware/install +define KernelPackage/mt7925-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7925 + cp \ + $(PKG_BUILD_DIR)/firmware/mt7925/WIFI_MT7925_PATCH_MCU_1_1_hdr.bin \ + $(PKG_BUILD_DIR)/firmware/mt7925/WIFI_RAM_CODE_MT7925_1_1.bin \ + $(1)/lib/firmware/mediatek/mt7925 +endef + +define KernelPackage/mt7992-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7996 + cp \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_dsp.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_eeprom.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_eeprom_2i5i.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_eeprom_2i5e.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_rom_patch.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_wa.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_wm.bin \ + $(1)/lib/firmware/mediatek/mt7996 +endef + +define KernelPackage/mt7992-23-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7996 + cp \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_dsp_23.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_eeprom_23.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_eeprom_23_2i5i.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_rom_patch_23.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_wa_23.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7992_wm_23.bin \ + $(1)/lib/firmware/mediatek/mt7996 +endef + +define KernelPackage/mt7996-firmware-common/install $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7996 cp \ $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_dsp.bin \ + $(1)/lib/firmware/mediatek/mt7996 +endef + +define KernelPackage/mt7996-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7996 + cp \ $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_eeprom.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_eeprom_2i5i6i.bin \ $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_rom_patch.bin \ $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_wa.bin \ $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_wm.bin \ $(1)/lib/firmware/mediatek/mt7996 endef +define KernelPackage/mt7996-233-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/mediatek/mt7996 + cp \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_eeprom_233.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_eeprom_233_2i5i6i.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_rom_patch_233.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_wa_233.bin \ + $(PKG_BUILD_DIR)/firmware/mt7996/mt7996_wm_233.bin \ + $(1)/lib/firmware/mediatek/mt7996 +endef + define Package/mt76-test/install mkdir -p $(1)/usr/sbin $(INSTALL_BIN) $(PKG_BUILD_DIR)/tools/mt76-test $(1)/usr/sbin endef +define Build/InstallDev + mkdir -p $(STAGING_DIR_IMAGE) + $(CP) $(PKG_BUILD_DIR)/firmware/mt7981_eeprom_mt7976_dbdc.bin $(STAGING_DIR_IMAGE)/ +endef + $(eval $(call KernelPackage,mt76-core)) $(eval $(call KernelPackage,mt76-usb)) $(eval $(call KernelPackage,mt76x02-usb)) @@ -753,6 +840,7 @@ $(eval $(call KernelPackage,mt7981-firmware)) $(eval $(call KernelPackage,mt7986-firmware)) $(eval $(call KernelPackage,mt7921-firmware)) $(eval $(call KernelPackage,mt7922-firmware)) +$(eval $(call KernelPackage,mt7925-firmware)) $(eval $(call KernelPackage,mt792x-common)) $(eval $(call KernelPackage,mt792x-usb)) $(eval $(call KernelPackage,mt7921-common)) @@ -763,6 +851,10 @@ $(eval $(call KernelPackage,mt7921e)) $(eval $(call KernelPackage,mt7925u)) $(eval $(call KernelPackage,mt7925e)) $(eval $(call KernelPackage,mt7996e)) +$(eval $(call KernelPackage,mt7992-firmware)) +$(eval $(call KernelPackage,mt7992-23-firmware)) +$(eval $(call KernelPackage,mt7996-firmware-common)) $(eval $(call KernelPackage,mt7996-firmware)) +$(eval $(call KernelPackage,mt7996-233-firmware)) $(eval $(call KernelPackage,mt76)) $(eval $(call BuildPackage,mt76-test)) diff --git a/feeds/mediatek-sdk/mt76/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch b/feeds/mediatek-sdk/mt76/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch index 1c9624e72..01fb9956d 100644 --- a/feeds/mediatek-sdk/mt76/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch +++ b/feeds/mediatek-sdk/mt76/patches/0001-wifi-mt76-fix-incorrect-HE-TX-GI-report.patch @@ -1,7 +1,7 @@ -From e9f5961a07a895d18b6158a94d74633c07eab50f Mon Sep 17 00:00:00 2001 +From 67edc0d71c271793b5ab04338abedaab41b8586e Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Thu, 18 May 2023 18:11:37 +0800 -Subject: [PATCH 01/14] wifi: mt76: fix incorrect HE TX GI report +Subject: [PATCH 01/21] wifi: mt76: fix incorrect HE TX GI report Change GI reporting source from static capability to rate-tuning module. @@ -17,7 +17,7 @@ Signed-off-by: Benjamin Lin 7 files changed, 282 insertions(+), 22 deletions(-) diff --git a/mt76.h b/mt76.h -index 2cbea73..92acba9 100644 +index 7dd59db3..bf0770a8 100644 --- a/mt76.h +++ b/mt76.h @@ -282,12 +282,16 @@ struct mt76_queue_ops { @@ -38,10 +38,10 @@ index 2cbea73..92acba9 100644 MT_PHY_TYPE_HE_EXT_SU, MT_PHY_TYPE_HE_TB, diff --git a/mt7915/init.c b/mt7915/init.c -index eee1879..edf83c4 100644 +index f1ef965f..888dbf82 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -673,6 +673,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy) +@@ -674,6 +674,8 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy) struct mt76_phy *mphy = phy->mt76; int ret; @@ -50,7 +50,7 @@ index eee1879..edf83c4 100644 INIT_DELAYED_WORK(&mphy->mac_work, mt7915_mac_work); mt7915_eeprom_parse_hw_cap(dev, phy); -@@ -1206,6 +1208,8 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1204,6 +1206,8 @@ int mt7915_register_device(struct mt7915_dev *dev) dev->phy.dev = dev; dev->phy.mt76 = &dev->mt76.phy; dev->mt76.phy.priv = &dev->phy; @@ -60,7 +60,7 @@ index eee1879..edf83c4 100644 INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work); INIT_LIST_HEAD(&dev->sta_rc_list); diff --git a/mt7915/mac.c b/mt7915/mac.c -index 8008ce3..b915201 100644 +index 8008ce3f..b9152018 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -180,15 +180,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) @@ -188,7 +188,7 @@ index 8008ce3..b915201 100644 mt76_tx_status_check(mphy->dev, false); diff --git a/mt7915/main.c b/mt7915/main.c -index b16a633..e61041d 100644 +index 2624edbb..b2a6278f 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -752,6 +752,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, @@ -220,7 +220,7 @@ index b16a633..e61041d 100644 static void mt7915_tx(struct ieee80211_hw *hw, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index fe54a2f..7df2162 100644 +index 18ba20cf..9774bcce 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -3793,6 +3793,167 @@ out: @@ -392,7 +392,7 @@ index fe54a2f..7df2162 100644 struct cfg80211_he_bss_color *he_bss_color) { diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index b41ac4a..8f36546 100644 +index b41ac4aa..8f365461 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -152,6 +152,61 @@ struct mt7915_mcu_eeprom_info { @@ -466,7 +466,7 @@ index b41ac4a..8f36546 100644 +}; #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index a30d08e..aee30c7 100644 +index a30d08eb..aee30c73 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -137,6 +137,7 @@ struct mt7915_sta { diff --git a/feeds/mediatek-sdk/mt76/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch b/feeds/mediatek-sdk/mt76/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch index 651281ca2..23d2a8638 100644 --- a/feeds/mediatek-sdk/mt76/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch +++ b/feeds/mediatek-sdk/mt76/patches/0002-wifi-mt76-mt7915-add-pc-stack-dump-for-WM-s-coredump.patch @@ -1,22 +1,21 @@ -From c7b5350668962272203b878cfc1ae2754c807d56 Mon Sep 17 00:00:00 2001 +From fc2e7f5745752912872c9648619bc7e677aa5063 Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Mon, 22 May 2023 13:49:37 +0800 -Subject: [PATCH 02/14] wifi: mt76: mt7915: add pc stack dump for WM's - coredump. +Subject: [PATCH] wifi: mt76: mt7915: add pc stack dump for WM's coredump. Signed-off-by: Bo Jiao --- mt76.h | 11 +++ mt76_connac_mcu.c | 9 +++ - mt7915/coredump.c | 169 +++++++++++++++++++++++++++++++--------------- - mt7915/coredump.h | 34 +++++++--- + mt7915/coredump.c | 171 ++++++++++++++++++++++++++++++++-------------- + mt7915/coredump.h | 34 ++++++--- mt7915/mac.c | 33 ++++++--- mt7915/mt7915.h | 2 +- mt7915/regs.h | 20 ++++++ - 7 files changed, 207 insertions(+), 71 deletions(-) + 7 files changed, 209 insertions(+), 71 deletions(-) diff --git a/mt76.h b/mt76.h -index 92acba9..ee14425 100644 +index bf0770a..4fb0787 100644 --- a/mt76.h +++ b/mt76.h @@ -32,6 +32,8 @@ @@ -52,7 +51,7 @@ index 92acba9..ee14425 100644 struct net_device napi_dev; struct net_device tx_napi_dev; diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c -index b35acf8..1ea9798 100644 +index 162c57f..4baaaac 100644 --- a/mt76_connac_mcu.c +++ b/mt76_connac_mcu.c @@ -2941,6 +2941,9 @@ int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm, @@ -86,7 +85,7 @@ index b35acf8..1ea9798 100644 struct mt76_connac2_patch_sec *sec; u32 len, addr, mode; diff --git a/mt7915/coredump.c b/mt7915/coredump.c -index 5daf225..298c1ca 100644 +index 5daf225..78f4c3f 100644 --- a/mt7915/coredump.c +++ b/mt7915/coredump.c @@ -7,7 +7,7 @@ @@ -388,7 +387,7 @@ index 5daf225..298c1ca 100644 } } -@@ -399,13 +458,17 @@ int mt7915_coredump_register(struct mt7915_dev *dev) +@@ -399,13 +458,19 @@ int mt7915_coredump_register(struct mt7915_dev *dev) void mt7915_coredump_unregister(struct mt7915_dev *dev) { @@ -398,18 +397,20 @@ index 5daf225..298c1ca 100644 - dev->coredump.crash_data->memdump_buf_len = 0; - } + int i; ++ struct mt7915_crash_data *crash_data; ++ ++ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) { ++ crash_data = dev->coredump.crash_data[i]; ++ ++ if (!crash_data) ++ continue; - vfree(dev->coredump.crash_data); - dev->coredump.crash_data = NULL; -+ for (i = 0; i < __MT76_RAM_TYPE_MAX; i++) { -+ if (dev->coredump.crash_data[i]->memdump_buf) { -+ vfree(dev->coredump.crash_data[i]->memdump_buf); -+ dev->coredump.crash_data[i]->memdump_buf = NULL; -+ dev->coredump.crash_data[i]->memdump_buf_len = 0; -+ } ++ if (crash_data->memdump_buf) ++ vfree(crash_data->memdump_buf); + -+ vfree(dev->coredump.crash_data[i]); -+ dev->coredump.crash_data[i] = NULL; ++ vfree(crash_data); + } } @@ -637,5 +638,5 @@ index 89ac8e6..7515b23 100644 + #endif -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch b/feeds/mediatek-sdk/mt76/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch index 2e4c7d0f8..dbb5c3f61 100644 --- a/feeds/mediatek-sdk/mt76/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch +++ b/feeds/mediatek-sdk/mt76/patches/0003-wifi-mt76-mt7915-move-temperature-margin-check-to-mt.patch @@ -1,7 +1,7 @@ -From 5201efd8c8527bf4f7f60c8be5d558f847b8c4e4 Mon Sep 17 00:00:00 2001 +From c4f870c030edebe27120d87364a213c9f8f7089c Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Thu, 13 Jul 2023 15:50:00 +0800 -Subject: [PATCH 03/14] wifi: mt76: mt7915: move temperature margin check to +Subject: [PATCH 03/21] wifi: mt76: mt7915: move temperature margin check to mt7915_thermal_temp_store() Originally, we would reduce the 10-degree margin to the restore @@ -17,10 +17,10 @@ Signed-off-by: Howard Hsu 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mt7915/init.c b/mt7915/init.c -index edf83c4..9fe0524 100644 +index 888dbf82..3b352fe9 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -83,12 +83,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev, +@@ -84,12 +84,13 @@ static ssize_t mt7915_thermal_temp_store(struct device *dev, mutex_lock(&phy->dev->mt76.mutex); val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 60, 130); @@ -38,7 +38,7 @@ index edf83c4..9fe0524 100644 return -EINVAL; } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 7df2162..6e9970c 100644 +index 9774bcce..dcf8782a 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -3226,8 +3226,7 @@ int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy) diff --git a/feeds/mediatek-sdk/mt76/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch b/feeds/mediatek-sdk/mt76/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch index 06dbcd824..a93ff89fe 100644 --- a/feeds/mediatek-sdk/mt76/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch +++ b/feeds/mediatek-sdk/mt76/patches/0004-wifi-mt76-mt7915-fix-txpower-issues.patch @@ -1,7 +1,7 @@ -From 81f7cb7c452f3e3cce7818bfd0547fc57c280dce Mon Sep 17 00:00:00 2001 +From 349e821372153fddd6abcd295e50753e5f040f1f Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Sat, 29 Jul 2023 04:53:47 +0800 -Subject: [PATCH 04/14] wifi: mt76: mt7915: fix txpower issues +Subject: [PATCH 04/21] wifi: mt76: mt7915: fix txpower issues --- eeprom.c | 2 +- @@ -10,7 +10,7 @@ Subject: [PATCH 04/14] wifi: mt76: mt7915: fix txpower issues 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/eeprom.c b/eeprom.c -index 0bc66cc..ecd09c0 100644 +index 0bc66cc1..ecd09c03 100644 --- a/eeprom.c +++ b/eeprom.c @@ -343,7 +343,7 @@ s8 mt76_get_rate_power_limits(struct mt76_phy *phy, @@ -23,7 +23,7 @@ index 0bc66cc..ecd09c0 100644 if (!mcs_rates) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 5780138..894e2cd 100644 +index 57801388..894e2cd7 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -951,9 +951,9 @@ mt7915_xmit_queues_show(struct seq_file *file, void *data) @@ -107,7 +107,7 @@ index 5780138..894e2cd 100644 reg = is_mt7915(&dev->mt76) ? MT_WF_PHY_TPC_CTRL_STAT(band) : MT_WF_PHY_TPC_CTRL_STAT_MT7916(band); diff --git a/mt7915/main.c b/mt7915/main.c -index e61041d..1903db4 100644 +index b2a6278f..a2ad918d 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -1080,6 +1080,7 @@ mt7915_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) diff --git a/feeds/mediatek-sdk/mt76/patches/0005-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch b/feeds/mediatek-sdk/mt76/patches/0005-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch index a30ec46ff..81601e436 100644 --- a/feeds/mediatek-sdk/mt76/patches/0005-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch +++ b/feeds/mediatek-sdk/mt76/patches/0005-wifi-mt76-mt7915-Fixed-null-pointer-dereference-issu.patch @@ -1,7 +1,7 @@ -From d4b6226c74988932d9df8f1a6b5afbcea7effc38 Mon Sep 17 00:00:00 2001 +From 7b49a07b4440843e3a85c268d3526b410ebf061e Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Thu, 26 Oct 2023 21:11:05 +0800 -Subject: [PATCH 05/14] wifi: mt76: mt7915: Fixed null pointer dereference +Subject: [PATCH 05/21] wifi: mt76: mt7915: Fixed null pointer dereference issue Without this patch, when the station is still in Authentication stage and @@ -17,7 +17,7 @@ Signed-off-by: MeiChia Chiu 1 file changed, 7 insertions(+) diff --git a/mt7915/main.c b/mt7915/main.c -index 1903db4..61a1dbb 100644 +index a2ad918d..ec2360c3 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -1170,9 +1170,16 @@ static void mt7915_sta_rc_update(struct ieee80211_hw *hw, diff --git a/feeds/mediatek-sdk/mt76/patches/0006-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch b/feeds/mediatek-sdk/mt76/patches/0006-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch index 114ee03bb..ac20c29d4 100644 --- a/feeds/mediatek-sdk/mt76/patches/0006-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch +++ b/feeds/mediatek-sdk/mt76/patches/0006-wifi-mt76-ACS-channel-time-too-long-on-duty-channel.patch @@ -1,7 +1,7 @@ -From dbc2448c773d6c2e8a36513a0c855ff0775f5ec4 Mon Sep 17 00:00:00 2001 +From b6f567e8d4223c309134df14c577f0adee2044bf Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Sat, 18 Nov 2023 07:36:45 +0800 -Subject: [PATCH 06/14] wifi: mt76: ACS channel time too long on duty channel +Subject: [PATCH 06/21] wifi: mt76: ACS channel time too long on duty channel Issue: There's a chance that the channel time for duty channel is zero in ACS @@ -26,10 +26,10 @@ scan done and before restore to duty channel. 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mac80211.c b/mac80211.c -index e7b763b..bc20f60 100644 +index 94e85ed9..aee6f1e7 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -927,6 +927,7 @@ void mt76_set_channel(struct mt76_phy *phy) +@@ -928,6 +928,7 @@ void mt76_set_channel(struct mt76_phy *phy) struct cfg80211_chan_def *chandef = &hw->conf.chandef; bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL; int timeout = HZ / 5; @@ -37,7 +37,7 @@ index e7b763b..bc20f60 100644 wait_event_timeout(dev->tx_wait, !mt76_has_tx_pending(phy), timeout); mt76_update_survey(phy); -@@ -941,7 +942,7 @@ void mt76_set_channel(struct mt76_phy *phy) +@@ -942,7 +943,7 @@ void mt76_set_channel(struct mt76_phy *phy) if (!offchannel) phy->main_chan = chandef->chan; diff --git a/feeds/mediatek-sdk/mt76/patches/0007-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch b/feeds/mediatek-sdk/mt76/patches/0007-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch index 1151befcf..c40f2aec8 100644 --- a/feeds/mediatek-sdk/mt76/patches/0007-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch +++ b/feeds/mediatek-sdk/mt76/patches/0007-wifi-mt76-mt7915-add-post-channel-switch-for-DFS-cha.patch @@ -1,7 +1,7 @@ -From 72e729e50f4b162db845e988275b91db2d558ef1 Mon Sep 17 00:00:00 2001 +From d5a9af18ab8f2c8c6a46c10ef99f2a50e08ae9c3 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 16 Nov 2023 14:41:54 +0800 -Subject: [PATCH 07/14] wifi: mt76: mt7915: add post channel switch for DFS +Subject: [PATCH 07/21] wifi: mt76: mt7915: add post channel switch for DFS channel switching Signed-off-by: StanleyYP Wang @@ -10,7 +10,7 @@ Signed-off-by: StanleyYP Wang 1 file changed, 22 insertions(+) diff --git a/mt7915/main.c b/mt7915/main.c -index 61a1dbb..71e0d55 100644 +index ec2360c3..0d24e74c 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -736,6 +736,27 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw, @@ -41,7 +41,7 @@ index 61a1dbb..71e0d55 100644 int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { -@@ -1701,6 +1722,7 @@ const struct ieee80211_ops mt7915_ops = { +@@ -1705,6 +1726,7 @@ const struct ieee80211_ops mt7915_ops = { .get_txpower = mt76_get_txpower, .set_sar_specs = mt7915_set_sar_specs, .channel_switch_beacon = mt7915_channel_switch_beacon, diff --git a/feeds/mediatek-sdk/mt76/patches/0008-wifi-mt76-mt7915-add-support-for-realtime-Rx-rate-up.patch b/feeds/mediatek-sdk/mt76/patches/0008-wifi-mt76-mt7915-add-support-for-realtime-Rx-rate-up.patch index c17f0f461..a5a024173 100644 --- a/feeds/mediatek-sdk/mt76/patches/0008-wifi-mt76-mt7915-add-support-for-realtime-Rx-rate-up.patch +++ b/feeds/mediatek-sdk/mt76/patches/0008-wifi-mt76-mt7915-add-support-for-realtime-Rx-rate-up.patch @@ -1,7 +1,7 @@ -From 0e87f52e13e654b144c12e3aad968fbc3da5ac1b Mon Sep 17 00:00:00 2001 +From 2b85ea7a8f85c36709442d5ebab72bded582d5cd Mon Sep 17 00:00:00 2001 From: "Henry.Yen" Date: Mon, 8 Jan 2024 17:19:01 +0800 -Subject: [PATCH 08/14] wifi: mt76: mt7915: add support for realtime Rx rate +Subject: [PATCH 08/21] wifi: mt76: mt7915: add support for realtime Rx rate updates Add support for realtime Rx rate updates. @@ -19,7 +19,7 @@ Signed-off-by: Henry.Yen 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mt76_connac.h b/mt76_connac.h -index 91987bd..4871857 100644 +index 445d0f0a..5028e49a 100644 --- a/mt76_connac.h +++ b/mt76_connac.h @@ -260,6 +260,12 @@ static inline bool is_connac_v1(struct mt76_dev *dev) @@ -36,7 +36,7 @@ index 91987bd..4871857 100644 { switch (mt76_chip(dev)) { diff --git a/mt7915/main.c b/mt7915/main.c -index 71e0d55..5d31f5a 100644 +index 0d24e74c..645d9779 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -1118,7 +1118,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, diff --git a/feeds/mediatek-sdk/mt76/patches/0009-wifi-mt76-mt7915-remove-redundant-argument-in-add_be.patch b/feeds/mediatek-sdk/mt76/patches/0009-wifi-mt76-mt7915-remove-redundant-argument-in-add_be.patch index 2d608c693..9125ae351 100644 --- a/feeds/mediatek-sdk/mt76/patches/0009-wifi-mt76-mt7915-remove-redundant-argument-in-add_be.patch +++ b/feeds/mediatek-sdk/mt76/patches/0009-wifi-mt76-mt7915-remove-redundant-argument-in-add_be.patch @@ -1,7 +1,7 @@ -From 995dd81673e89e6b387d256e26a0cf07e2ccb0e5 Mon Sep 17 00:00:00 2001 +From bc85ec5a69b6e57eab15c50b54e0603a0829d102 Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Wed, 24 Jan 2024 15:04:33 +0800 -Subject: [PATCH 09/14] wifi: mt76: mt7915: remove redundant argument in +Subject: [PATCH 09/21] wifi: mt76: mt7915: remove redundant argument in add_beacon function Remove redundant argument "changed". @@ -15,7 +15,7 @@ Signed-off-by: MeiChia Chiu 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 0f6b806..ada3a7f 100644 +index 0f6b8067..ada3a7f4 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -1285,8 +1285,7 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif) @@ -29,7 +29,7 @@ index 0f6b806..ada3a7f 100644 default: break; diff --git a/mt7915/main.c b/mt7915/main.c -index 5d31f5a..9eeca39 100644 +index 645d9779..f0491d66 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -659,7 +659,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, @@ -51,7 +51,7 @@ index 5d31f5a..9eeca39 100644 } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 6e9970c..84ffe07 100644 +index dcf8782a..a71562fb 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -1970,8 +1970,7 @@ mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, @@ -65,7 +65,7 @@ index 6e9970c..84ffe07 100644 struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_phy *phy = mt7915_hw_phy(hw); diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 5cd2b33..e1801d5 100644 +index 5cd2b334..e1801d5b 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -461,7 +461,7 @@ int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vi diff --git a/feeds/mediatek-sdk/mt76/patches/0010-wifi-mt76-mt7915-add-support-for-WMM-PBC-configurati.patch b/feeds/mediatek-sdk/mt76/patches/0010-wifi-mt76-mt7915-add-support-for-WMM-PBC-configurati.patch index b4c617944..04fe37e1a 100644 --- a/feeds/mediatek-sdk/mt76/patches/0010-wifi-mt76-mt7915-add-support-for-WMM-PBC-configurati.patch +++ b/feeds/mediatek-sdk/mt76/patches/0010-wifi-mt76-mt7915-add-support-for-WMM-PBC-configurati.patch @@ -1,7 +1,7 @@ -From 9c7177584089b98089142568514af4b23e0d4e72 Mon Sep 17 00:00:00 2001 +From 664d47ddcc7ed90b5d2d73b2040759bf0bf75714 Mon Sep 17 00:00:00 2001 From: Benjamin Lin Date: Mon, 29 Jan 2024 11:28:41 +0800 -Subject: [PATCH 10/14] wifi: mt76: mt7915: add support for WMM PBC +Subject: [PATCH 10/21] wifi: mt76: mt7915: add support for WMM PBC configuration --- @@ -14,10 +14,10 @@ Subject: [PATCH 10/14] wifi: mt76: mt7915: add support for WMM PBC 6 files changed, 127 insertions(+) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 67be14d..1dd8244 100644 +index 6873ce14..46dcd1c6 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1025,6 +1025,7 @@ enum { +@@ -1026,6 +1026,7 @@ enum { MCU_EXT_EVENT_ASSERT_DUMP = 0x23, MCU_EXT_EVENT_RDD_REPORT = 0x3a, MCU_EXT_EVENT_CSA_NOTIFY = 0x4f, @@ -25,7 +25,7 @@ index 67be14d..1dd8244 100644 MCU_EXT_EVENT_WA_TX_STAT = 0x74, MCU_EXT_EVENT_BCC_NOTIFY = 0x75, MCU_EXT_EVENT_MURU_CTRL = 0x9f, -@@ -1220,6 +1221,7 @@ enum { +@@ -1222,6 +1223,7 @@ enum { MCU_EXT_CMD_TXDPD_CAL = 0x60, MCU_EXT_CMD_CAL_CACHE = 0x67, MCU_EXT_CMD_RED_ENABLE = 0x68, @@ -34,10 +34,10 @@ index 67be14d..1dd8244 100644 MCU_EXT_CMD_SET_RADAR_TH = 0x7c, MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, diff --git a/mt7915/init.c b/mt7915/init.c -index 9fe0524..f81a2f2 100644 +index 3b352fe9..46762827 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -1221,6 +1221,8 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1219,6 +1219,8 @@ int mt7915_register_device(struct mt7915_dev *dev) INIT_WORK(&dev->dump_work, mt7915_mac_dump_work); mutex_init(&dev->dump_mutex); @@ -47,7 +47,7 @@ index 9fe0524..f81a2f2 100644 phy2 = mt7915_alloc_ext_phy(dev); diff --git a/mt7915/mac.c b/mt7915/mac.c -index ada3a7f..e167e7b 100644 +index ada3a7f4..e167e7b6 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -2032,6 +2032,8 @@ void mt7915_mac_work(struct work_struct *work) @@ -79,7 +79,7 @@ index ada3a7f..e167e7b 100644 if (++phy->stats_work_count == 10) { diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 84ffe07..446c512 100644 +index a71562fb..9126e62f 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -354,6 +354,93 @@ mt7915_mcu_rx_bcc_notify(struct mt7915_dev *dev, struct sk_buff *skb) @@ -187,7 +187,7 @@ index 84ffe07..446c512 100644 break; } diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 8f36546..fa0847d 100644 +index 8f365461..fa0847d5 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -329,10 +329,25 @@ enum { @@ -217,7 +217,7 @@ index 8f36546..fa0847d 100644 }; diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index e1801d5..89156f3 100644 +index e1801d5b..89156f35 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -326,6 +326,9 @@ struct mt7915_dev { diff --git a/feeds/mediatek-sdk/mt76/patches/0011-wifi-mt76-fix-tx-statistics-about-tx-retry-and-tx-fa.patch b/feeds/mediatek-sdk/mt76/patches/0011-wifi-mt76-fix-tx-statistics-about-tx-retry-and-tx-fa.patch index 04b333264..238b45295 100644 --- a/feeds/mediatek-sdk/mt76/patches/0011-wifi-mt76-fix-tx-statistics-about-tx-retry-and-tx-fa.patch +++ b/feeds/mediatek-sdk/mt76/patches/0011-wifi-mt76-fix-tx-statistics-about-tx-retry-and-tx-fa.patch @@ -1,7 +1,7 @@ -From 3bbf19ff34cd0d7ef3371b49101bbcaf9d068668 Mon Sep 17 00:00:00 2001 +From 1587828e06491339654d20dea3382749fde143ed Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 29 Jan 2024 11:02:06 +0800 -Subject: [PATCH 11/14] wifi: mt76: fix tx statistics about tx retry and tx +Subject: [PATCH 11/21] wifi: mt76: fix tx statistics about tx retry and tx fail The tx retry and tx failed are reported by PPDU TxS. @@ -13,7 +13,7 @@ Signed-off-by: Peter Chiu 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index b841bf6..630c640 100644 +index b841bf62..630c6402 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c @@ -716,9 +716,6 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid, @@ -27,7 +27,7 @@ index b841bf6..630c640 100644 skb = mt76_tx_status_skb_get(dev, wcid, pid, &list); if (skb) { diff --git a/mt7915/mac.c b/mt7915/mac.c -index e167e7b..a5d0b09 100644 +index e167e7b6..a5d0b096 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -1021,7 +1021,7 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/0012-wifi-mt76-add-sanity-check-to-prevent-kernel-crash.patch b/feeds/mediatek-sdk/mt76/patches/0012-wifi-mt76-add-sanity-check-to-prevent-kernel-crash.patch index 034e354b5..576cf69a7 100644 --- a/feeds/mediatek-sdk/mt76/patches/0012-wifi-mt76-add-sanity-check-to-prevent-kernel-crash.patch +++ b/feeds/mediatek-sdk/mt76/patches/0012-wifi-mt76-add-sanity-check-to-prevent-kernel-crash.patch @@ -1,7 +1,7 @@ -From fa15f886fd427e2de3e09ef5c93743e611483adf Mon Sep 17 00:00:00 2001 +From 65092f531e1319ed6ddb25e982393eddccb781b5 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 29 Jan 2024 15:33:24 +0800 -Subject: [PATCH 12/14] wifi: mt76: add sanity check to prevent kernel crash +Subject: [PATCH 12/21] wifi: mt76: add sanity check to prevent kernel crash wcid may not be initialized when mac80211 calls mt76.tx and it would lead to kernel crash. @@ -12,7 +12,7 @@ Signed-off-by: Peter Chiu 1 file changed, 8 insertions(+) diff --git a/tx.c b/tx.c -index 5cf6ede..ab42f69 100644 +index 5cf6edee..ab42f69b 100644 --- a/tx.c +++ b/tx.c @@ -345,6 +345,14 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, diff --git a/feeds/mediatek-sdk/mt76/patches/0013-wifi-mt76-mt7915-limit-per-band-token-count.patch b/feeds/mediatek-sdk/mt76/patches/0013-wifi-mt76-mt7915-limit-per-band-token-count.patch index ee848e6a4..167f36cdd 100644 --- a/feeds/mediatek-sdk/mt76/patches/0013-wifi-mt76-mt7915-limit-per-band-token-count.patch +++ b/feeds/mediatek-sdk/mt76/patches/0013-wifi-mt76-mt7915-limit-per-band-token-count.patch @@ -1,15 +1,26 @@ -From ef9b267adeee3803ae8ee3073d2ebcbd3e1c95f9 Mon Sep 17 00:00:00 2001 +From a2f8deaaf6a97b0157e49ec476b003ef1dd234f8 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 29 Jan 2024 15:33:24 +0800 -Subject: [PATCH] wifi: mt76: mt7915: limit per-band token count +Subject: [PATCH 13/21] wifi: mt76: mt7915: limit per-band token count Add a threshold for per-band token count to prevent a band from interfering with the other band. Signed-off-by: Peter Chiu +--- + mt76.h | 8 +++++++- + mt76_connac_mac.c | 2 ++ + mt7915/init.c | 3 +++ + mt7915/mac.c | 3 ++- + mt7921/pci_mac.c | 2 +- + mt7925/pci_mac.c | 2 +- + mt7996/init.c | 5 +++++ + mt7996/mac.c | 3 ++- + tx.c | 20 ++++++++++++++++++-- + 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/mt76.h b/mt76.h -index ee14425d..b83456b4 100644 +index 4fb07877..05ee568c 100644 --- a/mt76.h +++ b/mt76.h @@ -407,6 +407,8 @@ struct mt76_txwi_cache { @@ -38,7 +49,7 @@ index ee14425d..b83456b4 100644 spinlock_t rx_token_lock; struct idr rx_token; -@@ -1662,7 +1667,8 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) +@@ -1674,7 +1679,8 @@ static inline bool mt76_queue_is_wed_rx(struct mt76_queue *q) struct mt76_txwi_cache * mt76_token_release(struct mt76_dev *dev, int token, bool *wake); @@ -62,10 +73,10 @@ index 630c6402..a92c261d 100644 spin_unlock_bh(&dev->token_lock); idr_destroy(&dev->token); diff --git a/mt7915/init.c b/mt7915/init.c -index f81a2f2f..3ec9eab7 100644 +index 46762827..ea9bc735 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -1225,6 +1225,8 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1223,6 +1223,8 @@ int mt7915_register_device(struct mt7915_dev *dev) dev->dbdc_support = mt7915_band_config(dev); @@ -74,7 +85,7 @@ index f81a2f2f..3ec9eab7 100644 phy2 = mt7915_alloc_ext_phy(dev); if (IS_ERR(phy2)) return PTR_ERR(phy2); -@@ -1257,6 +1259,7 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1255,6 +1257,7 @@ int mt7915_register_device(struct mt7915_dev *dev) } dev->recovery.hw_init_done = true; @@ -130,10 +141,10 @@ index 9fca8879..f1d615c0 100644 return id; diff --git a/mt7996/init.c b/mt7996/init.c -index 9aa97e4a..7549a108 100644 +index 283df84f..d191a7b7 100644 --- a/mt7996/init.c +++ b/mt7996/init.c -@@ -634,6 +634,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy, +@@ -635,6 +635,8 @@ static int mt7996_register_phy(struct mt7996_dev *dev, struct mt7996_phy *phy, mtk_wed_device_start(&dev->mt76.mmio.wed_hif2, irq_mask); } diff --git a/feeds/mediatek-sdk/mt76/patches/0014-wifi-mt76-mt7915-update-power-on-sequence.patch b/feeds/mediatek-sdk/mt76/patches/0014-wifi-mt76-mt7915-update-power-on-sequence.patch index 4c2f703b2..5f53feb89 100644 --- a/feeds/mediatek-sdk/mt76/patches/0014-wifi-mt76-mt7915-update-power-on-sequence.patch +++ b/feeds/mediatek-sdk/mt76/patches/0014-wifi-mt76-mt7915-update-power-on-sequence.patch @@ -1,7 +1,7 @@ -From c3b0d9d6116df31a11d18e42e7227bf516c104f9 Mon Sep 17 00:00:00 2001 +From 55dd46f8caed3d8baa6819d884a1e82c496083f5 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Thu, 14 Mar 2024 17:55:12 +0800 -Subject: [PATCH 14/14] wifi: mt76: mt7915: update power on sequence +Subject: [PATCH 14/21] wifi: mt76: mt7915: update power on sequence Update power on sequence to prevent unexpected behavior. @@ -13,7 +13,7 @@ Signed-off-by: Peter Chiu 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 89156f3..74cd8ca 100644 +index 89156f35..74cd8caf 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -329,6 +329,7 @@ struct mt7915_dev { @@ -25,7 +25,7 @@ index 89156f3..74cd8ca 100644 enum { diff --git a/mt7915/regs.h b/mt7915/regs.h -index 7515b23..3452a7e 100644 +index 7515b23f..3452a7e9 100644 --- a/mt7915/regs.h +++ b/mt7915/regs.h @@ -775,6 +775,7 @@ enum offs_rev { @@ -45,7 +45,7 @@ index 7515b23..3452a7e 100644 /* ADIE */ #define MT_ADIE_CHIP_ID 0x02c diff --git a/mt7915/soc.c b/mt7915/soc.c -index 92d8d71..bb3468a 100644 +index 92d8d710..bb3468a9 100644 --- a/mt7915/soc.c +++ b/mt7915/soc.c @@ -260,6 +260,7 @@ static int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable) diff --git a/feeds/mediatek-sdk/mt76/patches/0015-wifi-mt76-mt7915-add-support-for-IEEE-802.11-fragmen.patch b/feeds/mediatek-sdk/mt76/patches/0015-wifi-mt76-mt7915-add-support-for-IEEE-802.11-fragmen.patch index ab924eb94..c28e51e81 100644 --- a/feeds/mediatek-sdk/mt76/patches/0015-wifi-mt76-mt7915-add-support-for-IEEE-802.11-fragmen.patch +++ b/feeds/mediatek-sdk/mt76/patches/0015-wifi-mt76-mt7915-add-support-for-IEEE-802.11-fragmen.patch @@ -1,7 +1,8 @@ -From 7b7d9e3ef08ce5526d43d657cb717b471002b087 Mon Sep 17 00:00:00 2001 +From 22225104ac30af79661bf46c04e8c9523c2d22fd Mon Sep 17 00:00:00 2001 From: Benjamin Lin Date: Wed, 3 Apr 2024 14:05:59 +0800 -Subject: [PATCH] wifi: mt76: mt7915: add support for IEEE 802.11 fragmentation +Subject: [PATCH 15/21] wifi: mt76: mt7915: add support for IEEE 802.11 + fragmentation Add fragmentation index into TXD.DW2 to support IEEE 802.11 fragmentation. @@ -12,7 +13,7 @@ Signed-off-by: Benjamin Lin 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h -index 5f13211..eb47653 100644 +index 5f132115..eb476536 100644 --- a/mt76_connac2_mac.h +++ b/mt76_connac2_mac.h @@ -355,4 +355,11 @@ enum tx_port_idx { @@ -28,7 +29,7 @@ index 5f13211..eb47653 100644 + #endif /* __MT76_CONNAC2_MAC_H */ diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index 630c640..d7d602a 100644 +index a92c261d..170ef367 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c @@ -391,6 +391,7 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, diff --git a/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-add-dummy-HW-offload-of-IEEE-802.11.patch b/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-add-dummy-HW-offload-of-IEEE-802.11.patch index b062d4055..d1a11c462 100644 --- a/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-add-dummy-HW-offload-of-IEEE-802.11.patch +++ b/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-add-dummy-HW-offload-of-IEEE-802.11.patch @@ -1,7 +1,7 @@ -From 239f1a1bb8eedd9f24dd3abcb801dceac7fe7ffb Mon Sep 17 00:00:00 2001 +From 9db10864ac1dbdc802e563fc6d8752c8b275c302 Mon Sep 17 00:00:00 2001 From: Benjamin Lin Date: Wed, 17 Apr 2024 10:47:08 +0800 -Subject: [PATCH] wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 +Subject: [PATCH 16/21] wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 fragmentation Currently, CONNAC2 series do not support encryption for fragmented Tx frames. @@ -14,10 +14,10 @@ Signed-off-by: Benjamin Lin 2 files changed, 8 insertions(+) diff --git a/mt7915/init.c b/mt7915/init.c -index 3ec9eab..19a68c5 100644 +index ea9bc735..470b198a 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -398,6 +398,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -399,6 +399,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD); ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); ieee80211_hw_set(hw, WANT_MONITOR_VIF); @@ -26,7 +26,7 @@ index 3ec9eab..19a68c5 100644 hw->max_tx_fragments = 4; diff --git a/mt7915/main.c b/mt7915/main.c -index 9eeca39..5224d83 100644 +index f0491d66..f4673c8d 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -1614,6 +1614,12 @@ mt7915_twt_teardown_request(struct ieee80211_hw *hw, @@ -42,7 +42,7 @@ index 9eeca39..5224d83 100644 static int mt7915_set_radar_background(struct ieee80211_hw *hw, struct cfg80211_chan_def *chandef) -@@ -1741,6 +1747,7 @@ const struct ieee80211_ops mt7915_ops = { +@@ -1745,6 +1751,7 @@ const struct ieee80211_ops mt7915_ops = { .sta_set_decap_offload = mt7915_sta_set_decap_offload, .add_twt_setup = mt7915_mac_add_twt_setup, .twt_teardown_request = mt7915_twt_teardown_request, diff --git a/feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch b/feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch deleted file mode 100644 index d4d3d2e82..000000000 --- a/feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 9c6e5082d5552ac2cefe5b4857da4b29b0c76685 Mon Sep 17 00:00:00 2001 -From: Benjamin Lin -Date: Thu, 25 Apr 2024 17:17:13 +0800 -Subject: [PATCH] wifi: mt76: mt7915: fix inconsistent QoS mapping between SW - and HW - -The mapping from IP DSCP to IEEE 802.11 user priority may be customized. -Therefore, driver needs to pass the mapping to HW, so that the QoS type of traffic can be mapped in a consistent manner for both SW and HW paths. - -Signed-off-by: Benjamin Lin ---- - mt76_connac_mcu.h | 1 + - mt7915/main.c | 3 +++ - mt7915/mcu.c | 37 +++++++++++++++++++++++++++++++++++++ - mt7915/mt7915.h | 1 + - 4 files changed, 42 insertions(+) - -diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 1dd8244..0936c1c 100644 ---- a/mt76_connac_mcu.h -+++ b/mt76_connac_mcu.h -@@ -1236,6 +1236,7 @@ enum { - MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab, - MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac, - MCU_EXT_CMD_PHY_STAT_INFO = 0xad, -+ MCU_EXT_CMD_SET_QOS_MAP = 0xb4, - }; - - enum { -diff --git a/mt7915/main.c b/mt7915/main.c -index 5ed84bc..26f9a5a 100644 ---- a/mt7915/main.c -+++ b/mt7915/main.c -@@ -646,6 +646,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, - } - } - -+ if (changed & BSS_CHANGED_QOS) -+ mt7915_mcu_set_qos_map(dev, vif); -+ - /* ensure that enable txcmd_mode after bss_info */ - if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED)) - mt7915_mcu_set_tx(dev, vif); -diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 446c512..3d7fc6d 100644 ---- a/mt7915/mcu.c -+++ b/mt7915/mcu.c -@@ -4212,3 +4212,40 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) - - return 0; - } -+ -+int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) -+{ -+#define IP_DSCP_NUM 64 -+ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; -+ struct { -+ u8 bss_idx; -+ u8 qos_map_enable; -+ u8 __rsv[2]; -+ s8 qos_map[IP_DSCP_NUM]; -+ } __packed req = { -+ .bss_idx = mvif->mt76.idx, -+ .qos_map_enable = false, -+ }; -+ struct cfg80211_qos_map *qos_map; -+ -+ rcu_read_lock(); -+ qos_map = ieee80211_get_qos_map(vif); -+ if (qos_map) { -+ struct cfg80211_dscp_range *dscp_range = qos_map->up; -+ s8 up; -+ -+ req.qos_map_enable = true; -+ for (up = 0; up < IEEE80211_NUM_UPS; ++up) { -+ u8 low = dscp_range[up].low, high = dscp_range[up].high; -+ -+ if (low >= IP_DSCP_NUM || high >= IP_DSCP_NUM || low > high) -+ continue; -+ -+ memset(req.qos_map + low, up, high - low + 1); -+ } -+ } -+ rcu_read_unlock(); -+ -+ return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP), &req, -+ sizeof(req), true); -+} -diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 74cd8ca..66d87d7 100644 ---- a/mt7915/mt7915.h -+++ b/mt7915/mt7915.h -@@ -521,6 +521,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); - void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); - void mt7915_mcu_exit(struct mt7915_dev *dev); - void mt7915_mcu_wmm_pbc_work(struct work_struct *work); -+int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif); - - static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) - { --- -2.18.0 - diff --git a/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch b/feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch similarity index 83% rename from feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch rename to feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch index f223d89e0..706b10782 100644 --- a/feeds/mediatek-sdk/mt76/patches/0016-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch +++ b/feeds/mediatek-sdk/mt76/patches/0017-wifi-mt76-mt7915-fix-rx-filter-setting-for-bfee-func.patch @@ -1,7 +1,7 @@ -From 1a9953c39a08407607e5ef9d2ca4fefa77b5eaea Mon Sep 17 00:00:00 2001 +From d0d40f91383444dce590d39157d05f4922102db3 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Fri, 12 Apr 2024 11:33:08 +0800 -Subject: [PATCH] wifi: mt76: mt7915: fix rx filter setting for bfee +Subject: [PATCH 17/21] wifi: mt76: mt7915: fix rx filter setting for bfee functionality Fix rx filter setting to prevent dropping NDPA frames. Without this @@ -14,7 +14,7 @@ Signed-off-by: Howard Hsu 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mt7915/main.c b/mt7915/main.c -index 9eeca39..6674c27 100644 +index f4673c8d..f40a9007 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -564,8 +564,7 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw, diff --git a/feeds/mediatek-sdk/mt76/patches/0018-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch b/feeds/mediatek-sdk/mt76/patches/0018-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch new file mode 100644 index 000000000..5f25fc542 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0018-wifi-mt76-mt7915-fix-inconsistent-QoS-mapping-betwee.patch @@ -0,0 +1,144 @@ +From 605a40dad37c685a49f2c7985e3a05806d7ac1fc Mon Sep 17 00:00:00 2001 +From: Benjamin Lin +Date: Thu, 25 Apr 2024 17:17:13 +0800 +Subject: [PATCH] wifi: mt76: mt7915: fix inconsistent QoS mapping between SW + and HW + +The mapping from IP DSCP to IEEE 802.11 user priority may be customized. +Therefore, the mapping needs to be passed to HW, so that the QoS type of traffic can be mapped in a consistent manner for both SW and HW paths. + +Signed-off-by: Benjamin Lin +--- + mt76_connac_mcu.h | 1 + + mt7915/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++- + mt7915/mt7915.h | 4 ++++ + 3 files changed, 63 insertions(+), 1 deletion(-) + +diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h +index 46dcd1c..e0255a2 100644 +--- a/mt76_connac_mcu.h ++++ b/mt76_connac_mcu.h +@@ -1238,6 +1238,7 @@ enum { + MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab, + MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac, + MCU_EXT_CMD_PHY_STAT_INFO = 0xad, ++ MCU_EXT_CMD_SET_QOS_MAP = 0xb4, + }; + + enum { +diff --git a/mt7915/main.c b/mt7915/main.c +index f40a900..71f3ad1 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -209,7 +209,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, + struct mt7915_phy *phy = mt7915_hw_phy(hw); + struct mt76_txq *mtxq; + bool ext_phy = phy != &dev->phy; +- int idx, ret = 0; ++ int idx, i, ret = 0; + + mutex_lock(&dev->mt76.mutex); + +@@ -255,6 +255,12 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, + mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; + mt76_wcid_init(&mvif->sta.wcid); + ++ /* init Default QoS map, defined in section 2.3 of RFC8325. ++ * Three most significant bits of DSCP are used as UP. ++ */ ++ for (i = 0; i < IP_DSCP_NUM; ++i) ++ mvif->qos_map[i] = i >> 3; ++ + mt7915_mac_wtbl_update(dev, idx, + MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + +@@ -1619,6 +1625,56 @@ mt7915_set_frag_threshold(struct ieee80211_hw *hw, u32 val) + return 0; + } + ++static int ++mt7915_set_qos_map(struct ieee80211_vif *vif, struct cfg80211_qos_map *usr_qos_map) ++{ ++ struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; ++ struct { ++ u8 bss_idx; ++ u8 qos_map_enable; ++ u8 __rsv[2]; ++ s8 qos_map[IP_DSCP_NUM]; ++ } __packed req = { ++ .bss_idx = mvif->mt76.idx, ++ .qos_map_enable = usr_qos_map ? true : false, ++ }; ++ ++ /* Prevent access to members of mt7915_vif before its initialization. */ ++ if (!mvif->phy) ++ return -EPERM; ++ ++ if (usr_qos_map) { ++ struct cfg80211_dscp_exception *exception = usr_qos_map->dscp_exception; ++ struct cfg80211_dscp_range *range = usr_qos_map->up; ++ s8 i; ++ ++ /* Default QoS map, defined in section 2.3 of RFC8325. ++ * Three most significant bits of DSCP are used as UP. ++ */ ++ for (i = 0; i < IP_DSCP_NUM; ++i) ++ req.qos_map[i] = i >> 3; ++ ++ /* User-defined QoS map */ ++ for (i = 0; i < IEEE80211_NUM_UPS; ++i) { ++ u8 low = range[i].low, high = range[i].high; ++ ++ if (low < IP_DSCP_NUM && high < IP_DSCP_NUM && low <= high) ++ memset(req.qos_map + low, i, high - low + 1); ++ } ++ ++ for (i = 0; i < usr_qos_map->num_des; ++i) { ++ u8 dscp = exception[i].dscp, up = exception[i].up; ++ ++ if (dscp < IP_DSCP_NUM && up < IEEE80211_NUM_UPS) ++ req.qos_map[dscp] = up; ++ } ++ memcpy(mvif->qos_map, req.qos_map, IP_DSCP_NUM); ++ } ++ ++ return mt76_mcu_send_msg(&mvif->phy->dev->mt76, MCU_WA_EXT_CMD(SET_QOS_MAP), ++ &req, sizeof(req), true); ++} ++ + static int + mt7915_set_radar_background(struct ieee80211_hw *hw, + struct cfg80211_chan_def *chandef) +@@ -1751,6 +1807,7 @@ const struct ieee80211_ops mt7915_ops = { + .add_twt_setup = mt7915_mac_add_twt_setup, + .twt_teardown_request = mt7915_twt_teardown_request, + .set_frag_threshold = mt7915_set_frag_threshold, ++ .set_qos_map = mt7915_set_qos_map, + CFG80211_TESTMODE_CMD(mt76_testmode_cmd) + CFG80211_TESTMODE_DUMP(mt76_testmode_dump) + #ifdef CONFIG_MAC80211_DEBUGFS +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index 74cd8ca..bfac851 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -83,6 +83,8 @@ + #define MT7915_CRIT_TEMP 110 + #define MT7915_MAX_TEMP 120 + ++#define IP_DSCP_NUM 64 ++ + struct mt7915_vif; + struct mt7915_sta; + struct mt7915_dfs_pulse; +@@ -175,6 +177,8 @@ struct mt7915_vif { + + struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct cfg80211_bitrate_mask bitrate_mask; ++ /* QoS map support */ ++ u8 qos_map[IP_DSCP_NUM]; + }; + + /* crash-dump */ +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0019-wifi-mt76-mt7915-adjust-rx-filter.patch b/feeds/mediatek-sdk/mt76/patches/0019-wifi-mt76-mt7915-adjust-rx-filter.patch new file mode 100644 index 000000000..aebc44fd0 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0019-wifi-mt76-mt7915-adjust-rx-filter.patch @@ -0,0 +1,58 @@ +From d189b10ff8b7cd3d6fdabde17e8476bfe66466cc Mon Sep 17 00:00:00 2001 +From: Howard Hsu +Date: Fri, 19 Apr 2024 15:43:23 +0800 +Subject: [PATCH 19/21] wifi: mt76: mt7915: adjust rx filter + +Adjust rx filter setting to drop the packet that we do not need to +receive. + +Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets") +Signed-off-by: Howard Hsu +--- + mt7915/main.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/mt7915/main.c b/mt7915/main.c +index 3a8b9404..0d2614e1 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -489,7 +489,8 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) + rxfilter |= MT_WF_RFCR_DROP_OTHER_UC; + dev->monitor_mask &= ~BIT(band); + } else { +- rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC; ++ rxfilter &= ~(MT_WF_RFCR_DROP_A2_BSSID | ++ MT_WF_RFCR_DROP_OTHER_UC); + dev->monitor_mask |= BIT(band); + } + +@@ -552,13 +553,14 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw, + MT_WF_RFCR_DROP_MCAST | + MT_WF_RFCR_DROP_BCAST | + MT_WF_RFCR_DROP_DUPLICATE | +- MT_WF_RFCR_DROP_A2_BSSID | + MT_WF_RFCR_DROP_UNWANTED_CTL | + MT_WF_RFCR_DROP_STBC_MULTI); ++ phy->rxfilter |= MT_WF_RFCR_DROP_VERSION; + + MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM | + MT_WF_RFCR_DROP_A3_MAC | +- MT_WF_RFCR_DROP_A3_BSSID); ++ MT_WF_RFCR_DROP_A3_BSSID | ++ MT_WF_RFCR_DROP_A2_BSSID); + + MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL); + +@@ -569,7 +571,8 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw, + *total_flags = flags; + rxfilter = phy->rxfilter; + if (hw->conf.flags & IEEE80211_CONF_MONITOR) +- rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC; ++ rxfilter &= ~(MT_WF_RFCR_DROP_A2_BSSID | ++ MT_WF_RFCR_DROP_OTHER_UC); + else + rxfilter |= MT_WF_RFCR_DROP_OTHER_UC; + mt76_wr(dev, MT_WF_RFCR(band), rxfilter); +-- +2.18.0 + diff --git a/feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch b/feeds/mediatek-sdk/mt76/patches/0020-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch similarity index 73% rename from feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch rename to feeds/mediatek-sdk/mt76/patches/0020-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch index 0113d3711..7b3b4646a 100644 --- a/feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch +++ b/feeds/mediatek-sdk/mt76/patches/0020-wifi-mt76-mt7915-add-additional-chain-signal-info-to.patch @@ -1,8 +1,8 @@ -From eaa1c8b40685b56c6298c85cb0a44c7b97c62e8c Mon Sep 17 00:00:00 2001 +From cab458a1d2d91784aa28bacfd0b6649fd5c3f740 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Wed, 20 Sep 2023 11:10:57 +0800 -Subject: [PATCH 1038/1053] wifi: mt76: mt7915: add additional chain signal - info to station dump +Subject: [PATCH 20/21] wifi: mt76: mt7915: add additional chain signal info to + station dump Signed-off-by: StanleyYP Wang --- @@ -10,10 +10,10 @@ Signed-off-by: StanleyYP Wang 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mt7915/mac.c b/mt7915/mac.c -index b0ddb10..9a49375 100644 +index 4604a682..95c794a3 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -442,7 +442,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -437,7 +437,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, if (v0 & MT_PRXV_HT_AD_CODE) status->enc_flags |= RX_ENC_FLAG_LDPC; diff --git a/feeds/mediatek-sdk/mt76/patches/1050-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch b/feeds/mediatek-sdk/mt76/patches/0021-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch similarity index 85% rename from feeds/mediatek-sdk/mt76/patches/1050-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch rename to feeds/mediatek-sdk/mt76/patches/0021-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch index 840d787b7..b318b8cc7 100644 --- a/feeds/mediatek-sdk/mt76/patches/1050-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch +++ b/feeds/mediatek-sdk/mt76/patches/0021-wifi-mt76-mt7915-remove-unnecessary-register-setting.patch @@ -1,7 +1,7 @@ -From 1e641bcbd21de95f4719063eecde6df206e2cf55 Mon Sep 17 00:00:00 2001 +From 9976288a87664bacf514902869be38215da1d8b1 Mon Sep 17 00:00:00 2001 From: Henry Yen Date: Wed, 6 Mar 2024 12:42:06 +0800 -Subject: [PATCH 1050/1053] wifi: mt76: mt7915: remove unnecessary register +Subject: [PATCH 21/21] wifi: mt76: mt7915: remove unnecessary register settings Remove unnecessary register settings from the driver layer, @@ -9,15 +9,15 @@ and let firmware take over the configuration control. Signed-off-by: Henry.Yen --- - mt7915/init.c | 35 ----------------------------------- + mt7915/init.c | 30 ------------------------------ mt7915/mac.c | 43 +------------------------------------------ - 2 files changed, 1 insertion(+), 77 deletions(-) + 2 files changed, 1 insertion(+), 72 deletions(-) diff --git a/mt7915/init.c b/mt7915/init.c -index 26ae63f..9ffeca5 100644 +index 470b198a..84c69a88 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -488,30 +488,6 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) +@@ -476,30 +476,6 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) { u32 mask, set; @@ -48,19 +48,19 @@ index 26ae63f..9ffeca5 100644 /* mt7915: disable rx rate report by default due to hw issues */ mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN); -@@ -614,23 +590,12 @@ mt7915_init_led_mux(struct mt7915_dev *dev) +@@ -602,23 +578,17 @@ mt7915_init_led_mux(struct mt7915_dev *dev) void mt7915_mac_init(struct mt7915_dev *dev) { int i; - u32 rx_len = is_mt7915(&dev->mt76) ? 0x400 : 0x680; -- -- /* config pse qid6 wfdma port selection */ -- if (!is_mt7915(&dev->mt76) && dev->hif2) -- mt76_rmw(dev, MT_WF_PP_TOP_RXQ_WFDMA_CF_5, 0, -- MT_WF_PP_TOP_RXQ_QID6_WFDMA_HIF_SEL_MASK); -- -- mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, rx_len); + /* config pse qid6 wfdma port selection */ + if (!is_mt7915(&dev->mt76) && dev->hif2) + mt76_rmw(dev, MT_WF_PP_TOP_RXQ_WFDMA_CF_5, 0, + MT_WF_PP_TOP_RXQ_QID6_WFDMA_HIF_SEL_MASK); + +- mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, rx_len); +- if (!is_mt7915(&dev->mt76)) mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT); else @@ -73,10 +73,10 @@ index 26ae63f..9ffeca5 100644 mt7915_mac_wtbl_update(dev, i, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); diff --git a/mt7915/mac.c b/mt7915/mac.c -index e9f50a3..c84b957 100644 +index 95c794a3..1c5ab41f 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1202,61 +1202,20 @@ void mt7915_mac_reset_counters(struct mt7915_phy *phy) +@@ -1149,61 +1149,20 @@ void mt7915_mac_reset_counters(struct mt7915_phy *phy) void mt7915_mac_set_timing(struct mt7915_phy *phy) { diff --git a/feeds/mediatek-sdk/mt76/patches/0022-wifi-mt76-mt7915-enable-PPDU-TXS-to-update-data-fram.patch b/feeds/mediatek-sdk/mt76/patches/0022-wifi-mt76-mt7915-enable-PPDU-TXS-to-update-data-fram.patch new file mode 100644 index 000000000..c325b52e9 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0022-wifi-mt76-mt7915-enable-PPDU-TXS-to-update-data-fram.patch @@ -0,0 +1,163 @@ +From 40d175e8ad31eb956071998bc3801538020febf0 Mon Sep 17 00:00:00 2001 +From: Benjamin Lin +Date: Fri, 2 Aug 2024 14:22:45 +0800 +Subject: [PATCH] wifi: mt76: mt7915: enable PPDU TXS to update data-frame TX + rate + +When WED is on, only use data-frame TXS to update station's TX rate. +When WED is off, enable PPDU TXS to update TX rate. + +Signed-off-by: Benjamin Lin +--- + mt76_connac.h | 2 +- + mt76_connac_mac.c | 10 ++++++---- + mt7915/init.c | 3 +-- + mt7915/mac.c | 13 +------------ + mt7915/main.c | 1 - + mt7915/mt7915.h | 1 - + tx.c | 5 ++--- + 7 files changed, 11 insertions(+), 24 deletions(-) + +diff --git a/mt76_connac.h b/mt76_connac.h +index 5028e49..355b506 100644 +--- a/mt76_connac.h ++++ b/mt76_connac.h +@@ -436,7 +436,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, + struct ieee80211_vif *vif, + bool beacon, bool mcast); + bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, +- __le32 *txs_data); ++ int pid, __le32 *txs_data); + bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid, + int pid, __le32 *txs_data); + void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev, +diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c +index 170ef36..ead859a 100644 +--- a/mt76_connac_mac.c ++++ b/mt76_connac_mac.c +@@ -594,7 +594,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, + EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi); + + bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, +- __le32 *txs_data) ++ int pid, __le32 *txs_data) + { + struct mt76_sta_stats *stats = &wcid->stats; + struct ieee80211_supported_band *sband; +@@ -606,8 +606,7 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, + txs = le32_to_cpu(txs_data[0]); + + /* PPDU based reporting */ +- if (mtk_wed_device_active(&dev->mmio.wed) && +- FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { ++ if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { + stats->tx_bytes += + le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - + le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); +@@ -628,6 +627,9 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, + } + } + ++ if (pid != MT_PACKET_ID_WED) ++ return true; ++ + txrate = FIELD_GET(MT_TXS0_TX_RATE, txs); + + rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate); +@@ -737,7 +739,7 @@ bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid, + !!(info->flags & IEEE80211_TX_STAT_ACK); + info->status.rates[0].idx = -1; + +- mt76_connac2_mac_fill_txs(dev, wcid, txs_data); ++ mt76_connac2_mac_fill_txs(dev, wcid, pid, txs_data); + mt76_tx_status_skb_done(dev, skb, &list); + } + mt76_tx_status_unlock(dev, &list); +diff --git a/mt7915/init.c b/mt7915/init.c +index 84c69a8..ebf5500 100644 +--- a/mt7915/init.c ++++ b/mt7915/init.c +@@ -505,8 +505,7 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band) + /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than + * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set. + */ +- if (mtk_wed_device_active(&dev->mt76.mmio.wed)) +- mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H); ++ mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H); + } + + static void +diff --git a/mt7915/mac.c b/mt7915/mac.c +index 1c5ab41..9ac85df 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -748,17 +748,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, + if (!wcid) + wcid = &dev->mt76.global_wcid; + +- if (sta) { +- struct mt7915_sta *msta; +- +- msta = (struct mt7915_sta *)sta->drv_priv; +- +- if (time_after(jiffies, msta->jiffies + HZ / 4)) { +- info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; +- msta->jiffies = jiffies; +- } +- } +- + t = (struct mt76_txwi_cache *)(txwi + mdev->drv->txwi_size); + t->skb = tx_info->skb; + +@@ -1023,7 +1012,7 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) + msta = container_of(wcid, struct mt7915_sta, wcid); + + if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) == MT_TXS_PPDU_FMT) +- mt76_connac2_mac_fill_txs(&dev->mt76, wcid, txs_data); ++ mt76_connac2_mac_fill_txs(&dev->mt76, wcid, pid, txs_data); + else + mt76_connac2_mac_add_txs_skb(&dev->mt76, wcid, pid, txs_data); + +diff --git a/mt7915/main.c b/mt7915/main.c +index 73a7153..fc45789 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -787,7 +787,6 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, + msta->wcid.idx = idx; + msta->wcid.phy_idx = ext_phy; + msta->wcid.tx_info |= MT_WCID_TX_INFO_SET; +- msta->jiffies = jiffies; + + ewma_avg_signal_init(&msta->avg_ack_signal); + +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index bfac851..77626e7 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -146,7 +146,6 @@ struct mt7915_sta { + struct ewma_avg_signal avg_ack_signal; + + unsigned long changed; +- unsigned long jiffies; + struct mt76_connac_sta_key_conf bip; + + struct { +diff --git a/tx.c b/tx.c +index 0fdf7d8..1fee6ff 100644 +--- a/tx.c ++++ b/tx.c +@@ -136,9 +136,8 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, + + if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | + IEEE80211_TX_CTL_RATE_CTRL_PROBE))) { +- if (mtk_wed_device_active(&dev->mmio.wed) && +- ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) || +- ieee80211_is_data(hdr->frame_control))) ++ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP || ++ ieee80211_is_data(hdr->frame_control)) + return MT_PACKET_ID_WED; + + return MT_PACKET_ID_NO_SKB; +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-fix-add-ba-issue-on-tid-not-equal-t.patch b/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-fix-add-ba-issue-on-tid-not-equal-t.patch new file mode 100644 index 000000000..b3f81dd6b --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-fix-add-ba-issue-on-tid-not-equal-t.patch @@ -0,0 +1,77 @@ +From b5c9fa8bc514d8db22a93c3d4d3e686b9b34a52d Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Wed, 21 Aug 2024 20:13:37 +0800 +Subject: [PATCH] wifi: mt76: mt7915: fix add ba issue on tid not equal to zero + case + +Signed-off-by: Rex Lu +--- + mt76.h | 6 ++++++ + mt7915/main.c | 7 +++++++ + 2 files changed, 13 insertions(+) + +diff --git a/mt76.h b/mt76.h +index bdc9a9b..592c3cd 100644 +--- a/mt76.h ++++ b/mt76.h +@@ -52,6 +52,8 @@ + #define MT_WED_RRO_Q_MSDU_PG(_n) __MT_WED_RRO_Q(MT76_WED_RRO_Q_MSDU_PG, _n) + #define MT_WED_RRO_Q_IND __MT_WED_RRO_Q(MT76_WED_RRO_Q_IND, 0) + ++#define AMPDU_ADDBA_SUCC_SHFT IEEE80211_NUM_TIDS ++ + struct mt76_dev; + struct mt76_phy; + struct mt76_wcid; +@@ -356,6 +358,10 @@ struct mt76_wcid { + int inactive_count; + + struct rate_info rate; ++ /* ++ *Bit 0 - 15: ADDBA of TID n started ++ *Bit 16 - 31: ADDBA of TID n succeeded ++ */ + unsigned long ampdu_state; + + u16 idx; +diff --git a/mt7915/main.c b/mt7915/main.c +index 73a7153..35b97db 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -907,12 +907,14 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + case IEEE80211_AMPDU_TX_OPERATIONAL: + mtxq->aggr = true; + mtxq->send_bar = false; ++ set_bit((tid + AMPDU_ADDBA_SUCC_SHFT), &msta->wcid.ampdu_state); + ret = mt7915_mcu_add_tx_ba(dev, params, true); + break; + case IEEE80211_AMPDU_TX_STOP_FLUSH: + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + mtxq->aggr = false; + clear_bit(tid, &msta->wcid.ampdu_state); ++ clear_bit((tid + AMPDU_ADDBA_SUCC_SHFT), &msta->wcid.ampdu_state); + ret = mt7915_mcu_add_tx_ba(dev, params, false); + break; + case IEEE80211_AMPDU_TX_START: +@@ -922,6 +924,7 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + case IEEE80211_AMPDU_TX_STOP_CONT: + mtxq->aggr = false; + clear_bit(tid, &msta->wcid.ampdu_state); ++ clear_bit((tid + AMPDU_ADDBA_SUCC_SHFT), &msta->wcid.ampdu_state); + ret = mt7915_mcu_add_tx_ba(dev, params, false); + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; +@@ -1747,6 +1750,10 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, + if (msta->wcid.idx > 0xff) + return -EIO; + ++ if (!test_bit((mvif->qos_map[path->mtk_wdma.tid >> 2] + AMPDU_ADDBA_SUCC_SHFT), ++ &msta->wcid.ampdu_state)) ++ return -EAGAIN; ++ + path->type = DEV_PATH_MTK_WDMA; + path->dev = ctx->dev; + path->mtk_wdma.wdma_idx = wed->wdma_idx; +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-refactor-check-for-TX-BA-sesstion-s.patch b/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-refactor-check-for-TX-BA-sesstion-s.patch new file mode 100644 index 000000000..1ab059919 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0023-wifi-mt76-mt7915-refactor-check-for-TX-BA-sesstion-s.patch @@ -0,0 +1,101 @@ +From 721b1a5bd935b16ff933ace32a6da36bec473e19 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Wed, 11 Dec 2024 11:41:49 +0800 +Subject: [PATCH] wifi: mt76: mt7915: refactor check for TX BA sesstion status + +Signed-off-by: Rex Lu +--- + mt76.h | 3 ++- + mt76_connac_mac.c | 41 +++++++++++++++++++++++++++++++---------- + 2 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/mt76.h b/mt76.h +index 592c3cd..fbddd7e 100644 +--- a/mt76.h ++++ b/mt76.h +@@ -348,6 +348,7 @@ DECLARE_EWMA(signal, 10, 8); + #define MT_WCID_TX_INFO_TXPWR_ADJ GENMASK(25, 18) + #define MT_WCID_TX_INFO_SET BIT(31) + ++#define ADDBA_RETRY_PERIOD (5 * HZ) + struct mt76_wcid { + struct mt76_rx_tid __rcu *aggr[IEEE80211_NUM_TIDS]; + +@@ -363,7 +364,7 @@ struct mt76_wcid { + *Bit 16 - 31: ADDBA of TID n succeeded + */ + unsigned long ampdu_state; +- ++ unsigned long last_addba_req_time[IEEE80211_NUM_TIDS]; + u16 idx; + u8 hw_key_idx; + u8 hw_key_idx2; +diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c +index 4d24cc6..c250f9f 100644 +--- a/mt76_connac_mac.c ++++ b/mt76_connac_mac.c +@@ -474,6 +474,34 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, + } + } + ++static void ++mt76_check_tx_ba_status(struct mt76_wcid *wcid, u8 tid) ++{ ++ struct ieee80211_sta *sta; ++ ++ if (!wcid) ++ return; ++ ++ sta = wcid_to_sta(wcid); ++ ++ if (!sta || ++ !(sta->ht_cap.ht_supported || sta->he_cap.has_he)) ++ return; ++ ++ if (test_bit(tid, &wcid->ampdu_state)) { ++ ieee80211_refresh_tx_agg_session_timer(sta, tid); ++ return; ++ } ++ ++ if (!wcid->last_addba_req_time[tid] || ++ time_after(jiffies, wcid->last_addba_req_time[tid] + ADDBA_RETRY_PERIOD)) { ++ set_bit(tid, &wcid->ampdu_state); ++ if (ieee80211_start_tx_ba_session(sta, tid, 0) < 0) ++ clear_bit(tid, &wcid->ampdu_state); ++ wcid->last_addba_req_time[tid] = jiffies; ++ } ++} ++ + void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, + struct ieee80211_key_conf *key, int pid, +@@ -617,14 +645,8 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, + le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_CNT); + + if (wcid->sta) { +- struct ieee80211_sta *sta; +- u8 tid; +- +- sta = container_of((void *)wcid, struct ieee80211_sta, +- drv_priv); +- tid = FIELD_GET(MT_TXS0_TID, txs); +- +- ieee80211_refresh_tx_agg_session_timer(sta, tid); ++ if (!le32_get_bits(txs_data[0], MT_TXS0_FIXED_RATE)) ++ mt76_check_tx_ba_status(wcid, FIELD_GET(MT_TXS0_TID, txs)); + } + } + +@@ -1134,8 +1156,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) + return; + + wcid = (struct mt76_wcid *)sta->drv_priv; +- if (!test_and_set_bit(tid, &wcid->ampdu_state)) +- ieee80211_start_tx_ba_session(sta, tid, 0); ++ mt76_check_tx_ba_status(wcid, tid); + } + EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr); + +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0024-wifi-mt76-mt7915-delete-twt-flow-before-remove-stati.patch b/feeds/mediatek-sdk/mt76/patches/0024-wifi-mt76-mt7915-delete-twt-flow-before-remove-stati.patch new file mode 100644 index 000000000..4fb5802d8 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0024-wifi-mt76-mt7915-delete-twt-flow-before-remove-stati.patch @@ -0,0 +1,38 @@ +From bd1f21a77b832ff70db23751789006090a4c5cd8 Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Mon, 14 Oct 2024 10:33:39 +0800 +Subject: [PATCH] wifi: mt76: mt7915: delete twt flow before remove stations + +Send a mcu command to FW to remove twt flows before removing stations. +If we remove stations first, twt flows may not be remove correctly. + +Signed-off-by: Peter Chiu +--- + mt7915/main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/mt7915/main.c b/mt7915/main.c +index 35b97db7..a7aba999 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -812,14 +812,14 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, + struct mt7915_phy *phy = msta->vif->phy; + int i; + ++ for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) ++ mt7915_mac_twt_teardown_flow(dev, msta, i); ++ + mt7915_mcu_add_sta(dev, vif, sta, false); + + mt7915_mac_wtbl_update(dev, msta->wcid.idx, + MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + +- for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) +- mt7915_mac_twt_teardown_flow(dev, msta, i); +- + spin_lock_bh(&mdev->sta_poll_lock); + if (!list_empty(&msta->wcid.poll_list)) + list_del_init(&msta->wcid.poll_list); +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0025-mtk-mt76-do-not-report-ACK-when-TXS-is-lost.patch b/feeds/mediatek-sdk/mt76/patches/0025-mtk-mt76-do-not-report-ACK-when-TXS-is-lost.patch new file mode 100644 index 000000000..cb27ea1f0 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0025-mtk-mt76-do-not-report-ACK-when-TXS-is-lost.patch @@ -0,0 +1,27 @@ +From 4efdf548d28d3afbc367e2cbe365107db1869690 Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Wed, 16 Oct 2024 08:41:49 +0800 +Subject: [PATCH] mtk: mt76: do not report ACK when TXS is lost + +Signed-off-by: Shayne Chen +--- + tx.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tx.c b/tx.c +index d6054ab6..b3d76692 100644 +--- a/tx.c ++++ b/tx.c +@@ -100,7 +100,8 @@ __mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, u8 flags, + return; + + /* Tx status can be unreliable. if it fails, mark the frame as ACKed */ +- if (flags & MT_TX_CB_TXS_FAILED) { ++ if ((flags & MT_TX_CB_TXS_FAILED) && ++ (dev->drv->drv_flags & MT_DRV_SW_RX_AIRTIME)) { /* Only CE chips do so */ + info->status.rates[0].count = 0; + info->status.rates[0].idx = -1; + info->flags |= IEEE80211_TX_STAT_ACK; +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0026-wifi-mt76-mt7915-fix-register-mapping.patch b/feeds/mediatek-sdk/mt76/patches/0026-wifi-mt76-mt7915-fix-register-mapping.patch new file mode 100644 index 000000000..320ab896c --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0026-wifi-mt76-mt7915-fix-register-mapping.patch @@ -0,0 +1,30 @@ +From 74d7c4a6d5ae3bb7cc5c04d74b713682442724ab Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Tue, 26 Nov 2024 13:29:18 +0800 +Subject: [PATCH] wifi: mt76: mt7915: fix register mapping + +Bypass the entry when ofs is equal to dev->reg.map[i].size. +Without this patch, it would get incorrect register mapping when the +CR address is located at the boundary of an entry. + +Signed-off-by: Peter Chiu +--- + mt7915/mmio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/mt7915/mmio.c b/mt7915/mmio.c +index 1ea91676..7a4268bb 100644 +--- a/mt7915/mmio.c ++++ b/mt7915/mmio.c +@@ -490,7 +490,7 @@ static u32 __mt7915_reg_addr(struct mt7915_dev *dev, u32 addr) + continue; + + ofs = addr - dev->reg.map[i].phys; +- if (ofs > dev->reg.map[i].size) ++ if (ofs >= dev->reg.map[i].size) + continue; + + return dev->reg.map[i].maps + ofs; +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0027-wifi-mt76-mt7915-update-adie-patch-in-mt7986-power-o.patch b/feeds/mediatek-sdk/mt76/patches/0027-wifi-mt76-mt7915-update-adie-patch-in-mt7986-power-o.patch new file mode 100644 index 000000000..9505a67cb --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/0027-wifi-mt76-mt7915-update-adie-patch-in-mt7986-power-o.patch @@ -0,0 +1,61 @@ +From 1aead9dad4c2eb2592332b402f23f43f4ee79207 Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Thu, 22 May 2025 15:42:50 +0800 +Subject: [PATCH] wifi: mt76: mt7915: update adie patch in mt7986 power on + sequence + +Update adie init CR. + +Signed-off-by: Peter Chiu + +diff --git a/mt7915/regs.h b/mt7915/regs.h +index 3452a7e9..28ded58c 100644 +--- a/mt7915/regs.h ++++ b/mt7915/regs.h +@@ -941,6 +941,7 @@ enum offs_rev { + #define MT_ADIE_XTAL_TRIM1_40M_OSC 0x399 + #define MT_ADIE_WRI_CK_SEL 0x4ac + #define MT_ADIE_RG_STRAP_PIN_IN 0x4fc ++#define MT_ADIE_RG_TOP_XO_08 0x600 + #define MT_ADIE_XTAL_C1 0x654 + #define MT_ADIE_XTAL_C2 0x658 + #define MT_ADIE_RG_XO_01 0x65c +diff --git a/mt7915/soc.c b/mt7915/soc.c +index bb3468a9..c613e77a 100644 +--- a/mt7915/soc.c ++++ b/mt7915/soc.c +@@ -506,6 +506,7 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) + { + u32 id, version, rg_xo_01, rg_xo_03; + int ret; ++ bool need_adie_patch = false; + + ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_CHIP_ID, &id); + if (ret) +@@ -525,6 +526,7 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) + if (is_mt7981(&dev->mt76)) { + rg_xo_01 = 0x1959c80f; + } else if (is_mt7986(&dev->mt76)) { ++ need_adie_patch = true; + rg_xo_01 = 0x1959f80f; + } else { + WARN_ON(1); +@@ -537,7 +539,14 @@ static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) + if (ret) + return ret; + +- return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03); ++ ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03); ++ if (ret) ++ return ret; ++ ++ if (!need_adie_patch) ++ return 0; ++ ++ return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_TOP_XO_08, 0); + } + + static int +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch b/feeds/mediatek-sdk/mt76/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch index 60b0e2da9..1f9477c19 100644 --- a/feeds/mediatek-sdk/mt76/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch +++ b/feeds/mediatek-sdk/mt76/patches/0999-wifi-mt76-mt7915-build-pass-for-Linux-Kernel-5.4-fix.patch @@ -1,7 +1,7 @@ -From 4300f1a6eb91cc3291d73e415ae32cbd120f6bc6 Mon Sep 17 00:00:00 2001 +From 4cdf382808962e209db2575b74d5fde2d2e7ac72 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Sat, 1 Apr 2023 08:18:17 +0800 -Subject: [PATCH 0999/1053] wifi: mt76: mt7915: build pass for Linux Kernel 5.4 +Subject: [PATCH 0999/1052] wifi: mt76: mt7915: build pass for Linux Kernel 5.4 fixes --- @@ -23,7 +23,7 @@ Subject: [PATCH 0999/1053] wifi: mt76: mt7915: build pass for Linux Kernel 5.4 15 files changed, 123 insertions(+), 232 deletions(-) diff --git a/debugfs.c b/debugfs.c -index c4649ba..1c8328d 100644 +index c4649ba0..1c8328d5 100644 --- a/debugfs.c +++ b/debugfs.c @@ -33,8 +33,10 @@ mt76_napi_threaded_set(void *data, u64 val) @@ -38,7 +38,7 @@ index c4649ba..1c8328d 100644 return 0; } diff --git a/dma.c b/dma.c -index f4f88c4..ccdd564 100644 +index f4f88c44..ccdd5646 100644 --- a/dma.c +++ b/dma.c @@ -178,7 +178,7 @@ mt76_free_pending_rxwi(struct mt76_dev *dev) @@ -240,7 +240,7 @@ index f4f88c4..ccdd564 100644 if (mtk_wed_device_active(&dev->mmio.wed)) diff --git a/dma.h b/dma.h -index 1de5a2b..619dc0f 100644 +index 1de5a2b2..619dc0fe 100644 --- a/dma.h +++ b/dma.h @@ -79,8 +79,7 @@ enum mt76_dma_wed_ind_reason { @@ -254,7 +254,7 @@ index 1de5a2b..619dc0f 100644 bool reset_idx); void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q); diff --git a/eeprom.c b/eeprom.c -index ecd09c0..a267397 100644 +index ecd09c03..a2673978 100644 --- a/eeprom.c +++ b/eeprom.c @@ -163,9 +163,15 @@ void @@ -275,10 +275,10 @@ index ecd09c0..a267397 100644 if (!is_valid_ether_addr(phy->macaddr)) { eth_random_addr(phy->macaddr); diff --git a/mac80211.c b/mac80211.c -index bc20f60..b30a74e 100644 +index aee6f1e7..4d50bfae 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -577,47 +577,6 @@ void mt76_unregister_phy(struct mt76_phy *phy) +@@ -578,47 +578,6 @@ void mt76_unregister_phy(struct mt76_phy *phy) } EXPORT_SYMBOL_GPL(mt76_unregister_phy); @@ -326,7 +326,7 @@ index bc20f60..b30a74e 100644 struct mt76_dev * mt76_alloc_device(struct device *pdev, unsigned int size, const struct ieee80211_ops *ops, -@@ -1817,21 +1776,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, +@@ -1818,21 +1777,6 @@ void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, } EXPORT_SYMBOL_GPL(mt76_ethtool_worker); @@ -349,7 +349,7 @@ index bc20f60..b30a74e 100644 { struct ieee80211_hw *hw = phy->hw; diff --git a/mcu.c b/mcu.c -index a8cafa3..fa4b054 100644 +index a8cafa39..fa4b0544 100644 --- a/mcu.c +++ b/mcu.c @@ -4,6 +4,7 @@ @@ -361,7 +361,7 @@ index a8cafa3..fa4b054 100644 struct sk_buff * __mt76_mcu_msg_alloc(struct mt76_dev *dev, const void *data, diff --git a/mt76.h b/mt76.h -index b83456b..a07c7df 100644 +index 05ee568c..063fc364 100644 --- a/mt76.h +++ b/mt76.h @@ -15,11 +15,6 @@ @@ -393,7 +393,7 @@ index b83456b..a07c7df 100644 void mt76_ethtool_worker(struct mt76_ethtool_worker_info *wi, struct mt76_sta_stats *stats, bool eht); int mt76_skb_adjust_pad(struct sk_buff *skb, int pad); -@@ -1673,25 +1667,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); +@@ -1685,25 +1679,6 @@ void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); struct mt76_txwi_cache *mt76_rx_token_release(struct mt76_dev *dev, int token); int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, struct mt76_txwi_cache *r, dma_addr_t phys); @@ -420,7 +420,7 @@ index b83456b..a07c7df 100644 static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) { diff --git a/mt7615/mcu.c b/mt7615/mcu.c -index ae34d01..c9444c6 100644 +index c807bd8d..a9310660 100644 --- a/mt7615/mcu.c +++ b/mt7615/mcu.c @@ -10,6 +10,7 @@ @@ -432,7 +432,7 @@ index ae34d01..c9444c6 100644 static bool prefer_offload_fw = true; module_param(prefer_offload_fw, bool, 0644); diff --git a/mt76_connac.h b/mt76_connac.h -index 4871857..8e7068c 100644 +index 5028e49a..5356c52c 100644 --- a/mt76_connac.h +++ b/mt76_connac.h @@ -56,7 +56,6 @@ enum { @@ -452,7 +452,7 @@ index 4871857..8e7068c 100644 if (chandef->width >= ARRAY_SIZE(width_to_bw)) diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c -index 1ea9798..a8f097d 100644 +index 4baaaacf..4e84f8d2 100644 --- a/mt76_connac_mcu.c +++ b/mt76_connac_mcu.c @@ -4,6 +4,7 @@ @@ -524,10 +524,10 @@ index 1ea9798..a8f097d 100644 #define DEFAULT_HE_DURATION_RTS_THRES 1023 static void diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 1dd8244..61ca241 100644 +index e0255a23..abc57f18 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1984,12 +1984,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val); +@@ -1992,12 +1992,8 @@ void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val); const struct ieee80211_sta_he_cap * mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif); @@ -541,10 +541,10 @@ index 1dd8244..61ca241 100644 int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, struct mt76_connac_sta_key_conf *sta_key_conf, diff --git a/mt7915/main.c b/mt7915/main.c -index 9eeca39..407da07 100644 +index 0d2614e1..a3facc9a 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -1438,22 +1438,20 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw, +@@ -1440,22 +1440,20 @@ void mt7915_get_et_strings(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 sset, u8 *data) { @@ -573,7 +573,7 @@ index 9eeca39..407da07 100644 } static void mt7915_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) -@@ -1481,7 +1479,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, +@@ -1483,7 +1481,7 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, .idx = mvif->mt76.idx, }; /* See mt7915_ampdu_stat_read_phy, etc */ @@ -582,7 +582,7 @@ index 9eeca39..407da07 100644 mutex_lock(&dev->mt76.mutex); -@@ -1593,12 +1591,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, +@@ -1595,12 +1593,9 @@ void mt7915_get_et_stats(struct ieee80211_hw *hw, return; ei += wi.worker_stat_count; @@ -599,7 +599,7 @@ index 9eeca39..407da07 100644 static void diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 446c512..8f6bc6e 100644 +index 9126e62f..34323577 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -6,6 +6,7 @@ @@ -611,10 +611,10 @@ index 446c512..8f6bc6e 100644 #define fw_name(_dev, name, ...) ({ \ char *_fw; \ diff --git a/usb.c b/usb.c -index dc690d1..058f2d1 100644 +index 58ff0682..0ca3b069 100644 --- a/usb.c +++ b/usb.c -@@ -319,27 +319,29 @@ mt76u_set_endpoints(struct usb_interface *intf, +@@ -318,27 +318,29 @@ mt76u_set_endpoints(struct usb_interface *intf, static int mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb, @@ -649,7 +649,7 @@ index dc690d1..058f2d1 100644 urb->num_sgs = i; } -@@ -352,16 +354,15 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb, +@@ -351,16 +353,15 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb, static int mt76u_refill_rx(struct mt76_dev *dev, struct mt76_queue *q, @@ -669,7 +669,7 @@ index dc690d1..058f2d1 100644 return urb->transfer_buffer ? 0 : -ENOMEM; } -@@ -399,7 +400,7 @@ mt76u_rx_urb_alloc(struct mt76_dev *dev, struct mt76_queue *q, +@@ -398,7 +399,7 @@ mt76u_rx_urb_alloc(struct mt76_dev *dev, struct mt76_queue *q, if (err) return err; @@ -678,7 +678,7 @@ index dc690d1..058f2d1 100644 } static void mt76u_urb_free(struct urb *urb) -@@ -407,10 +408,10 @@ static void mt76u_urb_free(struct urb *urb) +@@ -406,10 +407,10 @@ static void mt76u_urb_free(struct urb *urb) int i; for (i = 0; i < urb->num_sgs; i++) @@ -691,7 +691,7 @@ index dc690d1..058f2d1 100644 usb_free_urb(urb); } -@@ -546,8 +547,6 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb, +@@ -545,8 +546,6 @@ mt76u_process_rx_entry(struct mt76_dev *dev, struct urb *urb, len -= data_len; nsgs++; } @@ -700,7 +700,7 @@ index dc690d1..058f2d1 100644 dev->drv->rx_skb(dev, MT_RXQ_MAIN, skb, NULL); return nsgs; -@@ -613,7 +612,7 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) +@@ -612,7 +611,7 @@ mt76u_process_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) count = mt76u_process_rx_entry(dev, urb, q->buf_size); if (count > 0) { @@ -709,7 +709,7 @@ index dc690d1..058f2d1 100644 if (err < 0) break; } -@@ -664,10 +663,6 @@ mt76u_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid) +@@ -663,10 +662,6 @@ mt76u_alloc_rx_queue(struct mt76_dev *dev, enum mt76_rxq_id qid) struct mt76_queue *q = &dev->q_rx[qid]; int i, err; @@ -720,7 +720,7 @@ index dc690d1..058f2d1 100644 spin_lock_init(&q->lock); q->entry = devm_kcalloc(dev->dev, MT_NUM_RX_ENTRIES, sizeof(*q->entry), -@@ -696,6 +691,7 @@ EXPORT_SYMBOL_GPL(mt76u_alloc_mcu_queue); +@@ -695,6 +690,7 @@ EXPORT_SYMBOL_GPL(mt76u_alloc_mcu_queue); static void mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) { @@ -728,7 +728,7 @@ index dc690d1..058f2d1 100644 int i; for (i = 0; i < q->ndesc; i++) { -@@ -705,8 +701,13 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) +@@ -704,8 +700,13 @@ mt76u_free_rx_queue(struct mt76_dev *dev, struct mt76_queue *q) mt76u_urb_free(q->entry[i].urb); q->entry[i].urb = NULL; } @@ -745,7 +745,7 @@ index dc690d1..058f2d1 100644 static void mt76u_free_rx(struct mt76_dev *dev) diff --git a/wed.c b/wed.c -index f89e453..f7a3f1b 100644 +index f89e4537..f7a3f1b3 100644 --- a/wed.c +++ b/wed.c @@ -9,8 +9,12 @@ diff --git a/feeds/mediatek-sdk/mt76/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch b/feeds/mediatek-sdk/mt76/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch index a03665bb1..298678e84 100644 --- a/feeds/mediatek-sdk/mt76/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch +++ b/feeds/mediatek-sdk/mt76/patches/1000-wifi-mt76-mt7915-add-mtk-internal-debug-tools-for-mt.patch @@ -1,4 +1,4 @@ -From ae5f0852b50290e0aaf2ff9d5dd8f9bd2b97bbb6 Mon Sep 17 00:00:00 2001 +From fc8eaff0aa3ff1f6a7ac8808922aafba48ed3efc Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Wed, 22 Jun 2022 10:39:47 +0800 Subject: [PATCH] wifi: mt76: mt7915: add mtk internal debug tools for mt76 @@ -23,10 +23,10 @@ Subject: [PATCH] wifi: mt76: mt7915: add mtk internal debug tools for mt76 create mode 100644 mt7915/mtk_mcu.c diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 99cdd1b..a8690cd 100644 +index abc57f18..01d6598a 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1195,6 +1195,7 @@ enum { +@@ -1197,6 +1197,7 @@ enum { MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, MCU_EXT_CMD_FW_LOG_2_HOST = 0x13, MCU_EXT_CMD_TXBF_ACTION = 0x1e, @@ -34,7 +34,7 @@ index 99cdd1b..a8690cd 100644 MCU_EXT_CMD_EFUSE_BUFFER_MODE = 0x21, MCU_EXT_CMD_THERMAL_PROT = 0x23, MCU_EXT_CMD_STA_REC_UPDATE = 0x25, -@@ -1218,6 +1219,11 @@ enum { +@@ -1220,6 +1221,11 @@ enum { MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58, MCU_EXT_CMD_RXDCOC_CAL = 0x59, MCU_EXT_CMD_GET_MIB_INFO = 0x5a, @@ -47,7 +47,7 @@ index 99cdd1b..a8690cd 100644 MCU_EXT_CMD_CAL_CACHE = 0x67, MCU_EXT_CMD_RED_ENABLE = 0x68, diff --git a/mt7915/Makefile b/mt7915/Makefile -index c4dca9c..fd71141 100644 +index c4dca9c1..fd711416 100644 --- a/mt7915/Makefile +++ b/mt7915/Makefile @@ -4,7 +4,7 @@ EXTRA_CFLAGS += -DCONFIG_MT76_LEDS @@ -60,7 +60,7 @@ index c4dca9c..fd71141 100644 mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7915e-$(CONFIG_MT798X_WMAC) += soc.o diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 894e2cd..2661386 100644 +index 894e2cd7..26613869 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -8,6 +8,9 @@ @@ -232,7 +232,7 @@ index 894e2cd..2661386 100644 if (dev->relay_fwlog) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 4604a68..d99864f 100644 +index 9c56f105..d1f58eb4 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -282,6 +282,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, @@ -271,7 +271,7 @@ index 4604a68..d99864f 100644 } diff --git a/mt7915/main.c b/mt7915/main.c -index e10cdb3..3ac3df3 100644 +index 2b161611..90cd834c 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -73,7 +73,11 @@ int mt7915_run(struct ieee80211_hw *hw) @@ -292,10 +292,10 @@ index e10cdb3..3ac3df3 100644 mt76_wcid_init(&mvif->sta.wcid); + mvif->sta.vif = mvif; - mt7915_mac_wtbl_update(dev, idx, - MT_WTBL_UPDATE_ADM_COUNT_CLEAR); + /* init Default QoS map, defined in section 2.3 of RFC8325. + * Three most significant bits of DSCP are used as UP. diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 3e3d57c..1a3647a 100644 +index 34323577..ff7f81b0 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -205,6 +205,11 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, @@ -355,10 +355,11 @@ index 3e3d57c..1a3647a 100644 int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) { struct { -@@ -4214,6 +4241,25 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) +@@ -4213,3 +4240,22 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) + return 0; } - ++ +#ifdef MTK_DEBUG +int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable) +{ @@ -377,12 +378,8 @@ index 3e3d57c..1a3647a 100644 + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MEC_CTRL), &req, sizeof(req), true); +} +#endif -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index fa0847d..9ae0f07 100644 +index fa0847d5..9ae0f07a 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -347,6 +347,10 @@ enum { @@ -397,7 +394,7 @@ index fa0847d..9ae0f07 100644 MCU_WA_PARAM_RED_SETTING = 0x40, }; diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 66d87d7..398f851 100644 +index bfac8516..72158419 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -9,6 +9,7 @@ @@ -408,7 +405,7 @@ index 66d87d7..398f851 100644 #define MT7915_MAX_INTERFACES 19 #define MT7915_WTBL_SIZE 288 #define MT7916_WTBL_SIZE 544 -@@ -244,6 +245,14 @@ struct mt7915_phy { +@@ -248,6 +249,14 @@ struct mt7915_phy { #endif }; @@ -423,7 +420,7 @@ index 66d87d7..398f851 100644 struct mt7915_dev { union { /* must be first */ struct mt76_dev mt76; -@@ -327,6 +336,33 @@ struct mt7915_dev { +@@ -331,6 +340,33 @@ struct mt7915_dev { void __iomem *dcm; void __iomem *sku; @@ -457,7 +454,7 @@ index 66d87d7..398f851 100644 bool wmm_pbc_enable; struct work_struct wmm_pbc_work; u32 adie_type; -@@ -611,4 +647,24 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -614,4 +650,24 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, bool pci, int *irq); @@ -484,7 +481,7 @@ index 66d87d7..398f851 100644 #endif diff --git a/mt7915/mt7915_debug.h b/mt7915/mt7915_debug.h new file mode 100644 -index 0000000..1ec8de9 +index 00000000..2f9f3da7 --- /dev/null +++ b/mt7915/mt7915_debug.h @@ -0,0 +1,1442 @@ @@ -853,8 +850,8 @@ index 0000000..1ec8de9 + [DBG_PSE_FREEPG_CNT] = { DBG_INVALID_BASE, 0x380}, + [DBG_PSE_FREEPG_HEAD_TAIL] = { DBG_INVALID_BASE, 0x384}, + [DBG_PSE_HIF0_PG_INFO] = { DBG_INVALID_BASE, 0x150}, -+ [DBG_PSE_PG_HIF1_GROUP] = { DBG_INVALID_BASE, 0x154}, -+ [DBG_PSE_HIF1_PG_INFO] = { DBG_INVALID_BASE, 0x160}, ++ [DBG_PSE_PG_HIF1_GROUP] = { DBG_INVALID_BASE, 0x114}, ++ [DBG_PSE_HIF1_PG_INFO] = { DBG_INVALID_BASE, 0x154}, + [DBG_PSE_PG_CPU_GROUP] = { DBG_INVALID_BASE, 0x118}, + [DBG_PSE_CPU_PG_INFO] = { DBG_INVALID_BASE, 0x158}, + [DBG_PSE_PG_PLE_GROUP] = { DBG_INVALID_BASE, 0x11c}, @@ -866,7 +863,7 @@ index 0000000..1ec8de9 + [DBG_PSE_PG_LMAC2_GROUP] = { DBG_INVALID_BASE, 0x12c}, + [DBG_PSE_LMAC2_PG_INFO] = { DBG_INVALID_BASE, 0x16c}, + [DBG_PSE_PG_LMAC3_GROUP] = { DBG_INVALID_BASE, 0x130}, -+ [DBG_PSE_LMAC3_PG_INFO] = { DBG_INVALID_BASE, 0x17c}, ++ [DBG_PSE_LMAC3_PG_INFO] = { DBG_INVALID_BASE, 0x170}, + [DBG_PSE_PG_MDP_GROUP] = { DBG_INVALID_BASE, 0x134}, + [DBG_PSE_MDP_PG_INFO] = { DBG_INVALID_BASE, 0x174}, + [DBG_PSE_PG_PLE1_GROUP] = { DBG_INVALID_BASE, 0x120}, @@ -1386,17 +1383,17 @@ index 0000000..1ec8de9 +#define MT_DBG_PSE_MDP_PG_INFO_MDP_SRC_CNT_MASK GENMASK(27, 16) +#define MT_DBG_PSE_MDP_PG_INFO_MDP_RSV_CNT_MASK GENMASK(11, 0) + -+#define MT_DBG_PSE_FL_QUE_CTRL_0_ADDR MT_DBG_PLE(0x1b0) ++#define MT_DBG_PSE_FL_QUE_CTRL_0_ADDR MT_DBG_PSE(0x1b0) +#define MT_DBG_PSE_FL_QUE_CTRL_0_EXECUTE_MASK BIT(31) +#define MT_DBG_PSE_FL_QUE_CTRL_0_Q_BUF_QID_SHFT 24 +#define MT_DBG_PSE_FL_QUE_CTRL_0_Q_BUF_PID_SHFT 10 +#define MT_DBG_PSE_FL_QUE_CTRL_0_Q_BUF_WLANID_MASK GENMASK(9, 0) + -+#define MT_DBG_PSE_FL_QUE_CTRL_2_ADDR MT_DBG_PLE(0x1b8) ++#define MT_DBG_PSE_FL_QUE_CTRL_2_ADDR MT_DBG_PSE(0x1b8) +#define MT_DBG_PSE_FL_QUE_CTRL_2_QUEUE_TAIL_FID_MASK GENMASK(27, 16) +#define MT_DBG_PSE_FL_QUE_CTRL_2_QUEUE_HEAD_FID_MASK GENMASK(11, 0) + -+#define MT_DBG_PSE_FL_QUE_CTRL_3_ADDR MT_DBG_PLE(0x1bc) ++#define MT_DBG_PSE_FL_QUE_CTRL_3_ADDR MT_DBG_PSE(0x1bc) +#define MT_DBG_PSE_FL_QUE_CTRL_3_QUEUE_PKT_NUM_MASK GENMASK(11, 0) + + @@ -1932,7 +1929,7 @@ index 0000000..1ec8de9 +#endif diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c new file mode 100644 -index 0000000..62d3a99 +index 00000000..c0fcb2ee --- /dev/null +++ b/mt7915/mtk_debugfs.c @@ -0,0 +1,3750 @@ @@ -3749,8 +3746,8 @@ index 0000000..62d3a99 + rsv_pg = FIELD_GET(MT_DBG_PSE_LMAC1_PG_INFO_LMAC1_RSV_CNT_MASK, pg_flow_ctrl[11]); + used_pg = FIELD_GET(MT_DBG_PSE_LMAC1_PG_INFO_LMAC1_SRC_CNT_MASK, pg_flow_ctrl[11]); + seq_printf(s, "\t\tThe used/reserved pages of LMAC1 group=0x%03x/0x%03x\n", used_pg, rsv_pg); -+ seq_printf(s, "\tReserved page counter of LMAC2 group(0x82068180): 0x%08x\n", pg_flow_ctrl[11]); -+ seq_printf(s, "\tLMAC2 group page status(0x82068184): 0x%08x\n", pg_flow_ctrl[12]); ++ seq_printf(s, "\tReserved page counter of LMAC2 group(0x82068180): 0x%08x\n", pg_flow_ctrl[12]); ++ seq_printf(s, "\tLMAC2 group page status(0x82068184): 0x%08x\n", pg_flow_ctrl[13]); + min_q = FIELD_GET(MT_DBG_PSE_PG_LMAC2_GROUP_LMAC2_MIN_QUOTA_MASK, pg_flow_ctrl[12]); + max_q = FIELD_GET(MT_DBG_PSE_PG_LMAC2_GROUP_LMAC2_MAX_QUOTA_MASK, pg_flow_ctrl[12]); + seq_printf(s, "\t\tThe max/min quota pages of LMAC2 group=0x%03x/0x%03x\n", max_q, min_q); @@ -3776,8 +3773,8 @@ index 0000000..62d3a99 + used_pg = FIELD_GET(MT_DBG_PSE_PLE_PG_INFO_PLE_SRC_CNT_MASK, pg_flow_ctrl[15]); + seq_printf(s, "\t\tThe used/reserved pages of PLE group=0x%03x/0x%03x\n", used_pg, rsv_pg); + -+ seq_printf(s, "\tReserved page counter of PLE1 group(0x82068168): 0x%08x\n", pg_flow_ctrl[14]); -+ seq_printf(s, "\tPLE1 group page status(0x8206816c): 0x%08x\n", pg_flow_ctrl[15]); ++ seq_printf(s, "\tReserved page counter of PLE1 group(0x82068168): 0x%08x\n", pg_flow_ctrl[20]); ++ seq_printf(s, "\tPLE1 group page status(0x8206816c): 0x%08x\n", pg_flow_ctrl[21]); + min_q = FIELD_GET(MT_DBG_PSE_PG_PLE_GROUP_PLE_MIN_QUOTA_MASK, pg_flow_ctrl[20]); + max_q = FIELD_GET(MT_DBG_PSE_PG_PLE_GROUP_PLE_MAX_QUOTA_MASK, pg_flow_ctrl[20]); + seq_printf(s, "\t\tThe max/min quota pages of PLE1 group=0x%03x/0x%03x\n", max_q, min_q); @@ -4862,7 +4859,7 @@ index 0000000..62d3a99 + struct mt76_dev *mdev = NULL; + int i; + -+ seq_printf(s, "Version: 2.2.24.3\n"); ++ seq_printf(s, "Version: 2.2.24.7\n"); + + if (!test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) + return 0; @@ -5688,7 +5685,7 @@ index 0000000..62d3a99 +#endif diff --git a/mt7915/mtk_mcu.c b/mt7915/mtk_mcu.c new file mode 100644 -index 0000000..143dae2 +index 00000000..143dae26 --- /dev/null +++ b/mt7915/mtk_mcu.c @@ -0,0 +1,51 @@ @@ -5744,7 +5741,7 @@ index 0000000..143dae2 + sizeof(req), true); +} diff --git a/mt7915/soc.c b/mt7915/soc.c -index bb3468a..b941a49 100644 +index bb3468a9..b941a49d 100644 --- a/mt7915/soc.c +++ b/mt7915/soc.c @@ -360,6 +360,13 @@ static int mt798x_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type) @@ -5762,7 +5759,7 @@ index bb3468a..b941a49 100644 mt76_wmac_spi_unlock(dev); diff --git a/tools/fwlog.c b/tools/fwlog.c -index e5d4a10..3d51d9e 100644 +index e5d4a105..3d51d9ec 100644 --- a/tools/fwlog.c +++ b/tools/fwlog.c @@ -26,7 +26,7 @@ static const char *debugfs_path(const char *phyname, const char *file) @@ -5876,5 +5873,5 @@ index e5d4a10..3d51d9e 100644 return ret; } -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch b/feeds/mediatek-sdk/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch index 75db3ee6e..07a7d0391 100644 --- a/feeds/mediatek-sdk/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1001-wifi-mt76-mt7915-csi-implement-csi-support.patch @@ -1,4 +1,4 @@ -From b50df1502bddba9963eadba8d69e6b95a9b87337 Mon Sep 17 00:00:00 2001 +From e15bcf231758ad3d3060512e772257ac7aaaaa3f Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Mon, 6 Jun 2022 20:13:02 +0800 Subject: [PATCH] wifi: mt76: mt7915: csi: implement csi support @@ -6,22 +6,23 @@ Subject: [PATCH] wifi: mt76: mt7915: csi: implement csi support --- mt76_connac_mcu.h | 2 + mt7915/Makefile | 4 +- - mt7915/init.c | 38 ++++ - mt7915/main.c | 4 + - mt7915/mcu.c | 203 ++++++++++++++++++++ - mt7915/mcu.h | 74 ++++++++ - mt7915/mt7915.h | 60 ++++++ - mt7915/vendor.c | 470 ++++++++++++++++++++++++++++++++++++++++++++++ - mt7915/vendor.h | 63 +++++++ - 9 files changed, 916 insertions(+), 2 deletions(-) + mt7915/debugfs.c | 48 ++++ + mt7915/init.c | 46 ++++ + mt7915/main.c | 13 + + mt7915/mcu.c | 203 ++++++++++++++++ + mt7915/mcu.h | 74 ++++++ + mt7915/mt7915.h | 78 ++++++ + mt7915/vendor.c | 606 ++++++++++++++++++++++++++++++++++++++++++++++ + mt7915/vendor.h | 75 ++++++ + 10 files changed, 1147 insertions(+), 2 deletions(-) create mode 100644 mt7915/vendor.c create mode 100644 mt7915/vendor.h diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index a8690cd..cda7559 100644 +index 01d6598a..ad63596d 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1029,6 +1029,7 @@ enum { +@@ -1030,6 +1030,7 @@ enum { MCU_EXT_EVENT_WA_TX_STAT = 0x74, MCU_EXT_EVENT_BCC_NOTIFY = 0x75, MCU_EXT_EVENT_MURU_CTRL = 0x9f, @@ -29,7 +30,7 @@ index a8690cd..cda7559 100644 }; /* unified event table */ -@@ -1243,6 +1244,7 @@ enum { +@@ -1245,6 +1246,7 @@ enum { MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac, MCU_EXT_CMD_PHY_STAT_INFO = 0xad, MCU_EXT_CMD_SET_QOS_MAP = 0xb4, @@ -38,7 +39,7 @@ index a8690cd..cda7559 100644 enum { diff --git a/mt7915/Makefile b/mt7915/Makefile -index fd71141..65129b4 100644 +index fd711416..65129b4f 100644 --- a/mt7915/Makefile +++ b/mt7915/Makefile @@ -1,10 +1,10 @@ @@ -54,24 +55,92 @@ index fd71141..65129b4 100644 mt7915e-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7915e-$(CONFIG_MT798X_WMAC) += soc.o +diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c +index 26613869..909df246 100644 +--- a/mt7915/debugfs.c ++++ b/mt7915/debugfs.c +@@ -1241,6 +1241,51 @@ mt7915_rf_regval_set(void *data, u64 val) + DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get, + mt7915_rf_regval_set, "0x%08llx\n"); + ++#ifdef CONFIG_MTK_VENDOR ++static ssize_t ++mt7915_get_csi_stats(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++ ++{ ++ struct mt7915_phy *phy = file->private_data; ++ struct csi_mac_filter *current_mac, *tmp_mac; ++ static const size_t sz = 4096; ++ char *buf; ++ u32 reg, len = 0; ++ int ret; ++ ++ buf = kzalloc(sz, GFP_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ len += scnprintf(buf + len, sz - len, "CSI enable: %d\n", phy->csi.enable); ++ ++ if (phy->csi.enable) { ++ len += scnprintf(buf + len, sz - len, "CSI data_cnt: %d\n", phy->csi.count); ++ ++ mutex_lock(&phy->csi.mac_filter_lock); ++ ++ list_for_each_entry_safe(current_mac, tmp_mac, &phy->csi.mac_filter_list, node) { ++ len += scnprintf(buf + len, sz - len, "mac: %pM, interval: %d\n", current_mac->mac, current_mac->interval); ++ } ++ ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ } ++ ++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); ++ ++out: ++ kfree(buf); ++ return ret; ++} ++ ++static const struct file_operations mt7915_csi_ops = { ++ .read = mt7915_get_csi_stats, ++ .open = simple_open, ++ .llseek = default_llseek, ++}; ++#endif ++ + int mt7915_init_debugfs(struct mt7915_phy *phy) + { + struct mt7915_dev *dev = phy->dev; +@@ -1283,6 +1328,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) + debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir, + mt7915_rdd_monitor); + } ++#ifdef CONFIG_MTK_VENDOR ++ debugfs_create_file("csi_stats", 0400, dir, phy, &mt7915_csi_ops); ++#endif + + if (!ext_phy) + dev->debugfs_dir = dir; diff --git a/mt7915/init.c b/mt7915/init.c -index 19a68c5..c504ebf 100644 +index 84c69a88..ac15bc53 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -697,6 +697,12 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy) +@@ -668,6 +668,14 @@ mt7915_register_ext_phy(struct mt7915_dev *dev, struct mt7915_phy *phy) /* init wiphy according to mphy and phy */ mt7915_init_wiphy(phy); +#ifdef CONFIG_MTK_VENDOR -+ INIT_LIST_HEAD(&phy->csi.csi_list); -+ spin_lock_init(&phy->csi.csi_lock); ++ INIT_LIST_HEAD(&phy->csi.data_list); ++ spin_lock_init(&phy->csi.data_lock); ++ INIT_LIST_HEAD(&phy->csi.mac_filter_list); ++ mutex_init(&phy->csi.mac_filter_lock); + mt7915_vendor_register(phy); +#endif + ret = mt76_register_phy(mphy, true, mt76_rates, ARRAY_SIZE(mt76_rates)); if (ret) -@@ -1178,6 +1184,24 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) +@@ -1146,6 +1154,28 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) } } @@ -80,14 +149,18 @@ index 19a68c5..c504ebf 100644 +{ + struct csi_data *c, *tmp_c; + -+ spin_lock_bh(&phy->csi.csi_lock); ++ spin_lock_bh(&phy->csi.data_lock); + phy->csi.enable = 0; + -+ list_for_each_entry_safe(c, tmp_c, &phy->csi.csi_list, node) { ++ list_for_each_entry_safe(c, tmp_c, &phy->csi.data_list, node) { + list_del(&c->node); + kfree(c); + } -+ spin_unlock_bh(&phy->csi.csi_lock); ++ spin_unlock_bh(&phy->csi.data_lock); ++ ++ mutex_lock(&phy->csi.mac_filter_lock); ++ mt7915_csi_mac_filter_clear(phy); ++ mutex_unlock(&phy->csi.mac_filter_lock); + + return 0; +} @@ -96,7 +169,7 @@ index 19a68c5..c504ebf 100644 static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) { struct mt7915_phy *phy = mt7915_ext_phy(dev); -@@ -1186,6 +1210,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) +@@ -1154,6 +1184,10 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev) if (!phy) return; @@ -107,7 +180,7 @@ index 19a68c5..c504ebf 100644 mt7915_unregister_thermal(phy); mt76_unregister_phy(mphy); ieee80211_free_hw(mphy->hw); -@@ -1198,6 +1226,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev) +@@ -1166,6 +1200,10 @@ static void mt7915_stop_hardware(struct mt7915_dev *dev) mt7915_dma_cleanup(dev); tasklet_disable(&dev->mt76.irq_tasklet); @@ -118,13 +191,15 @@ index 19a68c5..c504ebf 100644 if (is_mt798x(&dev->mt76)) mt7986_wmac_disable(dev); } -@@ -1242,6 +1274,12 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1210,6 +1248,14 @@ int mt7915_register_device(struct mt7915_dev *dev) dev->mt76.test_ops = &mt7915_testmode_ops; #endif +#ifdef CONFIG_MTK_VENDOR -+ INIT_LIST_HEAD(&dev->phy.csi.csi_list); -+ spin_lock_init(&dev->phy.csi.csi_lock); ++ INIT_LIST_HEAD(&dev->phy.csi.data_list); ++ spin_lock_init(&dev->phy.csi.data_lock); ++ INIT_LIST_HEAD(&dev->phy.csi.mac_filter_list); ++ mutex_init(&dev->phy.csi.mac_filter_lock); + mt7915_vendor_register(&dev->phy); +#endif + @@ -132,22 +207,31 @@ index 19a68c5..c504ebf 100644 ARRAY_SIZE(mt76_rates)); if (ret) diff --git a/mt7915/main.c b/mt7915/main.c -index 3ac3df3..4edb11a 100644 +index 90cd834c..9a7703cf 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -811,6 +811,10 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, +@@ -816,6 +816,19 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, + struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_phy *phy = msta->vif->phy; int i; - +#ifdef CONFIG_MTK_VENDOR -+ mt7915_mcu_set_csi(&dev->phy, 2, 8, 1, 0, sta->addr, 0); -+#endif ++ struct csi_mac_filter *ent; + - mt7915_mcu_add_sta(dev, vif, sta, false); ++ mutex_lock(&phy->csi.mac_filter_lock); ++ ent = mt7915_csi_mac_filter_find(phy, sta->addr); ++ if (ent && !mt7915_mcu_set_csi(phy, 2, 8, 1, 0, sta->addr, 0)) { ++ list_del(&ent->node); ++ kfree(ent); ++ phy->csi.mac_filter_cnt--; ++ } ++ ++ mutex_unlock(&phy->csi.mac_filter_lock); ++#endif - mt7915_mac_wtbl_update(dev, msta->wcid.idx, + for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) + mt7915_mac_twt_teardown_flow(dev, msta, i); diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 1a3647a..65609b4 100644 +index ff7f81b0..44765b1f 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -40,6 +40,10 @@ static bool sr_scene_detect = true; @@ -193,7 +277,7 @@ index 1a3647a..65609b4 100644 + if (is_valid_ether_addr(mac_addr)) { + ether_addr_copy(req.mac_addr, mac_addr); + -+ if (req.v2 == 1 && sta_interval) ++ if ((req.v2 == ADD_CSI_MAC) && sta_interval) + req.sta_interval = sta_interval; + } + @@ -341,21 +425,21 @@ index 1a3647a..65609b4 100644 + + /* put the csi data into list */ + INIT_LIST_HEAD(&target_csi->node); -+ spin_lock_bh(&phy->csi.csi_lock); ++ spin_lock_bh(&phy->csi.data_lock); + + if (!phy->csi.enable) { + kfree(target_csi); -+ spin_unlock_bh(&phy->csi.csi_lock); ++ spin_unlock_bh(&phy->csi.data_lock); + return 0; + } + -+ list_add_tail(&target_csi->node, &phy->csi.csi_list); ++ list_add_tail(&target_csi->node, &phy->csi.data_list); + phy->csi.count++; + + if (phy->csi.count > CSI_MAX_BUF_NUM) { + struct csi_data *old; + -+ old = list_first_entry(&phy->csi.csi_list, ++ old = list_first_entry(&phy->csi.data_list, + struct csi_data, node); + + list_del(&old->node); @@ -365,7 +449,7 @@ index 1a3647a..65609b4 100644 + + if (target_csi->chain_info & BIT(15)) /* last chain */ + phy->csi.last_record = target_csi->ts; -+ spin_unlock_bh(&phy->csi.csi_lock); ++ spin_unlock_bh(&phy->csi.data_lock); + + return 0; +} @@ -375,7 +459,7 @@ index 1a3647a..65609b4 100644 int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp) { diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 9ae0f07..f32d525 100644 +index 9ae0f07a..f32d5256 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -604,4 +604,78 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower) @@ -458,10 +542,10 @@ index 9ae0f07..f32d525 100644 + #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 398f851..5a26335 100644 +index 72158419..4c2abdbf 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -195,6 +195,45 @@ struct mt7915_hif { +@@ -199,6 +199,57 @@ struct mt7915_hif { int irq; }; @@ -502,25 +586,41 @@ index 398f851..5a26335 100644 + + struct list_head node; +}; ++struct csi_mac_filter { ++ struct list_head node; ++ ++ u8 mac[ETH_ALEN]; ++ u32 interval; ++}; ++ ++#define DEL_CSI_MAC 0 ++#define ADD_CSI_MAC 1 ++#define SHOW_CSI_MAC 2 ++ ++#define MAX_CSI_MAC_NUM 10 +#endif + struct mt7915_phy { struct mt76_phy *mt76; struct mt7915_dev *dev; -@@ -243,6 +282,21 @@ struct mt7915_phy { +@@ -247,6 +298,25 @@ struct mt7915_phy { u8 spe_idx; } test; #endif + +#ifdef CONFIG_MTK_VENDOR + struct { -+ struct list_head csi_list; -+ spinlock_t csi_lock; /* used for csi data push/pop */ ++ struct list_head data_list; ++ spinlock_t data_lock; + u32 count; + bool mask; + bool reorder; + bool enable; + ++ struct mutex mac_filter_lock; ++ struct list_head mac_filter_list; ++ u8 mac_filter_cnt; ++ + struct csi_data buffered_csi; + u32 interval; + u32 last_record; @@ -529,7 +629,7 @@ index 398f851..5a26335 100644 }; #ifdef MTK_DEBUG -@@ -647,6 +701,12 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -650,6 +720,14 @@ void mt7915_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, bool pci, int *irq); @@ -537,6 +637,8 @@ index 398f851..5a26335 100644 +void mt7915_vendor_register(struct mt7915_phy *phy); +int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, + u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval); ++struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr); ++void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy); +#endif + #ifdef MTK_DEBUG @@ -544,10 +646,10 @@ index 398f851..5a26335 100644 int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp); diff --git a/mt7915/vendor.c b/mt7915/vendor.c new file mode 100644 -index 0000000..55da60a +index 00000000..92496513 --- /dev/null +++ b/mt7915/vendor.c -@@ -0,0 +1,470 @@ +@@ -0,0 +1,606 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2020, MediaTek Inc. All rights reserved. @@ -571,6 +673,7 @@ index 0000000..55da60a + [MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL] = { .type = NLA_U32 }, + [MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM] = { .type = NLA_U16 }, + [MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED }, ++ [MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER] = { .type = NLA_NESTED }, +}; + +struct csi_null_tone { @@ -728,6 +831,67 @@ index 0000000..55da60a + return mode * 11 + ch_bw * ch_bw + (data_bw + 1) * 2 + pri_ch_idx; +} + ++struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr) ++{ ++ struct csi_mac_filter *ent, *tmp_ent; ++ ++ list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) { ++ if (ether_addr_equal(ent->mac, addr)) ++ return ent; ++ } ++ ++ return NULL; ++} ++ ++void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy) ++{ ++ struct csi_mac_filter *ent, *tmp_ent; ++ list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) { ++ list_del(&ent->node); ++ kfree(ent); ++ } ++ ++ phy->csi.mac_filter_cnt = 0; ++} ++ ++static int mt7915_vendor_reply_csi_mac_filter(struct wiphy *wiphy, struct mt7915_phy *phy) ++{ ++ struct sk_buff *skb; ++ struct csi_mac_filter *ent, *tmp_ent; ++ int idx = 0; ++ struct nlattr *a, *b; ++ ++ mutex_lock(&phy->csi.mac_filter_lock); ++ ++#define ENTRY_SIZE nla_total_size(nla_total_size(ETH_ALEN) + \ ++ nla_total_size(sizeof(ent->interval))) ++ ++ skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, ENTRY_SIZE * ++ phy->csi.mac_filter_cnt); ++ if (!skb) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -ENOMEM; ++ } ++ ++ a = nla_nest_start(skb, MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER); ++ ++ list_for_each_entry_safe(ent, tmp_ent, &phy->csi.mac_filter_list, node) { ++ ++ b = nla_nest_start(skb, idx++); ++ nla_put(skb, MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC, ++ ETH_ALEN, ent->mac); ++ nla_put_u32(skb, MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL, ent->interval); ++ nla_nest_end(skb, b); ++ } ++ ++ nla_nest_end(skb, a); ++#undef ENTRY_SIZE ++ ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ ++ return cfg80211_vendor_cmd_reply(skb); ++} ++ +static int mt7915_vendor_csi_ctrl(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, @@ -787,12 +951,86 @@ index 0000000..55da60a + nla_get_u32(tb[MTK_VENDOR_ATTR_CSI_CTRL_STA_INTERVAL]); + } + -+ err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, mac_addr, sta_interval); ++ if (mode == 0) { ++ mutex_lock(&phy->csi.mac_filter_lock); + -+ if (err < 0) -+ return err; ++ err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, ++ mac_addr, sta_interval); ++ if (err) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return err; ++ } + -+ spin_lock_bh(&phy->csi.csi_lock); ++ mt7915_csi_mac_filter_clear(phy); ++ ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ } else if (mode == 2 && type == 8 && v1 == 1 && (v2 == ADD_CSI_MAC || v2 == DEL_CSI_MAC)) { ++ struct csi_mac_filter *ent; ++ ++ mutex_lock(&phy->csi.mac_filter_lock); ++ ++ if (v2 == DEL_CSI_MAC) { ++ ent = mt7915_csi_mac_filter_find(phy, mac_addr); ++ if (!ent) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -ENOENT; ++ } ++ } else { ++ if (is_mt7915(phy->mt76->dev)) { ++ if (phy->csi.mac_filter_cnt >= MAX_CSI_MAC_NUM) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -ENOSPC; ++ } ++ } else { ++ if (phy->csi.mac_filter_cnt >= MAX_CSI_MAC_NUM/2) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -ENOSPC; ++ } ++ } ++ ++ ent = mt7915_csi_mac_filter_find(phy, mac_addr); ++ if (ent) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -EEXIST; ++ } ++ ++ ent = kzalloc(sizeof(*ent), GFP_KERNEL); ++ if (!ent) { ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return -ENOMEM; ++ } ++ ++ ether_addr_copy(ent->mac, mac_addr); ++ ent->interval = sta_interval; ++ } ++ ++ err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, ++ mac_addr, sta_interval); ++ if (err) { ++ if (v2 == ADD_CSI_MAC) ++ kfree(ent); ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ return err; ++ } ++ ++ if (v2 == DEL_CSI_MAC) { ++ list_del(&ent->node); ++ kfree(ent); ++ phy->csi.mac_filter_cnt--; ++ } else { ++ list_add_tail(&ent->node, &phy->csi.mac_filter_list); ++ phy->csi.mac_filter_cnt++; ++ } ++ ++ mutex_unlock(&phy->csi.mac_filter_lock); ++ } else if (mode == 2 && type == 8 && v1 == 1 && v2 == SHOW_CSI_MAC) { ++ return mt7915_vendor_reply_csi_mac_filter(wiphy, phy); ++ } else { ++ err = mt7915_mcu_set_csi(phy, mode, type, v1, v2, ++ mac_addr, sta_interval); ++ if (err) ++ return err; ++ } + + phy->csi.enable = !!mode; + @@ -804,20 +1042,20 @@ index 0000000..55da60a + } + + /* clean up old csi stats */ -+ if ((mode == 0 || mode == 2) && !list_empty(&phy->csi.csi_list)) { ++ if (mode == 0 && !list_empty(&phy->csi.data_list)) { + struct csi_data *c, *tmp_c; + -+ list_for_each_entry_safe(c, tmp_c, &phy->csi.csi_list, ++ spin_lock_bh(&phy->csi.data_lock); ++ list_for_each_entry_safe(c, tmp_c, &phy->csi.data_list, + node) { + list_del(&c->node); + kfree(c); + phy->csi.count--; + } ++ spin_unlock_bh(&phy->csi.data_lock); + } else if (mode == 1) { + phy->csi.last_record = 0; + } -+ -+ spin_unlock_bh(&phy->csi.csi_lock); + } + + if (tb[MTK_VENDOR_ATTR_CSI_CTRL_INTERVAL]) @@ -933,14 +1171,14 @@ index 0000000..55da60a + *storage |= RESERVED_SET; + } + -+ spin_lock_bh(&phy->csi.csi_lock); ++ spin_lock_bh(&phy->csi.data_lock); + -+ if (!list_empty(&phy->csi.csi_list)) { ++ if (!list_empty(&phy->csi.data_list)) { + struct csi_data *csi; + void *a, *b; + int i; + -+ csi = list_first_entry(&phy->csi.csi_list, struct csi_data, node); ++ csi = list_first_entry(&phy->csi.data_list, struct csi_data, node); + + mt7915_vendor_csi_tone_mask(phy, csi); + @@ -993,7 +1231,7 @@ index 0000000..55da60a + err = phy->csi.count; + } +out: -+ spin_unlock_bh(&phy->csi.csi_lock); ++ spin_unlock_bh(&phy->csi.data_lock); + + return err; +} @@ -1020,10 +1258,10 @@ index 0000000..55da60a +} diff --git a/mt7915/vendor.h b/mt7915/vendor.h new file mode 100644 -index 0000000..e1f5fd3 +index 00000000..d2b90aa0 --- /dev/null +++ b/mt7915/vendor.h -@@ -0,0 +1,63 @@ +@@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: ISC */ +#ifndef __MT7915_VENDOR_H +#define __MT7915_VENDOR_H @@ -1049,6 +1287,7 @@ index 0000000..e1f5fd3 + MTK_VENDOR_ATTR_CSI_CTRL_DUMP_NUM, + + MTK_VENDOR_ATTR_CSI_CTRL_DATA, ++ MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER, + + /* keep last */ + NUM_MTK_VENDOR_ATTRS_CSI_CTRL, @@ -1086,7 +1325,18 @@ index 0000000..e1f5fd3 + NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1 +}; + ++enum mtk_vendor_attr_csi_mac_filter { ++ MTK_VENDOR_ATTR_CSI_MAC_FILTER_UNSPEC, ++ ++ MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAC, ++ MTK_VENDOR_ATTR_CSI_MAC_FILTER_INTERVAL, ++ ++ /* keep last */ ++ NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER, ++ MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX = ++ NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER - 1 ++}; +#endif -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch b/feeds/mediatek-sdk/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch index b2156ede1..06612eda2 100644 --- a/feeds/mediatek-sdk/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1002-wifi-mt76-mt7915-air-monitor-support.patch @@ -1,22 +1,22 @@ -From 1a63c07be0a813d1342346c937cd2f949439b837 Mon Sep 17 00:00:00 2001 +From 3ae462a794ae2a8b613c23aa6179cf5c7b2f7b3c Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Tue, 11 Jan 2022 12:03:23 +0800 -Subject: [PATCH] wifi: mt76: mt7915: air monitor support +Subject: [PATCH 1002/1052] wifi: mt76: mt7915: air monitor support --- mt76_connac_mcu.h | 2 + mt7915/mac.c | 4 + mt7915/main.c | 3 + - mt7915/mt7915.h | 32 ++++ + mt7915/mt7915.h | 33 +++++ mt7915/vendor.c | 361 ++++++++++++++++++++++++++++++++++++++++++++++ mt7915/vendor.h | 38 +++++ - 6 files changed, 440 insertions(+) + 6 files changed, 441 insertions(+) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index cda7559..3aa4e59 100644 +index ad63596d..cd6db774 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1243,6 +1243,8 @@ enum { +@@ -1245,6 +1245,8 @@ enum { MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab, MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac, MCU_EXT_CMD_PHY_STAT_INFO = 0xad, @@ -26,7 +26,7 @@ index cda7559..3aa4e59 100644 MCU_EXT_CMD_CSI_CTRL = 0xc2, }; diff --git a/mt7915/mac.c b/mt7915/mac.c -index d99864f..e38905a 100644 +index 8268c19a..778f04f7 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -531,6 +531,10 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb, @@ -41,7 +41,7 @@ index d99864f..e38905a 100644 status->flag |= RX_FLAG_8023; mt7915_wed_check_ppe(dev, &dev->mt76.q_rx[q], msta, skb, diff --git a/mt7915/main.c b/mt7915/main.c -index 4edb11a..847c74b 100644 +index 12bb0b39..aca3e9c0 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -800,6 +800,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, @@ -55,13 +55,21 @@ index 4edb11a..847c74b 100644 } diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 5a26335..576e70a 100644 +index 1316f93d..bb39a53a 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -232,6 +232,33 @@ struct csi_data { +@@ -232,6 +232,7 @@ struct csi_data { struct list_head node; }; ++ + struct csi_mac_filter { + struct list_head node; + +@@ -244,6 +245,33 @@ struct csi_mac_filter { + #define SHOW_CSI_MAC 2 + + #define MAX_CSI_MAC_NUM 10 + +#define MT7915_AIR_MONITOR_MAX_ENTRY 16 +#define MT7915_AIR_MONITOR_MAX_GROUP MT7915_AIR_MONITOR_MAX_ENTRY >> 1 @@ -92,7 +100,7 @@ index 5a26335..576e70a 100644 #endif struct mt7915_phy { -@@ -296,6 +323,8 @@ struct mt7915_phy { +@@ -312,6 +340,8 @@ struct mt7915_phy { u32 interval; u32 last_record; } csi; @@ -101,10 +109,10 @@ index 5a26335..576e70a 100644 #endif }; -@@ -705,6 +734,9 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, - void mt7915_vendor_register(struct mt7915_phy *phy); - int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, +@@ -722,6 +752,9 @@ int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval); + struct csi_mac_filter *mt7915_csi_mac_filter_find(struct mt7915_phy *phy, u8 *addr); + void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy); +void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); +int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, + struct ieee80211_sta *sta); @@ -112,10 +120,10 @@ index 5a26335..576e70a 100644 #ifdef MTK_DEBUG diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 55da60a..c964b14 100644 +index 92496513..fb32cd6d 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -448,6 +448,355 @@ out: +@@ -584,6 +584,355 @@ out: return err; } @@ -471,7 +479,7 @@ index 55da60a..c964b14 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -460,6 +809,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -596,6 +945,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_csi_ctrl_dump, .policy = csi_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_CSI_CTRL_MAX, @@ -491,7 +499,7 @@ index 55da60a..c964b14 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index e1f5fd3..1863eee 100644 +index d2b90aa0..429b25b7 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -5,6 +5,7 @@ @@ -502,10 +510,11 @@ index e1f5fd3..1863eee 100644 MTK_NL80211_VENDOR_SUBCMD_CSI_CTRL = 0xc2, }; -@@ -60,4 +61,41 @@ enum mtk_vendor_attr_csi_data { - NUM_MTK_VENDOR_ATTRS_CSI_DATA - 1 +@@ -72,4 +73,41 @@ enum mtk_vendor_attr_csi_mac_filter { + MTK_VENDOR_ATTR_CSI_MAC_FILTER_MAX = + NUM_MTK_VENDOR_ATTRS_CSI_MAC_FILTER - 1 }; - ++ +enum mtk_vendor_attr_mnt_ctrl { + MTK_VENDOR_ATTR_AMNT_CTRL_UNSPEC, + @@ -542,7 +551,6 @@ index e1f5fd3..1863eee 100644 + MTK_VENDOR_ATTR_AMNT_DUMP_MAX = + NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1 +}; -+ #endif -- 2.18.0 diff --git a/feeds/mediatek-sdk/mt76/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch b/feeds/mediatek-sdk/mt76/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch index d7b9f550c..7bf27a449 100644 --- a/feeds/mediatek-sdk/mt76/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch +++ b/feeds/mediatek-sdk/mt76/patches/1003-wifi-mt76-mt7915-add-support-for-muru_onoff-via.patch @@ -1,7 +1,7 @@ -From a0249520b2ff800bcff8ed1f8531dddccc97d29b Mon Sep 17 00:00:00 2001 +From 6ec4565becc5364a689b346496c7caaef98f83e9 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Tue, 4 Apr 2023 02:23:57 +0800 -Subject: [PATCH 1003/1053] wifi: mt76: mt7915: add support for muru_onoff via +Subject: [PATCH 1003/1052] wifi: mt76: mt7915: add support for muru_onoff via --- mt7915/init.c | 1 + @@ -12,10 +12,10 @@ Subject: [PATCH 1003/1053] wifi: mt76: mt7915: add support for muru_onoff via 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/mt7915/init.c b/mt7915/init.c -index 6d23dfd..fc42974 100644 +index ac15bc53..18c6ef7e 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -363,6 +363,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -364,6 +364,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US; phy->slottime = 9; @@ -24,7 +24,7 @@ index 6d23dfd..fc42974 100644 hw->sta_data_size = sizeof(struct mt7915_sta); hw->vif_data_size = sizeof(struct mt7915_vif); diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 9baf52b..6f73a7b 100644 +index 44765b1f..6867635f 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -965,6 +965,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, @@ -57,7 +57,7 @@ index 9baf52b..6f73a7b 100644 muru->mimo_dl.vht_mu_bfee = !!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index f32d525..f44146e 100644 +index f32d5256..f44146ed 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -678,4 +678,10 @@ enum CSI_CHAIN_TYPE { @@ -72,10 +72,10 @@ index f32d525..f44146e 100644 + #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 35ccfa3..e21a101 100644 +index bb39a53a..14107de3 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -289,6 +289,8 @@ struct mt7915_phy { +@@ -302,6 +302,8 @@ struct mt7915_phy { u32 rx_ampdu_ts; u32 ampdu_ref; @@ -85,7 +85,7 @@ index 35ccfa3..e21a101 100644 struct mt76_channel_state state_ts; diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index d2b5b7d..f521740 100644 +index 665d8bd4..0beb3644 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -2554,6 +2554,38 @@ static int mt7915_token_txd_read(struct seq_file *s, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/1004-wifi-mt76-mt7915-certification-patches.patch b/feeds/mediatek-sdk/mt76/patches/1004-wifi-mt76-mt7915-certification-patches.patch index 6f8ce965f..7024d1f5d 100644 --- a/feeds/mediatek-sdk/mt76/patches/1004-wifi-mt76-mt7915-certification-patches.patch +++ b/feeds/mediatek-sdk/mt76/patches/1004-wifi-mt76-mt7915-certification-patches.patch @@ -1,7 +1,7 @@ -From e98f4b4ccc941705436b9cdfbd22b2e72b2ef055 Mon Sep 17 00:00:00 2001 +From 230a5ba21216bb292f2fb1b0cf2236e2e14de2ca Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Mon, 6 Jun 2022 20:15:51 +0800 -Subject: [PATCH] wifi: mt76: mt7915: certification patches +Subject: [PATCH 1004/1052] wifi: mt76: mt7915: certification patches --- mt76_connac_mcu.h | 1 + @@ -16,10 +16,10 @@ Subject: [PATCH] wifi: mt76: mt7915: certification patches 9 files changed, 955 insertions(+), 5 deletions(-) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 3aa4e59..d62b7df 100644 +index cd6db774..bd28cc50 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1246,6 +1246,7 @@ enum { +@@ -1248,6 +1248,7 @@ enum { /* for vendor csi and air monitor */ MCU_EXT_CMD_SMESH_CTRL = 0xae, MCU_EXT_CMD_SET_QOS_MAP = 0xb4, @@ -28,7 +28,7 @@ index 3aa4e59..d62b7df 100644 }; diff --git a/mt7915/mac.c b/mt7915/mac.c -index e38905a..43cff27 100644 +index 778f04f7..2fd1d1fb 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -8,6 +8,7 @@ @@ -39,7 +39,7 @@ index e38905a..43cff27 100644 #define to_rssi(field, rcpi) ((FIELD_GET(field, rcpi) - 220) / 2) -@@ -2002,6 +2003,21 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy) +@@ -1961,6 +1962,21 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy) spin_unlock_bh(&phy->stats_lock); } @@ -61,7 +61,7 @@ index e38905a..43cff27 100644 void mt7915_mac_sta_rc_work(struct work_struct *work) { struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work); -@@ -2024,6 +2040,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) +@@ -1983,6 +1999,13 @@ void mt7915_mac_sta_rc_work(struct work_struct *work) sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv); @@ -76,7 +76,7 @@ index e38905a..43cff27 100644 IEEE80211_RC_NSS_CHANGED | IEEE80211_RC_BW_CHANGED)) diff --git a/mt7915/main.c b/mt7915/main.c -index 847c74b..8835cda 100644 +index aca3e9c0..09e1a83b 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -771,6 +771,9 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, @@ -107,7 +107,7 @@ index 847c74b..8835cda 100644 void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index b38c3d1..b50a2c2 100644 +index 6867635f..c819a3be 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4402,6 +4402,472 @@ mt7915_mcu_report_csi(struct mt7915_dev *dev, struct sk_buff *skb) @@ -584,7 +584,7 @@ index b38c3d1..b50a2c2 100644 #ifdef MTK_DEBUG diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index f44146e..eef2fc0 100644 +index f44146ed..eef2fc00 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -486,10 +486,14 @@ enum { @@ -818,10 +818,10 @@ index f44146e..eef2fc0 100644 #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 30fb064..136e89f 100644 +index 14107de3..cf49ac86 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -733,6 +733,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, +@@ -749,6 +749,19 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, bool pci, int *irq); #ifdef CONFIG_MTK_VENDOR @@ -842,7 +842,7 @@ index 30fb064..136e89f 100644 int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, u8 cfg, u8 v1, u32 v2, u8 *mac_addr, u32 sta_interval); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 2f55a84..84f8fae 100644 +index 0beb3644..54daa736 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -2560,7 +2560,8 @@ static int mt7915_muru_onoff_get(void *data, u64 *val) @@ -867,11 +867,11 @@ index 2f55a84..84f8fae 100644 } diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index c964b14..7a71894 100644 +index fb32cd6d..e4317af3 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -23,6 +23,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = { - [MTK_VENDOR_ATTR_CSI_CTRL_DATA] = { .type = NLA_NESTED }, +@@ -24,6 +24,29 @@ csi_ctrl_policy[NUM_MTK_VENDOR_ATTRS_CSI_CTRL] = { + [MTK_VENDOR_ATTR_CSI_CTRL_DUMP_MAC_FILTER] = { .type = NLA_NESTED }, }; +static const struct nla_policy @@ -900,7 +900,7 @@ index c964b14..7a71894 100644 struct csi_null_tone { u8 start; u8 end; -@@ -797,6 +820,149 @@ mt7915_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, +@@ -933,6 +956,149 @@ mt7915_vendor_amnt_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, return len + 1; } @@ -1050,7 +1050,7 @@ index c964b14..7a71894 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -821,6 +987,28 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -957,6 +1123,28 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_amnt_ctrl_dump, .policy = amnt_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_AMNT_CTRL_MAX, @@ -1080,7 +1080,7 @@ index c964b14..7a71894 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 1863eee..1a18cae 100644 +index 429b25b7..1a0139d7 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -7,6 +7,48 @@ diff --git a/feeds/mediatek-sdk/mt76/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch b/feeds/mediatek-sdk/mt76/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch index 137028bb5..d110348be 100644 --- a/feeds/mediatek-sdk/mt76/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch +++ b/feeds/mediatek-sdk/mt76/patches/1005-wifi-mt76-mt7915-add-mt76-vendor-muru-onoff-command.patch @@ -1,7 +1,7 @@ -From 7f14adae86830929258aad73e8290a7fd2b4e03e Mon Sep 17 00:00:00 2001 +From d6ae847c0cea20f781970198a2aed4dc7e4daffa Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Tue, 4 Apr 2023 02:27:44 +0800 -Subject: [PATCH 1005/1053] wifi: mt76: mt7915: add mt76 vendor muru onoff +Subject: [PATCH 1005/1052] wifi: mt76: mt7915: add mt76 vendor muru onoff command --- @@ -12,7 +12,7 @@ Subject: [PATCH 1005/1053] wifi: mt76: mt7915: add mt76 vendor muru onoff 4 files changed, 63 insertions(+) diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index cd533ae..63fb826 100644 +index c819a3be..cd5363c6 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4422,6 +4422,13 @@ void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif) @@ -30,7 +30,7 @@ index cd533ae..63fb826 100644 } diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index eef2fc0..8650053 100644 +index eef2fc00..86500536 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -493,6 +493,7 @@ enum { @@ -42,10 +42,10 @@ index eef2fc0..8650053 100644 }; diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 7a71894..a8b1fa8 100644 +index e4317af3..cf09b513 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -35,6 +35,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { +@@ -36,6 +36,11 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 }, }; @@ -57,7 +57,7 @@ index 7a71894..a8b1fa8 100644 static const struct nla_policy rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = { [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 }, -@@ -963,6 +968,33 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, +@@ -1099,6 +1104,33 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, return 0; } @@ -91,7 +91,7 @@ index 7a71894..a8b1fa8 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1009,6 +1041,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1145,6 +1177,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .doit = mt7915_vendor_wireless_ctrl, .policy = wireless_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, @@ -110,7 +110,7 @@ index 7a71894..a8b1fa8 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 1a18cae..a4a9180 100644 +index 1a0139d7..9cb67551 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -9,6 +9,7 @@ enum mtk_nl80211_vendor_subcmds { diff --git a/feeds/mediatek-sdk/mt76/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch b/feeds/mediatek-sdk/mt76/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch index 71d9c03f5..0182c4f39 100644 --- a/feeds/mediatek-sdk/mt76/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch +++ b/feeds/mediatek-sdk/mt76/patches/1006-wifi-mt76-mt7915-drop-undefined-action-frame.patch @@ -1,14 +1,14 @@ -From 3b76edcb079437bf742c4442c4db4609cf10d6b6 Mon Sep 17 00:00:00 2001 +From d48d6a0643e5be590744db4173e14c87f4945390 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Thu, 14 Apr 2022 15:18:02 +0800 -Subject: [PATCH 1006/1053] wifi: mt76: mt7915: drop undefined action frame +Subject: [PATCH 1006/1052] wifi: mt76: mt7915: drop undefined action frame --- mt7915/mac.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 43cff27..6b99437 100644 +index 2fd1d1fb..4177d6a3 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -744,6 +744,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, diff --git a/feeds/mediatek-sdk/mt76/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch b/feeds/mediatek-sdk/mt76/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch index 8f2d84103..0f0e9d595 100644 --- a/feeds/mediatek-sdk/mt76/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch +++ b/feeds/mediatek-sdk/mt76/patches/1007-wifi-mt76-testmode-rework-testmode-init-registers.patch @@ -1,7 +1,7 @@ -From 6668ef935f03e166732511ed063f706b9139cd19 Mon Sep 17 00:00:00 2001 +From bbbac8090c06fd110f3770d99e7993017101cfd0 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Mon, 6 Jun 2022 19:46:26 +0800 -Subject: [PATCH 1007/1053] wifi: mt76: testmode: rework testmode init +Subject: [PATCH 1007/1052] wifi: mt76: testmode: rework testmode init registers --- @@ -18,10 +18,10 @@ Subject: [PATCH 1007/1053] wifi: mt76: testmode: rework testmode init 10 files changed, 164 insertions(+), 35 deletions(-) diff --git a/mac80211.c b/mac80211.c -index b30a74e..3f5c2ed 100644 +index 4d50bfae..9ebb2746 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -804,7 +804,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) +@@ -805,7 +805,8 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) } #ifdef CONFIG_NL80211_TESTMODE @@ -32,7 +32,7 @@ index b30a74e..3f5c2ed 100644 if (status->flag & RX_FLAG_FAILED_FCS_CRC) phy->test.rx_stats.fcs_error[q]++; diff --git a/mt76.h b/mt76.h -index a07c7df..fe5b136 100644 +index 063fc364..329e4d7a 100644 --- a/mt76.h +++ b/mt76.h @@ -709,6 +709,8 @@ struct mt76_testmode_ops { @@ -62,10 +62,10 @@ index a07c7df..fe5b136 100644 }; diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 53262ce..75cb4e9 100644 +index bd28cc50..f5edeef6 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1239,6 +1239,7 @@ enum { +@@ -1241,6 +1241,7 @@ enum { MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a, MCU_EXT_CMD_SET_RDD_TH = 0x9d, MCU_EXT_CMD_MURU_CTRL = 0x9f, @@ -74,7 +74,7 @@ index 53262ce..75cb4e9 100644 MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab, MCU_EXT_CMD_DPD_PRE_CAL_INFO = 0xac, diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 8650053..7653b5e 100644 +index 86500536..7653b5e2 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -9,6 +9,7 @@ @@ -86,7 +86,7 @@ index 8650053..7653b5e 100644 MCU_ATE_CLEAN_TXQUEUE = 0x1c, }; diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 6004d64..694fc1b 100644 +index d6ecd698..02b4714c 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -120,6 +120,7 @@ static const u32 mt7986_reg[] = { @@ -106,7 +106,7 @@ index 6004d64..694fc1b 100644 [TMAC_ODTR] = 0x0cc, [TMAC_ATCR] = 0x00c, diff --git a/mt7915/regs.h b/mt7915/regs.h -index 3452a7e..8bb6a9f 100644 +index 3452a7e9..8bb6a9f2 100644 --- a/mt7915/regs.h +++ b/mt7915/regs.h @@ -48,6 +48,7 @@ enum reg_rev { @@ -154,7 +154,7 @@ index 3452a7e..8bb6a9f 100644 #define MT_AGG_ACR0(_band) MT_WF_AGG(_band, __OFFS(AGG_ACR0)) #define MT_AGG_ACR_CFEND_RATE GENMASK(13, 0) diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index 0d76ae3..4693919 100644 +index 0d76ae31..46939191 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -30,7 +30,7 @@ struct reg_band { @@ -379,7 +379,7 @@ index 0d76ae3..4693919 100644 const struct mt76_testmode_ops mt7915_testmode_ops = { diff --git a/mt7915/testmode.h b/mt7915/testmode.h -index 5573ac3..a1c54c8 100644 +index 5573ac30..a1c54c89 100644 --- a/mt7915/testmode.h +++ b/mt7915/testmode.h @@ -33,6 +33,12 @@ struct mt7915_tm_clean_txq { @@ -430,7 +430,7 @@ index 5573ac3..a1c54c8 100644 + #endif diff --git a/testmode.c b/testmode.c -index ca4fecc..9e05b86 100644 +index ca4feccf..9e05b862 100644 --- a/testmode.c +++ b/testmode.c @@ -448,8 +448,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -454,7 +454,7 @@ index ca4fecc..9e05b86 100644 return -EMSGSIZE; diff --git a/testmode.h b/testmode.h -index 5e2792d..8961326 100644 +index 5e2792d8..89613266 100644 --- a/testmode.h +++ b/testmode.h @@ -101,6 +101,8 @@ enum mt76_testmode_attr { diff --git a/feeds/mediatek-sdk/mt76/patches/1008-wifi-mt76-testmode-additional-supports.patch b/feeds/mediatek-sdk/mt76/patches/1008-wifi-mt76-testmode-additional-supports.patch index fa6094e9c..ecdfd6283 100644 --- a/feeds/mediatek-sdk/mt76/patches/1008-wifi-mt76-testmode-additional-supports.patch +++ b/feeds/mediatek-sdk/mt76/patches/1008-wifi-mt76-testmode-additional-supports.patch @@ -1,4 +1,4 @@ -From e6c4c7343a54ef607d8ceafa4615a32165c121fd Mon Sep 17 00:00:00 2001 +From 5731c2406732aff2f7702091d197f15245ac375c Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Thu, 21 Apr 2022 15:43:19 +0800 Subject: [PATCH] wifi: mt76: testmode: additional supports @@ -20,13 +20,13 @@ Signed-off-by: StanleyYP Wang mt7915/mmio.c | 2 + mt7915/mt7915.h | 17 +- mt7915/regs.h | 3 + - mt7915/testmode.c | 1244 ++++++++++++++++++++++++++++++++++++++++++--- + mt7915/testmode.c | 1245 ++++++++++++++++++++++++++++++++++++++++++--- mt7915/testmode.h | 278 ++++++++++ testmode.c | 289 +++++++++-- - testmode.h | 79 +++ + testmode.h | 85 ++++ tools/fields.c | 90 +++- tx.c | 3 +- - 20 files changed, 2073 insertions(+), 169 deletions(-) + 20 files changed, 2080 insertions(+), 169 deletions(-) diff --git a/dma.c b/dma.c index ccdd564..bc8afcf 100644 @@ -43,7 +43,7 @@ index ccdd564..bc8afcf 100644 #endif diff --git a/mac80211.c b/mac80211.c -index 3f5c2ed..305cae7 100644 +index 9ebb274..d6b7037 100644 --- a/mac80211.c +++ b/mac80211.c @@ -55,6 +55,13 @@ static const struct ieee80211_channel mt76_channels_5ghz[] = { @@ -73,10 +73,10 @@ index 3f5c2ed..305cae7 100644 static const struct ieee80211_channel mt76_channels_6ghz[] = { diff --git a/mt76.h b/mt76.h -index fe5b136..a7d424f 100644 +index 6575dd2..e29df4e 100644 --- a/mt76.h +++ b/mt76.h -@@ -707,6 +707,21 @@ struct mt76_testmode_ops { +@@ -714,6 +714,21 @@ struct mt76_testmode_ops { int (*set_params)(struct mt76_phy *phy, struct nlattr **tb, enum mt76_testmode_state new_state); int (*dump_stats)(struct mt76_phy *phy, struct sk_buff *msg); @@ -98,7 +98,7 @@ index fe5b136..a7d424f 100644 }; #define MT_TM_FW_RX_COUNT BIT(0) -@@ -715,16 +730,13 @@ struct mt76_testmode_data { +@@ -722,16 +737,13 @@ struct mt76_testmode_data { enum mt76_testmode_state state; u32 param_set[DIV_ROUND_UP(NUM_MT76_TM_ATTRS, 32)]; @@ -117,7 +117,7 @@ index fe5b136..a7d424f 100644 u8 tx_rate_stbc; u8 tx_ltf; -@@ -740,10 +752,37 @@ struct mt76_testmode_data { +@@ -747,10 +759,37 @@ struct mt76_testmode_data { u8 tx_power[4]; u8 tx_power_control; @@ -156,7 +156,7 @@ index fe5b136..a7d424f 100644 u32 tx_pending; u32 tx_queued; u16 tx_queued_limit; -@@ -1348,6 +1387,68 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy) +@@ -1355,6 +1394,68 @@ static inline bool mt76_testmode_enabled(struct mt76_phy *phy) #endif } @@ -225,7 +225,7 @@ index fe5b136..a7d424f 100644 static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, struct sk_buff *skb, struct ieee80211_hw **hw) -@@ -1358,7 +1459,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, +@@ -1365,7 +1466,8 @@ static inline bool mt76_is_testmode_skb(struct mt76_dev *dev, for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { struct mt76_phy *phy = dev->phys[i]; @@ -235,7 +235,7 @@ index fe5b136..a7d424f 100644 *hw = dev->phys[i]->hw; return true; } -@@ -1460,7 +1562,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -1467,7 +1569,8 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, struct netlink_callback *cb, void *data, int len); int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); @@ -246,7 +246,7 @@ index fe5b136..a7d424f 100644 static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) { diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c -index a8f097d..44cd646 100644 +index 4e84f8d..2acd7ef 100644 --- a/mt76_connac_mcu.c +++ b/mt76_connac_mcu.c @@ -407,6 +407,7 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb, @@ -268,10 +268,10 @@ index a8f097d..44cd646 100644 return; diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 22d477f..0f408d9 100644 +index f5edeef..152b4aa 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1023,6 +1023,7 @@ enum { +@@ -1024,6 +1024,7 @@ enum { MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13, MCU_EXT_EVENT_THERMAL_PROTECT = 0x22, MCU_EXT_EVENT_ASSERT_DUMP = 0x23, @@ -279,7 +279,7 @@ index 22d477f..0f408d9 100644 MCU_EXT_EVENT_RDD_REPORT = 0x3a, MCU_EXT_EVENT_CSA_NOTIFY = 0x4f, MCU_EXT_EVENT_BSS_ACQ_PKT_CNT = 0x52, -@@ -1246,6 +1247,7 @@ enum { +@@ -1248,6 +1249,7 @@ enum { MCU_EXT_CMD_PHY_STAT_INFO = 0xad, /* for vendor csi and air monitor */ MCU_EXT_CMD_SMESH_CTRL = 0xae, @@ -301,10 +301,10 @@ index bfdbc15..f4876fe 100644 return ret; } diff --git a/mt7915/init.c b/mt7915/init.c -index 0350250..5c4aa1e 100644 +index 18c6ef7..0c58ab7 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -727,7 +727,7 @@ static void mt7915_init_work(struct work_struct *work) +@@ -700,7 +700,7 @@ static void mt7915_init_work(struct work_struct *work) struct mt7915_dev *dev = container_of(work, struct mt7915_dev, init_work); @@ -314,7 +314,7 @@ index 0350250..5c4aa1e 100644 mt7915_txbf_init(dev); } diff --git a/mt7915/mac.c b/mt7915/mac.c -index 6b99437..7d3397e 100644 +index 79eb92b..7fce115 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -586,6 +586,7 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb) @@ -394,7 +394,7 @@ index 6b99437..7d3397e 100644 #endif } -@@ -1420,7 +1444,7 @@ mt7915_mac_restart(struct mt7915_dev *dev) +@@ -1379,7 +1403,7 @@ mt7915_mac_restart(struct mt7915_dev *dev) goto out; /* set the necessary init items */ @@ -404,7 +404,7 @@ index 6b99437..7d3397e 100644 goto out; diff --git a/mt7915/main.c b/mt7915/main.c -index 8835cda..e53754c 100644 +index caff98c..721aa66 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -238,7 +238,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, @@ -417,7 +417,7 @@ index 8835cda..e53754c 100644 mvif->mt76.wmm_idx += 2; diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 0d1bab1..05919e9 100644 +index cd5363c..b5177e3 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -478,6 +478,11 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb) @@ -556,7 +556,7 @@ index 7653b5e..c791c7f 100644 enum { diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 694fc1b..222e2cf 100644 +index 02b4714..730cd33 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -134,6 +134,7 @@ static const u32 mt7915_offs[] = { @@ -576,10 +576,10 @@ index 694fc1b..222e2cf 100644 [AGG_PCR0] = 0x040, [AGG_ACR0] = 0x054, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 136e89f..37abf56 100644 +index f7aeb44..efa9488 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -304,11 +304,15 @@ struct mt7915_phy { +@@ -321,11 +321,15 @@ struct mt7915_phy { s32 last_freq_offset; u8 last_rcpi[4]; @@ -595,7 +595,7 @@ index 136e89f..37abf56 100644 } test; #endif -@@ -421,6 +425,14 @@ struct mt7915_dev { +@@ -442,6 +446,14 @@ struct mt7915_dev { void __iomem *dcm; void __iomem *sku; @@ -610,7 +610,7 @@ index 136e89f..37abf56 100644 #ifdef MTK_DEBUG u16 wlan_idx; struct { -@@ -601,8 +613,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, +@@ -622,8 +634,8 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, void *data, u32 field); @@ -621,14 +621,14 @@ index 136e89f..37abf56 100644 int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num); int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, bool hdr_trans); -@@ -641,6 +653,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); +@@ -662,6 +674,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_exit(struct mt7915_dev *dev); +int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_wmm_pbc_work(struct work_struct *work); - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif); + static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) diff --git a/mt7915/regs.h b/mt7915/regs.h index 8bb6a9f..1236da9 100644 --- a/mt7915/regs.h @@ -651,7 +651,7 @@ index 8bb6a9f..1236da9 100644 (_n) * 4)) #define MT_AGG_PCR0(_band, _n) MT_WF_AGG(_band, (__OFFS(AGG_PCR0) + \ diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index 4693919..32dc85c 100644 +index 4693919..10713f6 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -9,6 +9,10 @@ @@ -1896,9 +1896,11 @@ index 4693919..32dc85c 100644 } static int -@@ -617,34 +1626,7 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en) +@@ -616,35 +1625,9 @@ mt7915_tm_set_tx_cont(struct mt7915_phy *phy, bool en) + tx_cont->center_ch = freq1; tx_cont->tx_ant = td->tx_antenna_mask; tx_cont->band = band; ++ tx_cont->txfd_mode = 3; - switch (chandef->width) { - case NL80211_CHAN_WIDTH_40: @@ -1932,7 +1934,7 @@ index 4693919..32dc85c 100644 if (!en) { req.op.rf.param.func_data = cpu_to_le32(band); -@@ -728,6 +1710,18 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed) +@@ -728,6 +1711,18 @@ mt7915_tm_update_params(struct mt7915_phy *phy, u32 changed) mt7915_tm_set_freq_offset(phy, en, en ? td->freq_offset : 0); if (changed & BIT(TM_CHANGED_TXPOWER)) mt7915_tm_set_tx_power(phy); @@ -1951,7 +1953,7 @@ index 4693919..32dc85c 100644 } static int -@@ -737,6 +1731,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) +@@ -737,6 +1732,11 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) struct mt7915_phy *phy = mphy->priv; enum mt76_testmode_state prev_state = td->state; @@ -1963,7 +1965,7 @@ index 4693919..32dc85c 100644 mphy->test.state = state; if (prev_state == MT76_TM_STATE_TX_FRAMES || -@@ -757,7 +1756,7 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) +@@ -757,7 +1757,7 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) (state == MT76_TM_STATE_OFF && prev_state == MT76_TM_STATE_IDLE)) { u32 changed = 0; @@ -1972,7 +1974,7 @@ index 4693919..32dc85c 100644 for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { u16 cur = tm_change_map[i]; -@@ -766,6 +1765,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) +@@ -766,6 +1766,10 @@ mt7915_tm_set_state(struct mt76_phy *mphy, enum mt76_testmode_state state) changed |= BIT(i); } @@ -1983,7 +1985,7 @@ index 4693919..32dc85c 100644 mt7915_tm_update_params(phy, changed); } -@@ -778,10 +1781,8 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, +@@ -778,10 +1782,8 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, { struct mt76_testmode_data *td = &mphy->test; struct mt7915_phy *phy = mphy->priv; @@ -1996,7 +1998,7 @@ index 4693919..32dc85c 100644 BUILD_BUG_ON(NUM_TM_CHANGED >= 32); -@@ -789,9 +1790,9 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, +@@ -789,9 +1791,9 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, td->state == MT76_TM_STATE_OFF) return 0; @@ -2009,7 +2011,7 @@ index 4693919..32dc85c 100644 for (i = 0; i < ARRAY_SIZE(tm_change_map); i++) { if (tb[tm_change_map[i]]) -@@ -807,6 +1808,7 @@ static int +@@ -807,6 +1809,7 @@ static int mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) { struct mt7915_phy *phy = mphy->priv; @@ -2017,7 +2019,7 @@ index 4693919..32dc85c 100644 void *rx, *rssi; int i; -@@ -827,6 +1829,16 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) +@@ -827,6 +1830,16 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) nla_nest_end(msg, rssi); @@ -2034,7 +2036,7 @@ index 4693919..32dc85c 100644 rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI); if (!rssi) return -ENOMEM; -@@ -852,11 +1864,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) +@@ -852,11 +1865,75 @@ mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) nla_nest_end(msg, rx); @@ -2919,7 +2921,7 @@ index 9e05b86..7587047 100644 if (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_POWER)) { diff --git a/testmode.h b/testmode.h -index 8961326..7a68625 100644 +index 8961326..3fad988 100644 --- a/testmode.h +++ b/testmode.h @@ -6,6 +6,8 @@ @@ -2939,7 +2941,17 @@ index 8961326..7a68625 100644 * @MT76_TM_ATTR_TX_COUNT: configured number of frames to send when setting * state to MT76_TM_STATE_TX_FRAMES (u32) * @MT76_TM_ATTR_TX_PENDING: pending frames during MT76_TM_STATE_TX_FRAMES (u32) -@@ -47,6 +50,15 @@ +@@ -34,6 +37,9 @@ + * @MT76_TM_ATTR_TX_POWER_CONTROL: enable tx power control (u8) + * @MT76_TM_ATTR_TX_POWER: per-antenna tx power array (nested, u8 attrs) + * ++ * @MT76_TM_ATTR_TX_PKT_BW: per-packet data bandwidth (u8) ++ * @MT76_TM_ATTR_TX_PRI_SEL: primary channel selection index (u8) ++ * + * @MT76_TM_ATTR_FREQ_OFFSET: RF frequency offset (u32) + * + * @MT76_TM_ATTR_STATS: statistics (nested, see &enum mt76_testmode_stats_attr) +@@ -47,6 +53,15 @@ * @MT76_TM_ATTR_DRV_DATA: driver specific netlink attrs (nested) * * @MT76_TM_ATTR_MAC_ADDRS: array of nested MAC addresses (nested) @@ -2955,7 +2967,7 @@ index 8961326..7a68625 100644 */ enum mt76_testmode_attr { MT76_TM_ATTR_UNSPEC, -@@ -57,6 +69,7 @@ enum mt76_testmode_attr { +@@ -57,6 +72,7 @@ enum mt76_testmode_attr { MT76_TM_ATTR_MTD_PART, MT76_TM_ATTR_MTD_OFFSET, @@ -2963,7 +2975,17 @@ index 8961326..7a68625 100644 MT76_TM_ATTR_TX_COUNT, MT76_TM_ATTR_TX_LENGTH, MT76_TM_ATTR_TX_RATE_MODE, -@@ -84,6 +97,17 @@ enum mt76_testmode_attr { +@@ -71,6 +87,9 @@ enum mt76_testmode_attr { + MT76_TM_ATTR_TX_POWER_CONTROL, + MT76_TM_ATTR_TX_POWER, + ++ MT76_TM_ATTR_TX_PKT_BW, ++ MT76_TM_ATTR_TX_PRI_SEL, ++ + MT76_TM_ATTR_FREQ_OFFSET, + + MT76_TM_ATTR_STATS, +@@ -84,6 +103,17 @@ enum mt76_testmode_attr { MT76_TM_ATTR_DRV_DATA, MT76_TM_ATTR_MAC_ADDRS, @@ -2981,7 +3003,7 @@ index 8961326..7a68625 100644 /* keep last */ NUM_MT76_TM_ATTRS, -@@ -128,6 +152,7 @@ enum mt76_testmode_stats_attr { +@@ -128,6 +158,7 @@ enum mt76_testmode_stats_attr { * * @MT76_TM_RX_ATTR_FREQ_OFFSET: frequency offset (s32) * @MT76_TM_RX_ATTR_RCPI: received channel power indicator (array, u8) @@ -2989,7 +3011,7 @@ index 8961326..7a68625 100644 * @MT76_TM_RX_ATTR_IB_RSSI: internal inband RSSI (array, s8) * @MT76_TM_RX_ATTR_WB_RSSI: internal wideband RSSI (array, s8) * @MT76_TM_RX_ATTR_SNR: signal-to-noise ratio (u8) -@@ -137,6 +162,7 @@ enum mt76_testmode_rx_attr { +@@ -137,6 +168,7 @@ enum mt76_testmode_rx_attr { MT76_TM_RX_ATTR_FREQ_OFFSET, MT76_TM_RX_ATTR_RCPI, @@ -2997,7 +3019,7 @@ index 8961326..7a68625 100644 MT76_TM_RX_ATTR_IB_RSSI, MT76_TM_RX_ATTR_WB_RSSI, MT76_TM_RX_ATTR_SNR, -@@ -198,4 +224,57 @@ enum mt76_testmode_tx_mode { +@@ -198,4 +230,57 @@ enum mt76_testmode_tx_mode { extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS]; @@ -3235,7 +3257,7 @@ index e3f6908..406ba77 100644 }; diff --git a/tx.c b/tx.c -index 0fdf7d8..db0d4df 100644 +index b3d7669..0002779 100644 --- a/tx.c +++ b/tx.c @@ -259,8 +259,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff * @@ -3249,5 +3271,5 @@ index 0fdf7d8..db0d4df 100644 wake_up(&dev->tx_wait); -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch b/feeds/mediatek-sdk/mt76/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch index 3ccce52f3..991c4e491 100644 --- a/feeds/mediatek-sdk/mt76/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1009-wifi-mt76-testmode-add-pre-cal-support.patch @@ -1,7 +1,7 @@ -From 2d9fc3393a175ec0b132e6186df69baaad77e428 Mon Sep 17 00:00:00 2001 +From fbbb77d3e06f0dd3f4ed27e8bb5ff113fe3c77fc Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Wed, 31 Aug 2022 20:06:52 +0800 -Subject: [PATCH 1009/1053] wifi: mt76: testmode: add pre-cal support +Subject: [PATCH 1009/1052] wifi: mt76: testmode: add pre-cal support Signed-off-by: StanleyYP Wang --- @@ -12,13 +12,13 @@ Signed-off-by: StanleyYP Wang mt7915/mt7915.h | 1 + mt7915/testmode.c | 425 +++++++++++++++++++++++++++++++++++++++++++++- mt7915/testmode.h | 36 ++++ - testmode.c | 15 +- + testmode.c | 15 ++ testmode.h | 17 ++ tools/fields.c | 8 + - 10 files changed, 506 insertions(+), 7 deletions(-) + 10 files changed, 507 insertions(+), 6 deletions(-) diff --git a/eeprom.c b/eeprom.c -index a267397..3625b16 100644 +index a2673978..3625b169 100644 --- a/eeprom.c +++ b/eeprom.c @@ -94,8 +94,10 @@ int mt76_get_of_data_from_mtd(struct mt76_dev *dev, void *eep, int offset, int l @@ -35,7 +35,7 @@ index a267397..3625b16 100644 out_put_node: diff --git a/mt76.h b/mt76.h -index 3fe18cd..22d76bb 100644 +index 62205051..d8c2a515 100644 --- a/mt76.h +++ b/mt76.h @@ -708,6 +708,7 @@ struct mt76_testmode_ops { @@ -47,10 +47,10 @@ index 3fe18cd..22d76bb 100644 struct mt76_testmode_entry_data { diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 0972010..b75d340 100644 +index 152b4aaa..cf88b674 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1019,6 +1019,7 @@ enum { +@@ -1020,6 +1020,7 @@ enum { /* ext event table */ enum { @@ -59,7 +59,7 @@ index 0972010..b75d340 100644 MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13, MCU_EXT_EVENT_THERMAL_PROTECT = 0x22, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 233411c..ad58e3b 100644 +index b5177e30..d4291e24 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -482,6 +482,9 @@ mt7915_mcu_rx_ext_event(struct mt7915_dev *dev, struct sk_buff *skb) @@ -73,10 +73,10 @@ index 233411c..ad58e3b 100644 case MCU_EXT_EVENT_BSS_ACQ_PKT_CNT: mt7915_mcu_rx_bss_acq_pkt_cnt(dev, skb); diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 1846e2f..dd2e80b 100644 +index bc77a61a..ca385b66 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -654,6 +654,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); +@@ -671,6 +671,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_exit(struct mt7915_dev *dev); int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb); @@ -85,7 +85,7 @@ index 1846e2f..dd2e80b 100644 static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index 32dc85c..4b34430 100644 +index 32dc85cd..4b344303 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -5,6 +5,7 @@ @@ -560,7 +560,7 @@ index 32dc85c..4b34430 100644 + .dump_precal = mt7915_tm_dump_precal, }; diff --git a/mt7915/testmode.h b/mt7915/testmode.h -index eb0e043..7569826 100644 +index eb0e0432..75698261 100644 --- a/mt7915/testmode.h +++ b/mt7915/testmode.h @@ -81,6 +81,11 @@ struct tm_tx_cont { @@ -628,7 +628,7 @@ index eb0e043..7569826 100644 TAM_ARB_OP_MODE_NORMAL = 1, TAM_ARB_OP_MODE_TEST, diff --git a/testmode.c b/testmode.c -index 7587047..070b296 100644 +index 75870478..132267eb 100644 --- a/testmode.c +++ b/testmode.c @@ -771,6 +771,18 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, @@ -650,18 +650,18 @@ index 7587047..070b296 100644 if (tb[MT76_TM_ATTR_STATS]) { err = -EINVAL; -@@ -804,7 +816,8 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, - - if (dev->test_mtd.name && - (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) || -- nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset))) -+ nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset) || -+ nla_put_u8(msg, MT76_TM_ATTR_BAND_IDX, phy->band_idx))) +@@ -802,6 +814,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, + if (nla_put_u32(msg, MT76_TM_ATTR_STATE, td->state)) goto out; - if (nla_put_u32(msg, MT76_TM_ATTR_TX_COUNT, td->tx_count) || ++ if (nla_put_u8(msg, MT76_TM_ATTR_BAND_IDX, phy->band_idx)) ++ goto out; ++ + if (dev->test_mtd.name && + (nla_put_string(msg, MT76_TM_ATTR_MTD_PART, dev->test_mtd.name) || + nla_put_u32(msg, MT76_TM_ATTR_MTD_OFFSET, dev->test_mtd.offset))) diff --git a/testmode.h b/testmode.h -index 7a68625..e4c1b52 100644 +index 7a686250..e4c1b521 100644 --- a/testmode.h +++ b/testmode.h @@ -19,6 +19,7 @@ @@ -717,7 +717,7 @@ index 7a68625..e4c1b52 100644 /* keep last */ diff --git a/tools/fields.c b/tools/fields.c -index 406ba77..27801db 100644 +index 406ba77c..27801dbe 100644 --- a/tools/fields.c +++ b/tools/fields.c @@ -11,6 +11,14 @@ static const char * const testmode_state[] = { diff --git a/feeds/mediatek-sdk/mt76/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch b/feeds/mediatek-sdk/mt76/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch index c4d423eea..edbae402c 100644 --- a/feeds/mediatek-sdk/mt76/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1010-wifi-mt76-testmode-add-iBF-command-mode-support.patch @@ -1,7 +1,7 @@ -From be62cd03caedf8de9f3d6f2ef8883f85be51b9c7 Mon Sep 17 00:00:00 2001 +From a78a0de5858eba651ca9630dc8970c947b190b28 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Mon, 12 Sep 2022 18:16:54 +0800 -Subject: [PATCH 1010/1053] wifi: mt76: testmode: add iBF command mode support +Subject: [PATCH 1010/1052] wifi: mt76: testmode: add iBF command mode support Signed-off-by: StanleyYP Wang --- @@ -12,7 +12,7 @@ Signed-off-by: StanleyYP Wang 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index 4b34430..453319e 100644 +index 4b344303..453319e1 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -722,6 +722,7 @@ mt7915_tm_txbf_profile_update(struct mt7915_phy *phy, u16 *val, bool ebf) @@ -104,7 +104,7 @@ index 4b34430..453319e 100644 mt7915_tm_set_tx_len(phy, tx_time); diff --git a/testmode.c b/testmode.c -index 070b296..b1986ad 100644 +index 132267eb..06b10a36 100644 --- a/testmode.c +++ b/testmode.c @@ -535,6 +535,42 @@ out: @@ -163,7 +163,7 @@ index 070b296..b1986ad 100644 nla_for_each_nested(cur, tb[MT76_TM_ATTR_TXBF_PARAM], rem) { if (nla_len(cur) != 2 || diff --git a/testmode.h b/testmode.h -index e4c1b52..1d7aef8 100644 +index e4c1b521..1d7aef86 100644 --- a/testmode.h +++ b/testmode.h @@ -285,8 +285,10 @@ enum mt76_testmode_txbf_act { @@ -178,7 +178,7 @@ index e4c1b52..1d7aef8 100644 /* keep last */ diff --git a/tools/fields.c b/tools/fields.c -index 27801db..b0ee84d 100644 +index 27801dbe..b0ee84d2 100644 --- a/tools/fields.c +++ b/tools/fields.c @@ -32,6 +32,20 @@ static const char * const testmode_tx_mode[] = { diff --git a/feeds/mediatek-sdk/mt76/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch b/feeds/mediatek-sdk/mt76/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch index b42e14190..056c2b1d3 100644 --- a/feeds/mediatek-sdk/mt76/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1011-wifi-mt76-testmode-add-ZWDFS-test-mode-support.patch @@ -1,7 +1,7 @@ -From 460f28c1cba4632a4bd046d0a93d1569f69acea0 Mon Sep 17 00:00:00 2001 +From 12f1e58ae28f7e12f298d213a0cfe13b751082df Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 27 Oct 2022 17:42:07 +0800 -Subject: [PATCH] wifi: mt76: testmode: add ZWDFS test mode support +Subject: [PATCH 1011/1052] wifi: mt76: testmode: add ZWDFS test mode support Signed-off-by: StanleyYP Wang --- @@ -18,7 +18,7 @@ Signed-off-by: StanleyYP Wang 10 files changed, 508 insertions(+), 1 deletion(-) diff --git a/mt76.h b/mt76.h -index 20577af..53b0964 100644 +index d8c2a515..15106812 100644 --- a/mt76.h +++ b/mt76.h @@ -793,6 +793,15 @@ struct mt76_testmode_data { @@ -38,10 +38,10 @@ index 20577af..53b0964 100644 struct mt76_vif { diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 6511060..9ac1c46 100644 +index cf88b674..40fa9fc8 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1241,6 +1241,7 @@ enum { +@@ -1243,6 +1243,7 @@ enum { MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a, MCU_EXT_CMD_SET_RDD_TH = 0x9d, MCU_EXT_CMD_MURU_CTRL = 0x9f, @@ -49,7 +49,7 @@ index 6511060..9ac1c46 100644 MCU_EXT_CMD_RX_STAT = 0xa4, MCU_EXT_CMD_SET_SPR = 0xa8, MCU_EXT_CMD_GROUP_PRE_CAL_INFO = 0xab, -@@ -1252,6 +1253,7 @@ enum { +@@ -1254,6 +1255,7 @@ enum { MCU_EXT_CMD_SET_QOS_MAP = 0xb4, MCU_EXT_CMD_CERT_CFG = 0xb7, MCU_EXT_CMD_CSI_CTRL = 0xc2, @@ -58,7 +58,7 @@ index 6511060..9ac1c46 100644 enum { diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 5f3fec8..2025ef3 100644 +index d4291e24..500ecbbb 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -2759,6 +2759,7 @@ mt7915_mcu_background_chain_ctrl(struct mt7915_phy *phy, @@ -69,10 +69,11 @@ index 5f3fec8..2025ef3 100644 req.band_idx = phy->mt76->band_idx; req.scan_mode = 2; break; -@@ -4955,6 +4956,71 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable) +@@ -4954,3 +4955,68 @@ int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable) + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MEC_CTRL), &req, sizeof(req), true); } #endif - ++ +int mt7915_mcu_ipi_hist_ctrl(struct mt7915_phy *phy, void *data, u8 cmd, bool wait_resp) +{ + struct mt7915_dev *dev = phy->dev; @@ -137,12 +138,8 @@ index 5f3fec8..2025ef3 100644 + + return 0; +} -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index c791c7f..066246b 100644 +index c791c7fa..066246bb 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -698,6 +698,52 @@ enum CSI_CHAIN_TYPE { @@ -199,10 +196,10 @@ index c791c7f..066246b 100644 #define OFDMA_DL BIT(0) #define OFDMA_UL BIT(1) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index b716b57..ec33afd 100644 +index ca385b66..00f55443 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -293,6 +293,7 @@ struct mt7915_phy { +@@ -306,6 +306,7 @@ struct mt7915_phy { struct mt76_mib_stats mib; struct mt76_channel_state state_ts; @@ -210,7 +207,7 @@ index b716b57..ec33afd 100644 u8 stats_work_count; struct list_head stats_list; -@@ -768,6 +769,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, +@@ -786,6 +787,9 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, struct ieee80211_sta *sta); #endif @@ -221,7 +218,7 @@ index b716b57..ec33afd 100644 int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir); int mt7915_dbg_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3, bool wait_resp); diff --git a/mt7915/regs.h b/mt7915/regs.h -index 1236da9..7e9b76b 100644 +index 1236da91..7e9b76b0 100644 --- a/mt7915/regs.h +++ b/mt7915/regs.h @@ -1211,6 +1211,8 @@ enum offs_rev { @@ -234,7 +231,7 @@ index 1236da9..7e9b76b 100644 #define MT_WF_PHY_BASE 0x83080000 #define MT_WF_PHY(ofs) (MT_WF_PHY_BASE + (ofs)) diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index 453319e..caa3590 100644 +index 453319e1..caa35906 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -14,6 +14,12 @@ enum { @@ -561,7 +558,7 @@ index 453319e..caa3590 100644 static int diff --git a/testmode.c b/testmode.c -index b1986ad..b369826 100644 +index 06b10a36..d8fc5d6f 100644 --- a/testmode.c +++ b/testmode.c @@ -26,6 +26,13 @@ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = { @@ -614,7 +611,7 @@ index b1986ad..b369826 100644 goto out; if (tb[MT76_TM_ATTR_TX_LENGTH]) { -@@ -866,6 +886,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, +@@ -868,6 +888,9 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_MODE, td->tx_rate_mode) || nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_SGI, td->tx_rate_sgi) || nla_put_u8(msg, MT76_TM_ATTR_TX_RATE_STBC, td->tx_rate_stbc) || @@ -625,7 +622,7 @@ index b1986ad..b369826 100644 nla_put_u8(msg, MT76_TM_ATTR_TX_LTF, td->tx_ltf)) || (mt76_testmode_param_present(td, MT76_TM_ATTR_TX_ANTENNA) && diff --git a/testmode.h b/testmode.h -index 1d7aef8..b39cf51 100644 +index 1d7aef86..b39cf511 100644 --- a/testmode.h +++ b/testmode.h @@ -64,6 +64,20 @@ @@ -693,7 +690,7 @@ index 1d7aef8..b39cf51 100644 + #endif diff --git a/tools/fields.c b/tools/fields.c -index b0ee84d..e2cf4b9 100644 +index b0ee84d2..e2cf4b92 100644 --- a/tools/fields.c +++ b/tools/fields.c @@ -46,6 +46,14 @@ static const char * const testmode_txbf_act[] = { diff --git a/feeds/mediatek-sdk/mt76/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch b/feeds/mediatek-sdk/mt76/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch index 289bbe401..19efa83c9 100644 --- a/feeds/mediatek-sdk/mt76/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch +++ b/feeds/mediatek-sdk/mt76/patches/1012-wifi-mt76-testmode-add-iBF-eBF-cal-and-cert-commands.patch @@ -1,8 +1,8 @@ -From 2a34bd2105e5021dacaf30c90bb6816f107cabd4 Mon Sep 17 00:00:00 2001 +From 46dec6692579a5ccd030e2facf62e16a51712ad2 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 15 Dec 2022 19:45:18 +0800 -Subject: [PATCH] wifi: mt76: testmode: add iBF/eBF cal and cert commands with - golden +Subject: [PATCH 37/94] wifi: mt76: testmode: add iBF/eBF cal and cert commands + with golden Signed-off-by: StanleyYP Wang --- @@ -25,10 +25,10 @@ Signed-off-by: StanleyYP Wang 16 files changed, 859 insertions(+), 325 deletions(-) diff --git a/mt76.h b/mt76.h -index 53b0964..1455144 100644 +index 62bf468..a2640cf 100644 --- a/mt76.h +++ b/mt76.h -@@ -755,6 +755,7 @@ struct mt76_testmode_data { +@@ -762,6 +762,7 @@ struct mt76_testmode_data { struct list_head tm_entry_list; struct mt76_wcid *cur_entry; @@ -36,7 +36,7 @@ index 53b0964..1455144 100644 u8 entry_num; union { struct mt76_testmode_entry_data ed; -@@ -783,6 +784,9 @@ struct mt76_testmode_data { +@@ -790,6 +791,9 @@ struct mt76_testmode_data { u8 txbf_act; u16 txbf_param[8]; @@ -47,7 +47,7 @@ index 53b0964..1455144 100644 u32 tx_pending; u32 tx_queued; diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c -index 44cd646..15e61c9 100644 +index 2acd7ef..0ce7ecd 100644 --- a/mt76_connac_mcu.c +++ b/mt76_connac_mcu.c @@ -2688,6 +2688,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, @@ -68,7 +68,7 @@ index 44cd646..15e61c9 100644 memcpy(bss->bssid, phy->macaddr, ETH_ALEN); } diff --git a/mt7915/mac.c b/mt7915/mac.c -index 7d3397e..d94a0d5 100644 +index 7fce115..7bc2834 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -737,8 +737,10 @@ mt7915_mac_write_txwi_tm(struct mt7915_phy *phy, __le32 *txwi, @@ -84,7 +84,7 @@ index 7d3397e..d94a0d5 100644 txwi[6] |= cpu_to_le32(val); #endif diff --git a/mt7915/main.c b/mt7915/main.c -index e53754c..69477f1 100644 +index 73d176c..73e8ec1 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -205,46 +205,37 @@ static void mt7915_init_bitrate_mask(struct ieee80211_vif *vif) @@ -101,7 +101,7 @@ index e53754c..69477f1 100644 + struct mt7915_dev *dev = phy->dev; struct mt76_txq *mtxq; bool ext_phy = phy != &dev->phy; - int idx, ret = 0; + int idx, i, ret = 0; - mutex_lock(&dev->mt76.mutex); - @@ -146,7 +146,7 @@ index e53754c..69477f1 100644 dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx); phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); -@@ -280,7 +271,26 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, +@@ -286,7 +277,26 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, mt7915_mcu_add_sta(dev, vif, NULL, true); rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); @@ -175,7 +175,7 @@ index e53754c..69477f1 100644 return ret; diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 2025ef3..f5042ae 100644 +index 500ecbb..6f05a08 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -199,6 +199,7 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, @@ -448,7 +448,7 @@ index 066246b..de17c57 100644 MURU_SET_ARB_OP_MODE = 14, MURU_SET_PLATFORM_TYPE = 25, diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 222e2cf..ddf1b72 100644 +index 730cd33..ed15d71 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -133,6 +133,7 @@ static const u32 mt7915_offs[] = { @@ -468,10 +468,10 @@ index 222e2cf..ddf1b72 100644 [AGG_AALCR0] = 0x028, [AGG_AWSCR0] = 0x030, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index ec33afd..700efaf 100644 +index 1df3d9f..ea284ae 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -312,7 +312,6 @@ struct mt7915_phy { +@@ -329,7 +329,6 @@ struct mt7915_phy { u8 spe_idx; @@ -479,7 +479,7 @@ index ec33afd..700efaf 100644 bool bf_ever_en; } test; #endif -@@ -426,7 +425,7 @@ struct mt7915_dev { +@@ -447,7 +446,7 @@ struct mt7915_dev { void __iomem *dcm; void __iomem *sku; @@ -488,7 +488,7 @@ index ec33afd..700efaf 100644 struct { void *txbf_phase_cal; void *txbf_pfmu_data; -@@ -574,6 +573,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force); +@@ -595,6 +594,7 @@ int mt7915_dma_reset(struct mt7915_dev *dev, bool force); int mt7915_dma_start(struct mt7915_dev *dev, bool reset, bool wed_reset); int mt7915_txbf_init(struct mt7915_dev *dev); void mt7915_init_txpower(struct mt7915_phy *phy); @@ -496,14 +496,13 @@ index ec33afd..700efaf 100644 void mt7915_reset(struct mt7915_dev *dev); int mt7915_run(struct ieee80211_hw *hw); int mt7915_mcu_init(struct mt7915_dev *dev); -@@ -654,11 +654,13 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); +@@ -675,10 +675,12 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level); void mt7915_mcu_rx_event(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_exit(struct mt7915_dev *dev); -int mt7915_tm_txbf_status_read(struct mt7915_dev *dev, struct sk_buff *skb); -void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb); void mt7915_mcu_wmm_pbc_work(struct work_struct *work); - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif); +#ifdef CONFIG_NL80211_TESTMODE +void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb); @@ -512,7 +511,7 @@ index ec33afd..700efaf 100644 static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) { return is_mt7915(&dev->mt76) ? MT7915_WTBL_SIZE : MT7916_WTBL_SIZE; -@@ -792,4 +794,10 @@ enum { +@@ -814,4 +816,10 @@ enum { #endif @@ -524,7 +523,7 @@ index ec33afd..700efaf 100644 + #endif diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 84f8fae..9e490ad 100644 +index b94914d..adc4929 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -2888,6 +2888,36 @@ mt7915_txpower_level_set(void *data, u64 val) @@ -1851,7 +1850,7 @@ index 7569826..5aba13c 100644 #endif diff --git a/testmode.c b/testmode.c -index b369826..a3e6d4a 100644 +index d8fc5d6..56b9205 100644 --- a/testmode.c +++ b/testmode.c @@ -196,6 +196,7 @@ mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len, @@ -1919,5 +1918,5 @@ index e2cf4b9..027b8cd 100644 static const char * const testmode_offchan_bw[] = { -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1013-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch b/feeds/mediatek-sdk/mt76/patches/1013-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch index cea0e5be1..7879b8578 100644 --- a/feeds/mediatek-sdk/mt76/patches/1013-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch +++ b/feeds/mediatek-sdk/mt76/patches/1013-wifi-mt76-connac-airtime-fairness-feature-off-in-mac.patch @@ -1,7 +1,7 @@ -From b19594cf12b01dede83a984ca717e26be37bbfdd Mon Sep 17 00:00:00 2001 +From 9e7d1c03b7944cd7a0641c68c9515f400e662451 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Fri, 6 May 2022 15:58:42 +0800 -Subject: [PATCH 1013/1053] wifi: mt76: connac: airtime fairness feature off in +Subject: [PATCH 1013/1052] wifi: mt76: connac: airtime fairness feature off in mac80211 --- @@ -9,7 +9,7 @@ Subject: [PATCH 1013/1053] wifi: mt76: connac: airtime fairness feature off in 1 file changed, 1 deletion(-) diff --git a/mac80211.c b/mac80211.c -index 305cae7..f9dfdf8 100644 +index d6b70374..750a642a 100644 --- a/mac80211.c +++ b/mac80211.c @@ -451,7 +451,6 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw) diff --git a/feeds/mediatek-sdk/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch b/feeds/mediatek-sdk/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch index 7f75d0019..3357c0db9 100644 --- a/feeds/mediatek-sdk/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch +++ b/feeds/mediatek-sdk/mt76/patches/1014-wifi-mt76-mt7915-add-phy-capability-vendor-command.patch @@ -1,17 +1,17 @@ -From 34cb90df1cfbbe69bb96a4eabd249e190d821e03 Mon Sep 17 00:00:00 2001 +From ea8636284d9278b7053ecedb02045be768d90957 Mon Sep 17 00:00:00 2001 From: Yi-Chia Hsieh Date: Tue, 12 Jul 2022 10:04:35 -0700 -Subject: [PATCH 1014/1053] wifi: mt76: mt7915: add phy capability vendor +Subject: [PATCH 1014/1052] wifi: mt76: mt7915: add phy capability vendor command --- mt7915/mt7915.h | 1 + mt7915/vendor.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ - mt7915/vendor.h | 25 ++++++++++++++++++++++++ - 3 files changed, 78 insertions(+) + mt7915/vendor.h | 26 +++++++++++++++++++++++++ + 3 files changed, 79 insertions(+) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index b06e5ca..d21b843 100644 +index ef92b2ea..64cfa2e0 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -11,6 +11,7 @@ @@ -23,10 +23,10 @@ index b06e5ca..d21b843 100644 #define MT7916_WTBL_SIZE 544 #define MT7915_WTBL_RESERVED (mt7915_wtbl_size(dev) - 1) diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index a8b1fa8..757aecb 100644 +index cf09b513..9e8d2442 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -51,6 +51,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = { +@@ -52,6 +52,18 @@ rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = { [MTK_VENDOR_ATTR_RFEATURE_CTRL_TRIG_TXBF] = { .type = NLA_U8 }, }; @@ -45,7 +45,7 @@ index a8b1fa8..757aecb 100644 struct csi_null_tone { u8 start; u8 end; -@@ -995,6 +1007,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, +@@ -1131,6 +1143,35 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, return 0; } @@ -81,7 +81,7 @@ index a8b1fa8..757aecb 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1052,6 +1093,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1188,6 +1229,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .doit = mt7915_vendor_mu_ctrl, .policy = mu_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX, @@ -100,7 +100,7 @@ index a8b1fa8..757aecb 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index a4a9180..34dd7d0 100644 +index 9cb67551..e58884ce 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -10,6 +10,7 @@ enum mtk_nl80211_vendor_subcmds { @@ -111,10 +111,11 @@ index a4a9180..34dd7d0 100644 }; enum mtk_capi_control_changed { -@@ -152,4 +153,28 @@ enum mtk_vendor_attr_mnt_dump { +@@ -164,4 +165,29 @@ enum mtk_vendor_attr_mnt_dump { + MTK_VENDOR_ATTR_AMNT_DUMP_MAX = NUM_MTK_VENDOR_ATTRS_AMNT_DUMP - 1 }; - ++ +enum mtk_vendor_attr_phy_capa_ctrl { + MTK_VENDOR_ATTR_PHY_CAPA_CTRL_UNSPEC, + diff --git a/feeds/mediatek-sdk/mt76/patches/1015-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch b/feeds/mediatek-sdk/mt76/patches/1015-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch index 14f77a57f..a8230fbca 100644 --- a/feeds/mediatek-sdk/mt76/patches/1015-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch +++ b/feeds/mediatek-sdk/mt76/patches/1015-wifi-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl-enable.patch @@ -1,7 +1,7 @@ -From 7f9793b9c724014e9993091b47566cd9bf3cec06 Mon Sep 17 00:00:00 2001 +From 31ecfaed704ad082d532a32ae5abd045f5d2f339 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Fri, 24 Jun 2022 11:15:45 +0800 -Subject: [PATCH] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl +Subject: [PATCH 1015/1052] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl enable/threshold/compensation --- @@ -15,10 +15,10 @@ Subject: [PATCH] wifi: mt76: mt7915: add vendor subcmd EDCCA ctrl 7 files changed, 264 insertions(+), 1 deletion(-) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 9ac1c46..012f9be 100644 +index 40fa9fc8..a85179b8 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1252,6 +1252,7 @@ enum { +@@ -1254,6 +1254,7 @@ enum { MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3, MCU_EXT_CMD_SET_QOS_MAP = 0xb4, MCU_EXT_CMD_CERT_CFG = 0xb7, @@ -27,7 +27,7 @@ index 9ac1c46..012f9be 100644 MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5, }; diff --git a/mt7915/main.c b/mt7915/main.c -index 69477f1..d0ba4b7 100644 +index 4a541188..de2f9098 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -479,6 +479,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) @@ -41,13 +41,14 @@ index 69477f1..d0ba4b7 100644 ret = mt7915_set_channel(phy); if (ret) diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index f5042ae..20395e9 100644 +index 6f05a081..f83d969c 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c -@@ -5038,6 +5038,78 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w +@@ -5037,3 +5037,75 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w + return 0; } - ++ +int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation) +{ + static const u8 ch_band[] = { @@ -119,12 +120,8 @@ index f5042ae..20395e9 100644 + + return 0; +} -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index de17c57..1682c11 100644 +index de17c579..1682c117 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -1128,6 +1128,27 @@ enum { @@ -156,10 +153,10 @@ index de17c57..1682c11 100644 #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index d4a3467..8da1d1b 100644 +index 64cfa2e0..141c151e 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -771,7 +771,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); +@@ -789,7 +789,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, struct ieee80211_sta *sta); #endif @@ -170,10 +167,10 @@ index d4a3467..8da1d1b 100644 int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp); diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 757aecb..3a58684 100644 +index 9e8d2442..aaa0cf1d 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -63,6 +63,24 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = { +@@ -64,6 +64,24 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = { [MTK_VENDOR_ATTR_PHY_CAPA_DUMP_MAX_SUPPORTED_STA] = { .type = NLA_U16 }, }; @@ -198,7 +195,7 @@ index 757aecb..3a58684 100644 struct csi_null_tone { u8 start; u8 end; -@@ -1036,6 +1054,108 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, +@@ -1172,6 +1190,108 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, return len; } @@ -307,7 +304,7 @@ index 757aecb..3a58684 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1104,6 +1224,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1240,6 +1360,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_phy_capa_ctrl_dump, .policy = phy_capa_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_PHY_CAPA_CTRL_MAX, @@ -327,7 +324,7 @@ index 757aecb..3a58684 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 34dd7d0..284994a 100644 +index e58884ce..c8d30b52 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -3,6 +3,7 @@ diff --git a/feeds/mediatek-sdk/mt76/patches/1016-wifi-mt76-mt7915-implement-bin-file-mode.patch b/feeds/mediatek-sdk/mt76/patches/1016-wifi-mt76-mt7915-implement-bin-file-mode.patch index 792580c08..9800bd240 100644 --- a/feeds/mediatek-sdk/mt76/patches/1016-wifi-mt76-mt7915-implement-bin-file-mode.patch +++ b/feeds/mediatek-sdk/mt76/patches/1016-wifi-mt76-mt7915-implement-bin-file-mode.patch @@ -1,7 +1,7 @@ -From 9291fdb4f324728e5f4e233a08282f828cc04b80 Mon Sep 17 00:00:00 2001 +From 6aa933c1f0af48d3703f500dce4514b62d9d2121 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 7 Jul 2022 11:09:59 +0800 -Subject: [PATCH 1016/1053] wifi: mt76: mt7915: implement bin file mode +Subject: [PATCH 1016/1052] wifi: mt76: mt7915: implement bin file mode Signed-off-by: StanleyYP Wang Signed-off-by: Shayne Chen @@ -16,7 +16,7 @@ Signed-off-by: Shayne Chen 7 files changed, 144 insertions(+), 4 deletions(-) diff --git a/eeprom.c b/eeprom.c -index 3625b16..9d029c0 100644 +index 3625b169..9d029c04 100644 --- a/eeprom.c +++ b/eeprom.c @@ -161,6 +161,31 @@ static int mt76_get_of_eeprom(struct mt76_dev *dev, void *eep, int len) @@ -52,7 +52,7 @@ index 3625b16..9d029c0 100644 mt76_eeprom_override(struct mt76_phy *phy) { diff --git a/mt76.h b/mt76.h -index 8025e04..48e98a3 100644 +index 9597f564..253a564f 100644 --- a/mt76.h +++ b/mt76.h @@ -983,6 +983,9 @@ struct mt76_dev { @@ -74,7 +74,7 @@ index 8025e04..48e98a3 100644 struct mt76_queue * mt76_init_queue(struct mt76_dev *dev, int qid, int idx, int n_desc, diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c -index f4876fe..c8b1c18 100644 +index f4876fe9..c8b1c18e 100644 --- a/mt7915/eeprom.c +++ b/mt7915/eeprom.c @@ -5,6 +5,30 @@ @@ -196,7 +196,7 @@ index f4876fe..c8b1c18 100644 if (ret) return ret; diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h -index 509fb43..99101f9 100644 +index 509fb43d..99101f91 100644 --- a/mt7915/eeprom.h +++ b/mt7915/eeprom.h @@ -109,6 +109,13 @@ enum mt7915_sku_rate_group { @@ -214,10 +214,10 @@ index 509fb43..99101f9 100644 mt7915_get_channel_group_5g(int channel, bool is_7976) { diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 000751b..a06a46e 100644 +index 141c151e..2fb8e2fb 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -397,6 +397,8 @@ struct mt7915_dev { +@@ -414,6 +414,8 @@ struct mt7915_dev { bool dbdc_support; bool flash_mode; @@ -226,7 +226,7 @@ index 000751b..a06a46e 100644 bool muru_debug; bool ibf; -@@ -783,6 +785,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info); +@@ -802,6 +804,7 @@ void mt7915_dump_tmac_info(u8 *tmac_info); int mt7915_mcu_set_txpower_level(struct mt7915_phy *phy, u8 drop_level); void mt7915_packet_log_to_host(struct mt7915_dev *dev, const void *data, int len, int type, int des_len); int mt7915_mcu_set_amsdu_algo(struct mt7915_dev *dev, u16 wcid, u8 enable); @@ -235,7 +235,7 @@ index 000751b..a06a46e 100644 #define PKT_BIN_DEBUG_MAGIC 0xc8763123 enum { diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 30c5f68..02e0db3 100644 +index 02fe61a3..76f4849e 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3,6 +3,7 @@ @@ -304,7 +304,7 @@ index 30c5f68..02e0db3 100644 } #endif diff --git a/testmode.h b/testmode.h -index 20fab3e..91d1e86 100644 +index 20fab3ec..91d1e867 100644 --- a/testmode.h +++ b/testmode.h @@ -17,7 +17,7 @@ diff --git a/feeds/mediatek-sdk/mt76/patches/1017-wifi-mt76-mt7915-Add-mu-dump-support.patch b/feeds/mediatek-sdk/mt76/patches/1017-wifi-mt76-mt7915-Add-mu-dump-support.patch index a8a9084f4..8e1378e94 100644 --- a/feeds/mediatek-sdk/mt76/patches/1017-wifi-mt76-mt7915-Add-mu-dump-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1017-wifi-mt76-mt7915-Add-mu-dump-support.patch @@ -1,7 +1,7 @@ -From 7a381293087e8d94349e5488936e53f884730787 Mon Sep 17 00:00:00 2001 +From 0623b3b87fe33c6ad8037aa01cf63b2a1ab2274f Mon Sep 17 00:00:00 2001 From: TomLiu Date: Thu, 11 Aug 2022 18:09:45 -0700 -Subject: [PATCH 1017/1053] wifi: mt76: mt7915: Add mu dump support +Subject: [PATCH 1017/1052] wifi: mt76: mt7915: Add mu dump support --- mt7915/vendor.c | 24 ++++++++++++++++++++++++ @@ -9,10 +9,10 @@ Subject: [PATCH 1017/1053] wifi: mt76: mt7915: Add mu dump support 2 files changed, 25 insertions(+) diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 3a58684..ac6f637 100644 +index aaa0cf1d..eb0b380d 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -38,6 +38,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { +@@ -39,6 +39,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { static const struct nla_policy mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 }, @@ -20,7 +20,7 @@ index 3a58684..ac6f637 100644 }; static const struct nla_policy -@@ -1025,6 +1026,28 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, +@@ -1161,6 +1162,28 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, return 0; } @@ -49,7 +49,7 @@ index 3a58684..ac6f637 100644 static int mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, struct sk_buff *skb, const void *data, int data_len, -@@ -1211,6 +1234,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1347,6 +1370,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .flags = WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = mt7915_vendor_mu_ctrl, @@ -58,7 +58,7 @@ index 3a58684..ac6f637 100644 .maxattr = MTK_VENDOR_ATTR_MU_CTRL_MAX, }, diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 284994a..8c2a996 100644 +index c8d30b52..c61ba260 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -73,6 +73,7 @@ enum mtk_vendor_attr_mu_ctrl { diff --git a/feeds/mediatek-sdk/mt76/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch b/feeds/mediatek-sdk/mt76/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch index 6718ab8fb..90266c6df 100644 --- a/feeds/mediatek-sdk/mt76/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch +++ b/feeds/mediatek-sdk/mt76/patches/1018-wifi-mt76-mt7915-add-vendor-subcmd-three-wire-PTA-ct.patch @@ -1,7 +1,8 @@ -From 35c3c602288b8c1a11b9c1ca4e1b0182d451d15e Mon Sep 17 00:00:00 2001 +From a2610e02282fb1825cdc2d76ebff9e979a6a977c Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Fri, 28 Oct 2022 10:15:56 +0800 -Subject: [PATCH] wifi: mt76: mt7915: add vendor subcmd three wire (PTA) ctrl +Subject: [PATCH 1018/1052] wifi: mt76: mt7915: add vendor subcmd three wire + (PTA) ctrl Signed-off-by: StanleyYP Wang --- @@ -14,10 +15,10 @@ Signed-off-by: StanleyYP Wang 6 files changed, 111 insertions(+), 29 deletions(-) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 012f9be..7e12c05 100644 +index a85179b8..e7eb6a93 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1251,7 +1251,7 @@ enum { +@@ -1253,7 +1253,7 @@ enum { MCU_EXT_CMD_SMESH_CTRL = 0xae, MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3, MCU_EXT_CMD_SET_QOS_MAP = 0xb4, @@ -27,7 +28,7 @@ index 012f9be..7e12c05 100644 MCU_EXT_CMD_CSI_CTRL = 0xc2, MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 20395e9..8f5fcbb 100644 +index f83d969c..3e4239f6 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4736,37 +4736,33 @@ void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable) @@ -92,7 +93,7 @@ index 20395e9..8f5fcbb 100644 void mt7915_mcu_set_bypass_smthint(struct mt7915_phy *phy, u8 val) diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 1682c11..1b0bd06 100644 +index 1682c117..1b0bd06b 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -916,6 +916,35 @@ struct mt7915_mcu_rdd_ipi_scan { @@ -132,10 +133,10 @@ index 1682c11..1b0bd06 100644 #define OFDMA_DL BIT(0) #define OFDMA_UL BIT(1) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 27b007b..f9ca9d5 100644 +index 2fb8e2fb..6027e7f7 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -765,6 +765,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction); +@@ -781,6 +781,7 @@ void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction); void mt7915_mcu_set_dynalgo(struct mt7915_phy *phy, u8 enable); int mt7915_mcu_set_mu_edca(struct mt7915_phy *phy, u8 val); void mt7915_mcu_set_cert(struct mt7915_phy *phy, u8 type); @@ -144,10 +145,10 @@ index 27b007b..f9ca9d5 100644 void mt7915_vendor_register(struct mt7915_phy *phy); int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index ac6f637..eeac18d 100644 +index eb0b380d..54b89030 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -41,6 +41,11 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { +@@ -42,6 +42,11 @@ mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 }, }; @@ -159,7 +160,7 @@ index ac6f637..eeac18d 100644 static const struct nla_policy rfeature_ctrl_policy[NUM_MTK_VENDOR_ATTRS_RFEATURE_CTRL] = { [MTK_VENDOR_ATTR_RFEATURE_CTRL_HE_GI] = {.type = NLA_U8 }, -@@ -992,7 +997,7 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, +@@ -1128,7 +1133,7 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, mt7915_set_wireless_vif, &val32); } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]) { val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]); @@ -168,7 +169,7 @@ index ac6f637..eeac18d 100644 mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */ } -@@ -1136,6 +1141,7 @@ static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy, +@@ -1272,6 +1277,7 @@ static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy, return 0; } @@ -176,7 +177,7 @@ index ac6f637..eeac18d 100644 static int mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, struct sk_buff *skb, const void *data, int data_len, -@@ -1179,6 +1185,31 @@ mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, +@@ -1315,6 +1321,31 @@ mt7915_vendor_edcca_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, return len; } @@ -208,7 +209,7 @@ index ac6f637..eeac18d 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1260,6 +1291,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1396,6 +1427,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_edcca_ctrl_dump, .policy = edcca_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX, @@ -227,7 +228,7 @@ index ac6f637..eeac18d 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 8c2a996..e61a6aa 100644 +index c61ba260..ddde0cc0 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -13,6 +13,7 @@ enum mtk_nl80211_vendor_subcmds { diff --git a/feeds/mediatek-sdk/mt76/patches/1019-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch b/feeds/mediatek-sdk/mt76/patches/1019-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch index e0e3ce706..cfd1574fe 100644 --- a/feeds/mediatek-sdk/mt76/patches/1019-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch +++ b/feeds/mediatek-sdk/mt76/patches/1019-wifi-mt76-mt7915-add-ibf-control-vendor-cmd.patch @@ -1,7 +1,7 @@ -From 090c1e87976b841379871abfa75879dc115e4224 Mon Sep 17 00:00:00 2001 +From 95a5898db592cf183d3275e67a511f3ad5c2f541 Mon Sep 17 00:00:00 2001 From: mtk27835 Date: Wed, 7 Sep 2022 14:01:29 -0700 -Subject: [PATCH 1019/1053] wifi: mt76: mt7915: add ibf control vendor cmd +Subject: [PATCH 1019/1052] wifi: mt76: mt7915: add ibf control vendor cmd Signed-off-by: mtk27835 --- @@ -10,10 +10,10 @@ Signed-off-by: mtk27835 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index eeac18d..a21cbce 100644 +index 54b89030..b4facaaa 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -87,6 +87,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = { +@@ -88,6 +88,11 @@ edcca_dump_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_DUMP] = { [MTK_VENDOR_ATTR_EDCCA_DUMP_SEC80_VAL] = { .type = NLA_U8 }, }; @@ -25,7 +25,7 @@ index eeac18d..a21cbce 100644 struct csi_null_tone { u8 start; u8 end; -@@ -1209,6 +1214,54 @@ static int mt7915_vendor_3wire_ctrl(struct wiphy *wiphy, +@@ -1345,6 +1350,54 @@ static int mt7915_vendor_3wire_ctrl(struct wiphy *wiphy, return mt7915_mcu_set_cfg(phy, CFGINFO_3WIRE_EN_CFG, three_wire_mode); } @@ -80,7 +80,7 @@ index eeac18d..a21cbce 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { -@@ -1302,6 +1355,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1438,6 +1491,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .doit = mt7915_vendor_3wire_ctrl, .policy = three_wire_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_3WIRE_CTRL_MAX, @@ -100,7 +100,7 @@ index eeac18d..a21cbce 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index e61a6aa..876edf3 100644 +index ddde0cc0..24f35c8e 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -13,7 +13,8 @@ enum mtk_nl80211_vendor_subcmds { @@ -113,7 +113,7 @@ index e61a6aa..876edf3 100644 }; -@@ -225,4 +226,26 @@ enum mtk_vendor_attr_phy_capa_dump { +@@ -238,4 +239,26 @@ enum mtk_vendor_attr_phy_capa_dump { NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP - 1 }; diff --git a/feeds/mediatek-sdk/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch b/feeds/mediatek-sdk/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch index dd8f1dd9f..a16e3865e 100644 --- a/feeds/mediatek-sdk/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1020-wifi-mt76-mt7915-add-cal-free-data-merge-support.patch @@ -1,7 +1,7 @@ -From 0d530532bcd6795ff333eb7dafee44872c35c64b Mon Sep 17 00:00:00 2001 +From 1c8aa13277994e9d4bedcc2399bdcbd73d3612ef Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 30 Mar 2023 15:12:37 +0800 -Subject: [PATCH 1020/1053] wifi: mt76: mt7915: add cal free data merge support +Subject: [PATCH 1020/1052] wifi: mt76: mt7915: add cal free data merge support 1. add basic cal free data support 2. add E3 low yield rate workaround for panther E3 with 7976 adie @@ -19,12 +19,12 @@ Signed-off-by: StanleyYP Wang 5 files changed, 250 insertions(+), 6 deletions(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 2661386..5c08910 100644 +index 909df246..c3692969 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c -@@ -1241,6 +1241,46 @@ mt7915_rf_regval_set(void *data, u64 val) - DEFINE_DEBUGFS_ATTRIBUTE(fops_rf_regval, mt7915_rf_regval_get, - mt7915_rf_regval_set, "0x%08llx\n"); +@@ -1286,6 +1286,46 @@ static const struct file_operations mt7915_csi_ops = { + }; + #endif +static ssize_t +mt7915_efuse_get(struct file *file, char __user *user_buf, @@ -69,16 +69,16 @@ index 2661386..5c08910 100644 int mt7915_init_debugfs(struct mt7915_phy *phy) { struct mt7915_dev *dev = phy->dev; -@@ -1283,6 +1323,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) +@@ -1328,6 +1368,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir, mt7915_rdd_monitor); } + debugfs_create_file("otp", 0400, dir, dev, &mt7915_efuse_ops); - - if (!ext_phy) - dev->debugfs_dir = dir; + #ifdef CONFIG_MTK_VENDOR + debugfs_create_file("csi_stats", 0400, dir, phy, &mt7915_csi_ops); + #endif diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c -index c8b1c18..6133c20 100644 +index c8b1c18e..6133c200 100644 --- a/mt7915/eeprom.c +++ b/mt7915/eeprom.c @@ -48,8 +48,13 @@ static int mt7915_eeprom_load_precal(struct mt7915_dev *dev) @@ -309,7 +309,7 @@ index c8b1c18..6133c20 100644 memcpy(dev->mphy.macaddr, dev->mt76.eeprom.data + MT_EE_MAC_ADDR, ETH_ALEN); diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h -index 99101f9..70fca0b 100644 +index 99101f91..70fca0b3 100644 --- a/mt7915/eeprom.h +++ b/mt7915/eeprom.h @@ -68,6 +68,8 @@ enum mt7915_eeprom_field { @@ -322,7 +322,7 @@ index 99101f9..70fca0b 100644 MT7976_ONE_ADIE_DBDC = 0x7, MT7975_ONE_ADIE = 0x8, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 072185f..1262206 100644 +index 3e4239f6..85112791 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -2968,6 +2968,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf) @@ -353,10 +353,10 @@ index 072185f..1262206 100644 dev_kfree_skb(skb); diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 00d2b35..1e5cd94 100644 +index 6027e7f7..7d068e1e 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -562,6 +562,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id); +@@ -579,6 +579,7 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id); int mt7915_register_device(struct mt7915_dev *dev); void mt7915_unregister_device(struct mt7915_dev *dev); diff --git a/feeds/mediatek-sdk/mt76/patches/1021-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch b/feeds/mediatek-sdk/mt76/patches/1021-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch index 59e269015..610fecd3b 100644 --- a/feeds/mediatek-sdk/mt76/patches/1021-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch +++ b/feeds/mediatek-sdk/mt76/patches/1021-wifi-mt76-mt7915-support-on-off-SW-ACI-through-debug.patch @@ -1,7 +1,7 @@ -From 43d77d4dd7c55898fea4df333be72e77b5571eab Mon Sep 17 00:00:00 2001 +From cf95b91353888672b8fcf839592760de4d5f93ac Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Fri, 14 Oct 2022 11:15:13 +0800 -Subject: [PATCH 1021/1053] wifi: mt76: mt7915: support on off SW ACI through +Subject: [PATCH 1021/1052] wifi: mt76: mt7915: support on off SW ACI through debugfs Signed-off-by: Evelyn Tsai @@ -11,11 +11,11 @@ Signed-off-by: Evelyn Tsai 2 files changed, 22 insertions(+) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 109462a..c6a43dd 100644 +index e7eb6a93..49c3f1aa 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1252,6 +1252,7 @@ enum { - MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3, +@@ -1255,6 +1255,7 @@ enum { + MCU_EXT_CMD_SET_QOS_MAP = 0xb4, MCU_EXT_CMD_SET_CFG = 0xb7, MCU_EXT_CMD_EDCCA = 0xba, + MCU_EXT_CMD_SWLNA_ACI_CTRL = 0xc0, @@ -23,7 +23,7 @@ index 109462a..c6a43dd 100644 MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5, }; diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 02e0db3..a433e67 100644 +index 76f4849e..3e84d753 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3770,6 +3770,25 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/1022-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch b/feeds/mediatek-sdk/mt76/patches/1022-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch index 9030b991a..100d631bf 100644 --- a/feeds/mediatek-sdk/mt76/patches/1022-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1022-wifi-mt76-mt7915-add-bf-backoff-limit-table-support.patch @@ -1,7 +1,8 @@ -From ff7ce1171852dedcaec49ea0de398dfea04aaced Mon Sep 17 00:00:00 2001 +From 94af1c45316f8510f60afd0348918345757f1c20 Mon Sep 17 00:00:00 2001 From: Shayne Chen Date: Mon, 5 Dec 2022 18:21:51 +0800 -Subject: [PATCH] wifi: mt76: mt7915: add bf backoff limit table support +Subject: [PATCH 1022/1052] wifi: mt76: mt7915: add bf backoff limit table + support Signed-off-by: Shayne Chen --- @@ -17,7 +18,7 @@ Signed-off-by: Shayne Chen 9 files changed, 275 insertions(+), 54 deletions(-) diff --git a/debugfs.c b/debugfs.c -index 1c8328d..a626f7c 100644 +index 1c8328d5..a626f7cf 100644 --- a/debugfs.c +++ b/debugfs.c @@ -95,9 +95,9 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str, @@ -33,7 +34,7 @@ index 1c8328d..a626f7c 100644 } EXPORT_SYMBOL_GPL(mt76_seq_puts_array); diff --git a/eeprom.c b/eeprom.c -index 9d029c0..aa33e7b 100644 +index 9d029c04..aa33e7b5 100644 --- a/eeprom.c +++ b/eeprom.c @@ -336,9 +336,10 @@ mt76_apply_array_limit(s8 *pwr, size_t pwr_len, const __be32 *data, @@ -114,7 +115,7 @@ index 9d029c0..aa33e7b 100644 return max_power; } diff --git a/mt76.h b/mt76.h -index 48e98a3..5c26715 100644 +index 253a564f..580320fd 100644 --- a/mt76.h +++ b/mt76.h @@ -1089,6 +1089,14 @@ struct mt76_power_limits { @@ -133,7 +134,7 @@ index 48e98a3..5c26715 100644 struct mt76_ethtool_worker_info { diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 5c08910..fa1d2ac 100644 +index c3692969..3830a735 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -1020,7 +1020,7 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf, @@ -233,7 +234,7 @@ index 5c08910..fa1d2ac 100644 static int mt7915_twt_stats(struct seq_file *s, void *data) { -@@ -1310,7 +1373,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) +@@ -1355,7 +1418,9 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) debugfs_create_file("implicit_txbf", 0600, dir, dev, &fops_implicit_txbf); debugfs_create_file("txpower_sku", 0400, dir, phy, @@ -245,10 +246,10 @@ index 5c08910..fa1d2ac 100644 mt7915_twt_stats); debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); diff --git a/mt7915/init.c b/mt7915/init.c -index 439403f..b32e213 100644 +index 0c58ab7b..a9cb496b 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -284,6 +284,8 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, +@@ -285,6 +285,8 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band); struct mt76_power_limits limits; @@ -257,7 +258,7 @@ index 439403f..b32e213 100644 for (i = 0; i < sband->n_channels; i++) { struct ieee80211_channel *chan = &sband->channels[i]; u32 target_power = 0; -@@ -300,6 +302,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, +@@ -301,6 +303,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, target_power = mt76_get_rate_power_limits(phy->mt76, chan, &limits, target_power); @@ -270,7 +271,7 @@ index 439403f..b32e213 100644 target_power = DIV_ROUND_UP(target_power, 2); chan->max_power = min_t(int, chan->max_reg_power, diff --git a/mt7915/main.c b/mt7915/main.c -index 9fafa16..da7a87b 100644 +index de2f9098..4a5a0155 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -73,11 +73,7 @@ int mt7915_run(struct ieee80211_hw *hw) @@ -287,7 +288,7 @@ index 9fafa16..da7a87b 100644 goto out; diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 1262206..eb7638b 100644 +index 85112791..1b5ef875 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -3422,7 +3422,8 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy, @@ -535,7 +536,7 @@ index 1262206..eb7638b 100644 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req, diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 1b0bd06..94eff26 100644 +index 1b0bd06b..94eff268 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -517,12 +517,18 @@ enum { @@ -558,7 +559,7 @@ index 1b0bd06..94eff26 100644 SPR_ENABLE = 0x1, SPR_ENABLE_SD = 0x3, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 1e5cd94..826682b 100644 +index 7d068e1e..437cfb63 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -72,6 +72,7 @@ @@ -569,7 +570,7 @@ index 1e5cd94..826682b 100644 #define MT7915_MAX_TWT_AGRT 16 #define MT7915_MAX_STA_TWT_AGRT 8 -@@ -300,6 +301,9 @@ struct mt7915_phy { +@@ -313,6 +314,9 @@ struct mt7915_phy { struct list_head stats_list; spinlock_t stats_lock; @@ -579,7 +580,7 @@ index 1e5cd94..826682b 100644 #ifdef CONFIG_NL80211_TESTMODE struct { u32 *reg_backup; -@@ -626,9 +630,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, +@@ -643,9 +647,10 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, u8 en); int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); diff --git a/feeds/mediatek-sdk/mt76/patches/1023-wifi-mt76-mt7915-amsdu-set-and-get-control.patch b/feeds/mediatek-sdk/mt76/patches/1023-wifi-mt76-mt7915-amsdu-set-and-get-control.patch index 3bad2596a..72fd7b939 100644 --- a/feeds/mediatek-sdk/mt76/patches/1023-wifi-mt76-mt7915-amsdu-set-and-get-control.patch +++ b/feeds/mediatek-sdk/mt76/patches/1023-wifi-mt76-mt7915-amsdu-set-and-get-control.patch @@ -1,7 +1,7 @@ -From 568ebf749e43bade66a39a223a53918db8d71edf Mon Sep 17 00:00:00 2001 +From 71155a316facf65574dc5a03cc6c70a824c3d220 Mon Sep 17 00:00:00 2001 From: TomLiu Date: Wed, 14 Dec 2022 00:44:07 -0800 -Subject: [PATCH 1023/1053] wifi: mt76: mt7915: amsdu set and get control +Subject: [PATCH 1023/1052] wifi: mt76: mt7915: amsdu set and get control --- mt7915/mac.c | 7 +++++++ @@ -11,10 +11,10 @@ Subject: [PATCH 1023/1053] wifi: mt76: mt7915: amsdu set and get control 4 files changed, 50 insertions(+) diff --git a/mt7915/mac.c b/mt7915/mac.c -index d94a0d5..1e39ad2 100644 +index dc75ff1f..e14b3fdd 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -2035,6 +2035,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy) +@@ -1994,6 +1994,13 @@ static void mt7915_mac_sta_stats_work(struct mt7915_phy *phy) spin_unlock_bh(&phy->stats_lock); } @@ -29,10 +29,10 @@ index d94a0d5..1e39ad2 100644 void mt7915_capi_sta_rc_work(void *data, struct ieee80211_sta *sta) { diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 826682b..fe7c211 100644 +index 437cfb63..82d374eb 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -758,6 +758,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, +@@ -775,6 +775,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, bool pci, int *irq); #ifdef CONFIG_MTK_VENDOR @@ -41,10 +41,10 @@ index 826682b..fe7c211 100644 void mt7915_set_wireless_vif(void *data, u8 *mac, struct ieee80211_vif *vif); void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev, diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index a21cbce..e25a0ce 100644 +index b4facaaa..4848e0a1 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -31,10 +31,16 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { +@@ -32,10 +32,16 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { [MTK_VENDOR_ATTR_WIRELESS_CTRL_NUSERS_OFDMA] = {.type = NLA_U8 }, [MTK_VENDOR_ATTR_WIRELESS_CTRL_MIMO] = {.type = NLA_U8 }, [MTK_VENDOR_ATTR_WIRELESS_CTRL_BA_BUFFER_SIZE] = {.type = NLA_U16 }, @@ -61,7 +61,7 @@ index a21cbce..e25a0ce 100644 static const struct nla_policy mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 }, -@@ -1004,11 +1010,34 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, +@@ -1140,11 +1146,34 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT]); mt7915_mcu_set_cfg(phy, CFGINFO_CERT_CFG, val8); /* Cert Enable for OMI */ mt7915_mcu_set_bypass_smthint(phy, val8); /* Cert bypass smooth interpolation */ @@ -96,7 +96,7 @@ index a21cbce..e25a0ce 100644 static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, -@@ -1307,6 +1336,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1443,6 +1472,7 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .flags = WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING, .doit = mt7915_vendor_wireless_ctrl, @@ -105,7 +105,7 @@ index a21cbce..e25a0ce 100644 .maxattr = MTK_VENDOR_ATTR_WIRELESS_CTRL_MAX, }, diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 876edf3..7c4e914 100644 +index 24f35c8e..8a13b3a3 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -75,6 +75,7 @@ enum mtk_vendor_attr_wireless_ctrl { diff --git a/feeds/mediatek-sdk/mt76/patches/1024-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch b/feeds/mediatek-sdk/mt76/patches/1024-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch index 94d7b0e8b..153f1e372 100644 --- a/feeds/mediatek-sdk/mt76/patches/1024-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch +++ b/feeds/mediatek-sdk/mt76/patches/1024-wifi-mt76-mt7915-Add-vendor-command-attribute-for-RT.patch @@ -1,7 +1,7 @@ -From b6063c3c2566911919194c88cb9b68e68596d994 Mon Sep 17 00:00:00 2001 +From fbbc0bb4591648f645ed1b0b43f77e9922ecdfdd Mon Sep 17 00:00:00 2001 From: "himanshu.goyal" Date: Tue, 24 Jan 2023 14:32:08 +0800 -Subject: [PATCH 1024/1053] wifi: mt76: mt7915: Add vendor command attribute +Subject: [PATCH 1024/1052] wifi: mt76: mt7915: Add vendor command attribute for RTS BW signaling. Signed-off-by: himanshu.goyal @@ -13,7 +13,7 @@ Signed-off-by: himanshu.goyal 4 files changed, 20 insertions(+) diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index eb7638b..8e9b801 100644 +index 1b5ef875..ca18acfb 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4863,6 +4863,12 @@ int mt7915_mcu_set_cfg(struct mt7915_phy *phy, u8 cfg_info, u8 type) @@ -30,7 +30,7 @@ index eb7638b..8e9b801 100644 tlv_len = sizeof(struct three_wire_cfg); req.three_wire.tag = cpu_to_le16(cfg_info); diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 94eff26..6ebcce0 100644 +index 94eff268..6ebcce0d 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -936,6 +936,13 @@ struct three_wire_cfg { @@ -62,10 +62,10 @@ index 94eff26..6ebcce0 100644 }; diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index e25a0ce..8370216 100644 +index 4848e0a1..35891d49 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -34,6 +34,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { +@@ -35,6 +35,7 @@ wireless_ctrl_policy[NUM_MTK_VENDOR_ATTRS_WIRELESS_CTRL] = { [MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU] = {.type = NLA_U8 }, [MTK_VENDOR_ATTR_WIRELESS_CTRL_MU_EDCA] = {.type = NLA_U8 }, [MTK_VENDOR_ATTR_WIRELESS_CTRL_CERT] = {.type = NLA_U8 }, @@ -73,7 +73,7 @@ index e25a0ce..8370216 100644 }; static const struct nla_policy -@@ -1013,6 +1014,9 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, +@@ -1149,6 +1150,9 @@ static int mt7915_vendor_wireless_ctrl(struct wiphy *wiphy, } else if (tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]) { val8 = nla_get_u8(tb[MTK_VENDOR_ATTR_WIRELESS_CTRL_AMSDU]); mt7915_set_wireless_amsdu(hw, val8); @@ -84,7 +84,7 @@ index e25a0ce..8370216 100644 return 0; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 7c4e914..3672420 100644 +index 8a13b3a3..f91ad695 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -77,6 +77,7 @@ enum mtk_vendor_attr_wireless_ctrl { diff --git a/feeds/mediatek-sdk/mt76/patches/1025-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch b/feeds/mediatek-sdk/mt76/patches/1025-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch index df92c1abe..dc858704c 100644 --- a/feeds/mediatek-sdk/mt76/patches/1025-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch +++ b/feeds/mediatek-sdk/mt76/patches/1025-wifi-mt76-mt7915-add-vendor-cmd-to-get-available-col.patch @@ -1,7 +1,7 @@ -From 9981c906450cc4758d975b98f89ff62a64529be6 Mon Sep 17 00:00:00 2001 +From a48f497ea998ba30f4ee8ab7e5c41e0eb7738119 Mon Sep 17 00:00:00 2001 From: Yi-Chia Hsieh Date: Thu, 26 Jan 2023 08:50:47 +0800 -Subject: [PATCH 1025/1053] wifi: mt76: mt7915: add vendor cmd to get available +Subject: [PATCH 1025/1052] wifi: mt76: mt7915: add vendor cmd to get available color bitmap Add a vendor cmd to notify user space available color bitmap. @@ -14,10 +14,10 @@ Signed-off-by: Yi-Chia Hsieh 2 files changed, 48 insertions(+) diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 8370216..9a26f7f 100644 +index 35891d49..df08704b 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -99,6 +99,11 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = { +@@ -100,6 +100,11 @@ ibf_ctrl_policy[NUM_MTK_VENDOR_ATTRS_IBF_CTRL] = { [MTK_VENDOR_ATTR_IBF_CTRL_ENABLE] = { .type = NLA_U8 }, }; @@ -29,7 +29,7 @@ index 8370216..9a26f7f 100644 struct csi_null_tone { u8 start; u8 end; -@@ -1295,6 +1300,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, +@@ -1431,6 +1436,27 @@ mt7915_vendor_ibf_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev, return 1; } @@ -57,7 +57,7 @@ index 8370216..9a26f7f 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { -@@ -1401,6 +1427,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1537,6 +1563,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_ibf_ctrl_dump, .policy = ibf_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_IBF_CTRL_MAX, @@ -76,7 +76,7 @@ index 8370216..9a26f7f 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 3672420..bd1c617 100644 +index f91ad695..5b8d99bf 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -15,6 +15,7 @@ enum mtk_nl80211_vendor_subcmds { @@ -87,7 +87,7 @@ index 3672420..bd1c617 100644 }; -@@ -261,4 +262,14 @@ enum mtk_vendor_attr_ibf_dump { +@@ -274,4 +275,14 @@ enum mtk_vendor_attr_ibf_dump { NUM_MTK_VENDOR_ATTRS_IBF_DUMP - 1 }; diff --git a/feeds/mediatek-sdk/mt76/patches/1026-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch b/feeds/mediatek-sdk/mt76/patches/1026-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch index a6b71d541..fc382a9e7 100644 --- a/feeds/mediatek-sdk/mt76/patches/1026-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch +++ b/feeds/mediatek-sdk/mt76/patches/1026-wifi-mt76-mt7915-disable-SW-ACI-by-default.patch @@ -1,7 +1,7 @@ -From 0df14b3d2578681009ca9be604e98bb94ee1186a Mon Sep 17 00:00:00 2001 +From 252b23b1e979d3b44ca148407d0166c9b618c9e2 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Fri, 24 Feb 2023 16:29:42 +0800 -Subject: [PATCH] wifi: mt76: mt7915: disable SW-ACI by default +Subject: [PATCH 1026/1052] wifi: mt76: mt7915: disable SW-ACI by default Support to enable/disable SW-ACI by module parameter "sw_aci_enable". SW-ACI feature is disable by default. @@ -13,7 +13,7 @@ SW-ACI feature is disable by default. 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/mt7915/main.c b/mt7915/main.c -index b80d6fd..2ff7667 100644 +index 4a5a0155..75042189 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -8,6 +8,10 @@ @@ -39,13 +39,14 @@ index b80d6fd..2ff7667 100644 if (phy != &dev->phy) { diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 5534603..e95a5d7 100644 +index ca18acfb..7a7b3bac 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c -@@ -5223,6 +5223,21 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value) +@@ -5222,3 +5222,18 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value) + return 0; } - ++ +int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val) +{ +#define SWLNA_ENABLE 6 @@ -60,15 +61,11 @@ index 5534603..e95a5d7 100644 + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SWLNA_ACI_CTRL), &req, + sizeof(req), NULL); +} -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 9e7183c..c8b697c 100644 +index 82d374eb..3fa32574 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -783,6 +783,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, +@@ -801,6 +801,7 @@ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, #endif int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation); int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value); @@ -77,7 +74,7 @@ index 9e7183c..c8b697c 100644 int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 8f2f496..ad7abda 100644 +index 3e84d753..d9323603 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3773,16 +3773,12 @@ static int mt7915_show_eeprom_mode(struct seq_file *s, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/1027-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch b/feeds/mediatek-sdk/mt76/patches/1027-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch index 85afdcb9c..0cfc75860 100644 --- a/feeds/mediatek-sdk/mt76/patches/1027-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch +++ b/feeds/mediatek-sdk/mt76/patches/1027-wifi-mt76-mt7915-add-muru-user-number-debug-command.patch @@ -1,7 +1,7 @@ -From ed2035d25794352ca10f4cdc04dd931b1ebfac50 Mon Sep 17 00:00:00 2001 +From ffe8743a0ee8310def4abad0968fee55cf409ea6 Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Thu, 27 Apr 2023 15:37:33 +0800 -Subject: [PATCH 1027/1053] wifi: mt76: mt7915: add muru user number debug +Subject: [PATCH 1027/1052] wifi: mt76: mt7915: add muru user number debug command --- @@ -11,10 +11,10 @@ Subject: [PATCH 1027/1053] wifi: mt76: mt7915: add muru user number debug 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 44dd0f4..e5a201c 100644 +index 3fa32574..c745b31d 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -645,6 +645,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev, +@@ -662,6 +662,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev, int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index, const struct mt7915_dfs_pattern *pattern); int mt7915_mcu_set_muru_ctrl(struct mt7915_dev *dev, u32 cmd, u32 val); @@ -23,10 +23,10 @@ index 44dd0f4..e5a201c 100644 int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy); int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch); diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 9a26f7f..432d750 100644 +index df08704b..6446439f 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -46,6 +46,8 @@ static const struct nla_policy +@@ -47,6 +47,8 @@ static const struct nla_policy mu_ctrl_policy[NUM_MTK_VENDOR_ATTRS_MU_CTRL] = { [MTK_VENDOR_ATTR_MU_CTRL_ONOFF] = {.type = NLA_U8 }, [MTK_VENDOR_ATTR_MU_CTRL_DUMP] = {.type = NLA_U8 }, @@ -35,7 +35,7 @@ index 9a26f7f..432d750 100644 }; static const struct nla_policy -@@ -1053,9 +1055,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, +@@ -1189,9 +1191,10 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, int data_len) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); @@ -47,7 +47,7 @@ index 9a26f7f..432d750 100644 u32 val32 = 0; err = nla_parse(tb, MTK_VENDOR_ATTR_MU_CTRL_MAX, data, data_len, -@@ -1069,6 +1072,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, +@@ -1205,6 +1208,16 @@ static int mt7915_vendor_mu_ctrl(struct wiphy *wiphy, FIELD_PREP(RATE_CFG_VAL, val8); ieee80211_iterate_active_interfaces_atomic(hw, IEEE80211_IFACE_ITER_RESUME_ALL, mt7915_set_wireless_vif, &val32); @@ -65,7 +65,7 @@ index 9a26f7f..432d750 100644 return 0; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index bd1c617..03d1660 100644 +index 5b8d99bf..11ccd0d8 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -103,6 +103,8 @@ enum mtk_vendor_attr_mu_ctrl { diff --git a/feeds/mediatek-sdk/mt76/patches/1028-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch b/feeds/mediatek-sdk/mt76/patches/1028-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch index 480d7c676..650f7decc 100644 --- a/feeds/mediatek-sdk/mt76/patches/1028-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch +++ b/feeds/mediatek-sdk/mt76/patches/1028-wifi-mt76-mt7915-add-debugfs-for-fw-coredump.patch @@ -1,7 +1,7 @@ -From 1eedf84cfc86e9b6e9de78509e85789025b1b3ac Mon Sep 17 00:00:00 2001 +From 15cd113a03288b74f6486c898378d61b2204b09e Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Mon, 22 May 2023 15:30:21 +0800 -Subject: [PATCH 1028/1053] wifi: mt76: mt7915: add debugfs for fw coredump. +Subject: [PATCH 1028/1052] wifi: mt76: mt7915: add debugfs for fw coredump. Signed-off-by: Bo Jiao --- @@ -12,7 +12,7 @@ Signed-off-by: Bo Jiao 4 files changed, 58 insertions(+), 9 deletions(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index fa1d2ac..3044557 100644 +index 3830a735..06c62dd3 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -82,8 +82,10 @@ mt7915_sys_recovery_set(struct file *file, const char __user *user_buf, @@ -67,10 +67,10 @@ index fa1d2ac..3044557 100644 /* SER statistics */ desc += scnprintf(buff + desc, bufsz - desc, diff --git a/mt7915/mac.c b/mt7915/mac.c -index 1e39ad2..14367fd 100644 +index e14b3fdd..35e97f88 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1728,10 +1728,34 @@ void mt7915_mac_dump_work(struct work_struct *work) +@@ -1687,10 +1687,34 @@ void mt7915_mac_dump_work(struct work_struct *work) dev = container_of(work, struct mt7915_dev, dump_work); @@ -107,7 +107,7 @@ index 1e39ad2..14367fd 100644 } void mt7915_reset(struct mt7915_dev *dev) -@@ -1750,7 +1774,7 @@ void mt7915_reset(struct mt7915_dev *dev) +@@ -1709,7 +1733,7 @@ void mt7915_reset(struct mt7915_dev *dev) wiphy_name(dev->mt76.hw->wiphy)); mt7915_irq_disable(dev, MT_INT_MCU_CMD); @@ -117,7 +117,7 @@ index 1e39ad2..14367fd 100644 } diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 6ebcce0..035ad97 100644 +index 6ebcce0d..035ad97d 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -760,8 +760,12 @@ enum { @@ -135,7 +135,7 @@ index 6ebcce0..035ad97 100644 SER_ENABLE = 2, SER_RECOVER diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index e5a201c..ea91611 100644 +index c745b31d..ef51d6e2 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -91,6 +91,13 @@ struct mt7915_sta; @@ -152,7 +152,7 @@ index e5a201c..ea91611 100644 enum mt7915_txq_id { MT7915_TXQ_FWDL = 16, MT7915_TXQ_MCU_WM, -@@ -387,6 +394,7 @@ struct mt7915_dev { +@@ -404,6 +411,7 @@ struct mt7915_dev { /* protects coredump data */ struct mutex dump_mutex; @@ -160,7 +160,7 @@ index e5a201c..ea91611 100644 #ifdef CONFIG_DEV_COREDUMP struct { struct mt7915_crash_data *crash_data[__MT76_RAM_TYPE_MAX]; -@@ -583,6 +591,7 @@ int mt7915_txbf_init(struct mt7915_dev *dev); +@@ -600,6 +608,7 @@ int mt7915_txbf_init(struct mt7915_dev *dev); void mt7915_init_txpower(struct mt7915_phy *phy); int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_en); void mt7915_reset(struct mt7915_dev *dev); diff --git a/feeds/mediatek-sdk/mt76/patches/1029-wifi-mt76-mt7915-remove-BW160-support.patch b/feeds/mediatek-sdk/mt76/patches/1029-wifi-mt76-mt7915-remove-BW160-support.patch index 12435fbb5..ab2f5d5a2 100644 --- a/feeds/mediatek-sdk/mt76/patches/1029-wifi-mt76-mt7915-remove-BW160-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1029-wifi-mt76-mt7915-remove-BW160-support.patch @@ -1,7 +1,7 @@ -From 42cbeac3362b0d1ca2c513b4bcb850a73afafb94 Mon Sep 17 00:00:00 2001 +From 1ffedbe219a388f3b76a717cbf2d42e6ba9b25f2 Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Wed, 24 May 2023 22:35:54 +0800 -Subject: [PATCH 1029/1053] wifi: mt76: mt7915: remove BW160 support +Subject: [PATCH 1029/1052] wifi: mt76: mt7915: remove BW160 support Remove BW160 capability in mt7915. --- @@ -9,10 +9,10 @@ Remove BW160 capability in mt7915. 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/mt7915/init.c b/mt7915/init.c -index b32e213..decccc0 100644 +index a9cb496b..a77078f7 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -439,11 +439,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -441,11 +441,6 @@ mt7915_init_wiphy(struct mt7915_phy *phy) vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; @@ -24,7 +24,7 @@ index b32e213..decccc0 100644 } else { phy->mt76->sband_5g.sband.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_2; -@@ -899,13 +894,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy, +@@ -873,13 +868,9 @@ mt7915_set_stream_he_txbf_caps(struct mt7915_phy *phy, int sts = hweight8(phy->mt76->chainmask); u8 c, sts_160 = sts; @@ -41,7 +41,7 @@ index b32e213..decccc0 100644 #ifdef CONFIG_MAC80211_MESH if (vif == NL80211_IFTYPE_MESH_POINT) -@@ -989,15 +980,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, +@@ -963,15 +954,10 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, int i, idx = 0, nss = hweight8(phy->mt76->antenna_mask); u16 mcs_map = 0; u16 mcs_map_160 = 0; diff --git a/feeds/mediatek-sdk/mt76/patches/1030-wifi-mt76-mt7915-add-txpower-info-dump-support.patch b/feeds/mediatek-sdk/mt76/patches/1030-wifi-mt76-mt7915-add-txpower-info-dump-support.patch index 20c8bd33f..c7b206bb5 100644 --- a/feeds/mediatek-sdk/mt76/patches/1030-wifi-mt76-mt7915-add-txpower-info-dump-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1030-wifi-mt76-mt7915-add-txpower-info-dump-support.patch @@ -1,7 +1,7 @@ -From cc213fc945f430c8767ee6984741c3cf9a030d9c Mon Sep 17 00:00:00 2001 +From ac55beffc7c153e47a63dd889a80f90656afa5a4 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Tue, 11 Jul 2023 17:06:04 +0800 -Subject: [PATCH 1030/1053] wifi: mt76: mt7915: add txpower info dump support +Subject: [PATCH 1030/1052] wifi: mt76: mt7915: add txpower info dump support Signed-off-by: StanleyYP Wang --- @@ -11,7 +11,7 @@ Signed-off-by: StanleyYP Wang 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 3044557..24e88f7 100644 +index 06c62dd3..223f9a37 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -1259,6 +1259,91 @@ mt7915_txpower_path_show(struct seq_file *file, void *data) @@ -106,7 +106,7 @@ index 3044557..24e88f7 100644 static int mt7915_twt_stats(struct seq_file *s, void *data) { -@@ -1388,6 +1473,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) +@@ -1433,6 +1518,8 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) &mt7915_txpower_fops); debugfs_create_file("txpower_path", 0400, dir, phy, &mt7915_txpower_path_fops); @@ -116,7 +116,7 @@ index 3044557..24e88f7 100644 mt7915_twt_stats); debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 45b0907..b9beb4f 100644 +index 7a7b3bac..34d36e50 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -3624,6 +3624,8 @@ int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len, @@ -129,7 +129,7 @@ index 45b0907..b9beb4f 100644 dev_kfree_skb(skb); diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 035ad97..3089fb6 100644 +index 035ad97d..3089fb64 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -525,7 +525,8 @@ enum { diff --git a/feeds/mediatek-sdk/mt76/patches/1031-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch b/feeds/mediatek-sdk/mt76/patches/1031-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch index 4c42bbdb8..db5cf0efc 100644 --- a/feeds/mediatek-sdk/mt76/patches/1031-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch +++ b/feeds/mediatek-sdk/mt76/patches/1031-wifi-mt76-mt7915-report-tx-and-rx-byte-to-tpt_led-wh.patch @@ -1,8 +1,8 @@ -From 539de29220ad63d73fdb1ff86d63014b4e246e3a Mon Sep 17 00:00:00 2001 +From 51f9f9e7d922b77f86ddebca13232472a91609d2 Mon Sep 17 00:00:00 2001 From: Yi-Chia Hsieh Date: Fri, 23 Jun 2023 06:06:21 +0800 -Subject: [PATCH 1031/1053] wifi: mt76: mt7915: report tx and rx byte to - tpt_led when wed is enabled +Subject: [PATCH] wifi: mt76: mt7915: report tx and rx byte to tpt_led when wed + is enabled Signed-off-by: Yi-Chia Hsieh --- @@ -11,18 +11,17 @@ Signed-off-by: Yi-Chia Hsieh 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index 630c640..949df63 100644 +index 09c28dc..8a511c9 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c -@@ -597,9 +597,15 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, +@@ -605,8 +605,14 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, txs = le32_to_cpu(txs_data[0]); + mphy = mt76_dev_phy(dev, wcid->phy_idx); + /* PPDU based reporting */ - if (mtk_wed_device_active(&dev->mmio.wed) && - FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { + if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { + ieee80211_tpt_led_trig_tx(mphy->hw, + le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - + le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE)); @@ -30,7 +29,7 @@ index 630c640..949df63 100644 stats->tx_bytes += le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); -@@ -640,10 +646,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, +@@ -650,10 +656,6 @@ bool mt76_connac2_mac_fill_txs(struct mt76_dev *dev, struct mt76_wcid *wcid, cck = true; fallthrough; case MT_PHY_TYPE_OFDM: @@ -42,7 +41,7 @@ index 630c640..949df63 100644 sband = &mphy->sband_5g.sband; else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index ddf1b72..437a9b0 100644 +index ed15d71..b1b219c 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -588,6 +588,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed, @@ -65,5 +64,5 @@ index ddf1b72..437a9b0 100644 wcid->stats.rx_packets += le32_to_cpu(stats->rx_pkt_cnt); wcid->stats.rx_errors += le32_to_cpu(stats->rx_err_cnt); -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1032-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch b/feeds/mediatek-sdk/mt76/patches/1032-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch index 3e8500fa8..a62749d2b 100644 --- a/feeds/mediatek-sdk/mt76/patches/1032-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch +++ b/feeds/mediatek-sdk/mt76/patches/1032-wifi-mt76-mt7915-Establish-BA-in-VO-queue.patch @@ -1,17 +1,17 @@ -From d588c607b158e13343964b451d1de5b98bba7feb Mon Sep 17 00:00:00 2001 +From fcfa851c3dd6782c382dc1890f2623fdc0858f73 Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Tue, 8 Aug 2023 11:20:58 +0800 -Subject: [PATCH 1032/1053] wifi: mt76: mt7915: Establish BA in VO queue +Subject: [PATCH 1032/1052] wifi: mt76: mt7915: Establish BA in VO queue --- mt76_connac_mac.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index 949df63..d036047 100644 +index 6eeea971..c23d266e 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c -@@ -1115,8 +1115,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) +@@ -1123,8 +1123,6 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) return; tid = le32_get_bits(txwi[1], MT_TXD1_TID); diff --git a/feeds/mediatek-sdk/mt76/patches/1033-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch b/feeds/mediatek-sdk/mt76/patches/1033-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch index 09fda9134..4ca8bffa6 100644 --- a/feeds/mediatek-sdk/mt76/patches/1033-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch +++ b/feeds/mediatek-sdk/mt76/patches/1033-wifi-mt76-mt7915-Disable-RegDB-when-enable-single-sk.patch @@ -1,7 +1,7 @@ -From ee3f33638400dfe0306ed5d12f1e2c1840632cea Mon Sep 17 00:00:00 2001 +From 6eb114c04f79a4e1642a6743e9895cb8038a4630 Mon Sep 17 00:00:00 2001 From: "Allen.Ye" Date: Fri, 11 Aug 2023 16:46:53 +0800 -Subject: [PATCH 1033/1053] wifi: mt76: mt7915: Disable RegDB when enable +Subject: [PATCH 1033/1052] wifi: mt76: mt7915: Disable RegDB when enable single sku --- @@ -11,7 +11,7 @@ Subject: [PATCH 1033/1053] wifi: mt76: mt7915: Disable RegDB when enable 3 files changed, 57 insertions(+), 11 deletions(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 24e88f7..502b493 100644 +index 223f9a37..2c1e1bea 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -1020,10 +1020,16 @@ mt7915_rate_txpower_get(struct file *file, char __user *user_buf, @@ -40,15 +40,15 @@ index 24e88f7..502b493 100644 - MT_WF_PHY_TPC_CTRL_STAT_MT7916(band); + reg = is_mt7915(&dev->mt76) ? MT_WF_IRPI_TPC_CTRL_STAT(band) : + MT_WF_IRPI_TPC_CTRL_STAT_MT7916(band); - -- len += scnprintf(buf + len, sz - len, "\nTx power (bbp) : %6ld\n", -- mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER)); ++ + len += scnprintf(buf + len, sz - len, "\nTx power (bbp) : %6ld [0.5 dBm]\n", + mt76_get_field(dev, reg, MT_WF_IRPI_TPC_POWER)); + + len += scnprintf(buf + len, sz - len, "RegDB maximum power:\t%d [dBm]\n", + chan->max_reg_power); -+ + +- len += scnprintf(buf + len, sz - len, "\nTx power (bbp) : %6ld\n", +- mt76_get_field(dev, reg, MT_WF_PHY_TPC_POWER)); + if (chan->band == NL80211_BAND_2GHZ) + sband = phy->mt76->sband_2g.sband; + else if (chan->band == NL80211_BAND_5GHZ) @@ -103,10 +103,10 @@ index 24e88f7..502b493 100644 return ret; } diff --git a/mt7915/init.c b/mt7915/init.c -index decccc0..a5b38c8 100644 +index a77078f7..6f616b54 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -283,9 +283,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, +@@ -284,9 +284,11 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, int nss_delta = mt76_tx_power_nss_delta(n_chains); int pwr_delta = mt7915_eeprom_get_power_delta(dev, sband->band); struct mt76_power_limits limits; @@ -118,7 +118,7 @@ index decccc0..a5b38c8 100644 for (i = 0; i < sband->n_channels; i++) { struct ieee80211_channel *chan = &sband->channels[i]; u32 target_power = 0; -@@ -309,8 +311,13 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, +@@ -310,8 +312,13 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, target_power += nss_delta; target_power = DIV_ROUND_UP(target_power, 2); @@ -135,7 +135,7 @@ index decccc0..a5b38c8 100644 } } diff --git a/mt7915/regs.h b/mt7915/regs.h -index 4d05e39..ca355d1 100644 +index 4d05e391..ca355d14 100644 --- a/mt7915/regs.h +++ b/mt7915/regs.h @@ -1215,6 +1215,10 @@ enum offs_rev { diff --git a/feeds/mediatek-sdk/mt76/patches/1034-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch b/feeds/mediatek-sdk/mt76/patches/1034-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch index 8467fb709..89f875ee9 100644 --- a/feeds/mediatek-sdk/mt76/patches/1034-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch +++ b/feeds/mediatek-sdk/mt76/patches/1034-wifi-mt76-mt7915-enable-the-mac80211-hw-bmc-ps-buffe.patch @@ -1,18 +1,18 @@ -From 20c497b434dc4555210ea64cde38dd86817d8891 Mon Sep 17 00:00:00 2001 +From 18fd1219383a2d2f2b0881d87ca8a1552e273bf1 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Thu, 24 Aug 2023 03:01:27 +0800 -Subject: [PATCH] wifi: mt76: mt7915: enable the mac80211 hw bmc ps buffer - function. +Subject: [PATCH 1034/1052] wifi: mt76: mt7915: enable the mac80211 hw bmc ps + buffer function. --- mt7915/init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mt7915/init.c b/mt7915/init.c -index 35aefca..545afe7 100644 +index 6f616b54..c4685f21 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -413,6 +413,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -414,6 +414,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) ieee80211_hw_set(hw, SUPPORTS_RX_DECAP_OFFLOAD); ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); ieee80211_hw_set(hw, WANT_MONITOR_VIF); diff --git a/feeds/mediatek-sdk/mt76/patches/1035-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch b/feeds/mediatek-sdk/mt76/patches/1035-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch index 5c46d2929..b41c81dd9 100644 --- a/feeds/mediatek-sdk/mt76/patches/1035-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch +++ b/feeds/mediatek-sdk/mt76/patches/1035-wifi-mt76-update-debugfs-knob-for-tx-tokens.patch @@ -1,7 +1,7 @@ -From e9cf08519595e2d8c5c227486948d8cb00db626a Mon Sep 17 00:00:00 2001 +From c324616943e4a51d5d288a26bdbb330be11d2d8f Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Thu, 24 Aug 2023 03:01:27 +0800 -Subject: [PATCH 1035/1053] wifi: mt76: update debugfs knob for tx tokens +Subject: [PATCH 1035/1052] wifi: mt76: update debugfs knob for tx tokens 1. dump token pending time 2. dump per-band token counts @@ -14,7 +14,7 @@ Signed-off-by: Peter Chiu 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/mt76.h b/mt76.h -index 5c26715..6f78c07 100644 +index 580320fd..16b76b48 100644 --- a/mt76.h +++ b/mt76.h @@ -403,6 +403,7 @@ struct mt76_txwi_cache { @@ -26,7 +26,7 @@ index 5c26715..6f78c07 100644 union { struct sk_buff *skb; diff --git a/mt7915/mac.c b/mt7915/mac.c -index 14367fd..71b4e2d 100644 +index 35e97f88..a7314465 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -811,6 +811,8 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, @@ -39,7 +39,7 @@ index 14367fd..71b4e2d 100644 mt7915_mac_write_txwi(mdev, txwi_ptr, tx_info->skb, wcid, pid, key, qid, 0); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index f00ac10..3c248ee 100644 +index d9323603..2cc0b2d8 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -2203,17 +2203,31 @@ static int mt7915_mibinfo_band1(struct seq_file *s, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/1036-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch b/feeds/mediatek-sdk/mt76/patches/1036-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch index 4306c68de..98ae91e5d 100644 --- a/feeds/mediatek-sdk/mt76/patches/1036-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch +++ b/feeds/mediatek-sdk/mt76/patches/1036-wifi-mt76-mt7915-support-enable-disable-spatial-reus.patch @@ -1,7 +1,7 @@ -From e81df1a68b96bc91891c9c097db376a1890450ae Mon Sep 17 00:00:00 2001 +From 8e5290c521da92f931b169e1b2dccc7125e17253 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Tue, 5 Sep 2023 20:17:19 +0800 -Subject: [PATCH 1036/1053] wifi: mt76: mt7915: support enable/disable spatial +Subject: [PATCH 1036/1052] wifi: mt76: mt7915: support enable/disable spatial reuse through debugfs Signed-off-by: Howard Hsu @@ -12,7 +12,7 @@ Signed-off-by: Howard Hsu 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index b9beb4f..4b5fb53 100644 +index 34d36e50..40d94c4f 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -3756,8 +3756,7 @@ int mt7915_mcu_set_txbf(struct mt7915_dev *dev, u8 action) @@ -26,10 +26,10 @@ index b9beb4f..4b5fb53 100644 struct mt7915_dev *dev = phy->dev; struct mt7915_mcu_sr_ctrl req = { diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index ea91611..bfd87bc 100644 +index ef51d6e2..bc0f313c 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -795,6 +795,7 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value); +@@ -814,6 +814,7 @@ int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value); int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val); int mt7915_mcu_ipi_hist_ctrl(struct mt7915_phy *phy, void *data, u8 cmd, bool wait_resp); int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp); @@ -38,7 +38,7 @@ index ea91611..bfd87bc 100644 #ifdef MTK_DEBUG int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 3c248ee..9bbe50d 100644 +index 2cc0b2d8..c00184f8 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3799,6 +3799,17 @@ mt7915_sw_aci_set(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/1037-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch b/feeds/mediatek-sdk/mt76/patches/1037-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch index d61c1fba0..d3fd14d98 100644 --- a/feeds/mediatek-sdk/mt76/patches/1037-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch +++ b/feeds/mediatek-sdk/mt76/patches/1037-wifi-mt76-mt7915-add-debug-log-for-SER-flow.patch @@ -1,7 +1,7 @@ -From b8b4b5abf0dce8bedfca44e1a7871c119f2b92e6 Mon Sep 17 00:00:00 2001 +From 50046dd2dad794942f0f28fda6ede3b90261e0be Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Mon, 11 Sep 2023 17:11:24 +0800 -Subject: [PATCH 1037/1053] wifi: mt76: mt7915: add debug log for SER flow. +Subject: [PATCH 1037/1052] wifi: mt76: mt7915: add debug log for SER flow. Signed-off-by: Bo Jiao --- @@ -9,10 +9,10 @@ Signed-off-by: Bo Jiao 1 file changed, 9 insertions(+) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 71b4e2d..b0ddb10 100644 +index a7314465..c421447c 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1572,6 +1572,9 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1531,6 +1531,9 @@ void mt7915_mac_reset_work(struct work_struct *work) if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA)) return; @@ -22,7 +22,7 @@ index 71b4e2d..b0ddb10 100644 ieee80211_stop_queues(mt76_hw(dev)); if (ext_phy) ieee80211_stop_queues(ext_phy->hw); -@@ -1647,6 +1650,9 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1606,6 +1609,9 @@ void mt7915_mac_reset_work(struct work_struct *work) ieee80211_queue_delayed_work(ext_phy->hw, &phy2->mt76->mac_work, MT7915_WATCHDOG_TIME); @@ -32,7 +32,7 @@ index 71b4e2d..b0ddb10 100644 } /* firmware coredump */ -@@ -1762,6 +1768,9 @@ void mt7915_coredump(struct mt7915_dev *dev, u8 state) +@@ -1721,6 +1727,9 @@ void mt7915_coredump(struct mt7915_dev *dev, u8 state) void mt7915_reset(struct mt7915_dev *dev) { diff --git a/feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch b/feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch similarity index 88% rename from feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch rename to feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch index 422582573..a367ad8ca 100644 --- a/feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch +++ b/feeds/mediatek-sdk/mt76/patches/1038-wifi-mt76-mt7915-add-debuffs-knob-for-protect-thresh.patch @@ -1,7 +1,7 @@ -From 2674288ca511860d73b068f73c14d864de13653f Mon Sep 17 00:00:00 2001 +From 5fa70ee3f31733b9ddee67fdc78fe637df251aca Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 2 Oct 2023 14:00:13 +0800 -Subject: [PATCH 1039/1053] wifi: mt76: mt7915: add debuffs knob for protect +Subject: [PATCH 1038/1052] wifi: mt76: mt7915: add debuffs knob for protect threshold --- @@ -10,10 +10,10 @@ Subject: [PATCH 1039/1053] wifi: mt76: mt7915: add debuffs knob for protect 2 files changed, 12 insertions(+) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index bfd87bc..1b43c54 100644 +index bc0f313c..183d59da 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -775,6 +775,7 @@ void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev, +@@ -792,6 +792,7 @@ void mt7915_mcu_set_rfeature_starec(void *data, struct mt7915_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig_type); int mt7915_mcu_set_mu_dl_ack_policy(struct mt7915_phy *phy, u8 policy_num); @@ -22,7 +22,7 @@ index bfd87bc..1b43c54 100644 void mt7915_mcu_set_nusers_ofdma(struct mt7915_phy *phy, u8 type, u8 ofdma_user_cnt); void mt7915_mcu_set_mimo(struct mt7915_phy *phy, u8 direction); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 9bbe50d..2b59e35 100644 +index c00184f8..c8efd266 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -2852,6 +2852,16 @@ static int mt7915_sta_tx_amsdu_set(void *data, u64 tx_amsdu) diff --git a/feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch b/feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch similarity index 86% rename from feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch rename to feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch index b1594a10d..39612b05c 100644 --- a/feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1039-wifi-mt76-mt7915-add-mt7981-efuse-variants-support.patch @@ -1,7 +1,7 @@ -From 45752d6719ee863fe80d2821f9ff6176e6a2497d Mon Sep 17 00:00:00 2001 +From 90dfcdd20e564dc3b82342141dfd6917899b7b66 Mon Sep 17 00:00:00 2001 From: "Henry.Yen" Date: Mon, 11 Dec 2023 16:01:55 +0800 -Subject: [PATCH 1040/1053] wifi: mt76: mt7915 add mt7981 efuse variants +Subject: [PATCH 1039/1052] wifi: mt76: mt7915 add mt7981 efuse variants support --- @@ -10,7 +10,7 @@ Subject: [PATCH 1040/1053] wifi: mt76: mt7915 add mt7981 efuse variants 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c -index 6133c20..df5e396 100644 +index 6133c200..df5e396c 100644 --- a/mt7915/eeprom.c +++ b/mt7915/eeprom.c @@ -193,6 +193,21 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) @@ -50,10 +50,10 @@ index 6133c20..df5e396 100644 mt7915_eeprom_parse_band_config(phy); diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 1b43c54..c6150c8 100644 +index 183d59da..c8f9ed52 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -407,6 +407,7 @@ struct mt7915_dev { +@@ -424,6 +424,7 @@ struct mt7915_dev { u32 hw_pattern; @@ -61,7 +61,7 @@ index 1b43c54..c6150c8 100644 bool dbdc_support; bool flash_mode; bool bin_file_mode; -@@ -681,7 +682,11 @@ void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb); +@@ -698,7 +699,11 @@ void mt7915_tm_rf_test_event(struct mt7915_dev *dev, struct sk_buff *skb); static inline u16 mt7915_wtbl_size(struct mt7915_dev *dev) { diff --git a/feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-scs-feature.patch b/feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-support-scs-feature.patch similarity index 90% rename from feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-scs-feature.patch rename to feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-support-scs-feature.patch index aa6ba21f1..0f39a4a1a 100644 --- a/feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-scs-feature.patch +++ b/feeds/mediatek-sdk/mt76/patches/1040-wifi-mt76-mt7915-support-scs-feature.patch @@ -1,7 +1,7 @@ -From 9c8dcebc80801b77b23b0a2af28a3d51662c164f Mon Sep 17 00:00:00 2001 +From 5ba9ebc9e86610960d798ff1103350d2d3453a90 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Wed, 6 Dec 2023 08:53:03 +0800 -Subject: [PATCH] wifi: mt76: mt7915: support scs feature +Subject: [PATCH 1040/1052] wifi: mt76: mt7915: support scs feature Add support scs feature for connac2 codebase. This commit includes three parts. @@ -29,7 +29,7 @@ Signed-off-by: Howard Hsu 9 files changed, 188 insertions(+) diff --git a/mt76.h b/mt76.h -index cff22f5..7ffba7d 100644 +index 16b76b48..43f3c282 100644 --- a/mt76.h +++ b/mt76.h @@ -311,6 +311,7 @@ struct mt76_sta_stats { @@ -49,10 +49,10 @@ index cff22f5..7ffba7d 100644 enum mt76_wcid_flags { diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 94fcf32..247b520 100644 +index 49c3f1aa..febe3ed4 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1236,6 +1236,7 @@ enum { +@@ -1238,6 +1238,7 @@ enum { MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, MCU_EXT_CMD_MWDS_SUPPORT = 0x80, MCU_EXT_CMD_SET_SER_TRIGGER = 0x81, @@ -61,10 +61,10 @@ index 94fcf32..247b520 100644 MCU_EXT_CMD_FW_DBG_CTRL = 0x95, MCU_EXT_CMD_OFFCH_SCAN_CTRL = 0x9a, diff --git a/mt7915/init.c b/mt7915/init.c -index 545afe7..074f247 100644 +index c4685f21..a26e0d69 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -1248,6 +1248,7 @@ int mt7915_register_device(struct mt7915_dev *dev) +@@ -1222,6 +1222,7 @@ int mt7915_register_device(struct mt7915_dev *dev) spin_lock_init(&dev->phy.stats_lock); INIT_WORK(&dev->rc_work, mt7915_mac_sta_rc_work); INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7915_mac_work); @@ -73,10 +73,10 @@ index 545afe7..074f247 100644 INIT_LIST_HEAD(&dev->twt_list); diff --git a/mt7915/mac.c b/mt7915/mac.c -index 9a49375..2e4a8f8 100644 +index c421447c..fb989405 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1504,6 +1504,8 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) +@@ -1463,6 +1463,8 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) if (ext_phy) cancel_delayed_work_sync(&ext_phy->mac_work); @@ -85,7 +85,7 @@ index 9a49375..2e4a8f8 100644 mutex_lock(&dev->mt76.mutex); for (i = 0; i < 10; i++) { if (!mt7915_mac_restart(dev)) -@@ -1529,6 +1531,10 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) +@@ -1488,6 +1490,10 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) ieee80211_queue_delayed_work(ext_phy->hw, &ext_phy->mac_work, MT7915_WATCHDOG_TIME); @@ -96,7 +96,7 @@ index 9a49375..2e4a8f8 100644 } /* system error recovery */ -@@ -1587,6 +1593,7 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1546,6 +1552,7 @@ void mt7915_mac_reset_work(struct work_struct *work) set_bit(MT76_RESET, &phy2->mt76->state); cancel_delayed_work_sync(&phy2->mt76->mac_work); } @@ -104,7 +104,7 @@ index 9a49375..2e4a8f8 100644 mt76_worker_disable(&dev->mt76.tx_worker); mt76_for_each_q_rx(&dev->mt76, i) napi_disable(&dev->mt76.napi[i]); -@@ -1651,6 +1658,10 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1610,6 +1617,10 @@ void mt7915_mac_reset_work(struct work_struct *work) &phy2->mt76->mac_work, MT7915_WATCHDOG_TIME); @@ -116,7 +116,7 @@ index 9a49375..2e4a8f8 100644 wiphy_name(dev->mt76.hw->wiphy)); } diff --git a/mt7915/main.c b/mt7915/main.c -index 2ff7667..2750e60 100644 +index 75042189..04301300 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -89,12 +89,24 @@ int mt7915_run(struct ieee80211_hw *hw) @@ -153,13 +153,14 @@ index 2ff7667..2750e60 100644 mt7915_mcu_set_mac(dev, dev->phy.mt76->band_idx, false, false); } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 1af6dac..aa3f9ad 100644 +index 40d94c4f..fcbe4da4 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c -@@ -5239,6 +5239,124 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val) +@@ -5238,3 +5238,121 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val) + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SWLNA_ACI_CTRL), &req, sizeof(req), NULL); } - ++ +int mt7915_mcu_set_scs_en(struct mt7915_phy *phy, u8 enable) +{ + struct mt7915_dev *dev = phy->dev; @@ -277,12 +278,8 @@ index 1af6dac..aa3f9ad 100644 + if (scs_enable_flag) + ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ); +} -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 3089fb6..742a785 100644 +index 3089fb64..742a7855 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -1200,4 +1200,8 @@ struct mt7915_mcu_edcca_info { @@ -295,10 +292,10 @@ index 3089fb6..742a785 100644 +}; #endif diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 03ec7e2..3daec29 100644 +index c8f9ed52..6b27be9c 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -270,6 +270,15 @@ struct mt7915_air_monitor_ctrl { +@@ -283,6 +283,15 @@ struct mt7915_air_monitor_ctrl { }; #endif @@ -314,7 +311,7 @@ index 03ec7e2..3daec29 100644 struct mt7915_phy { struct mt76_phy *mt76; struct mt7915_dev *dev; -@@ -344,6 +353,7 @@ struct mt7915_phy { +@@ -361,6 +370,7 @@ struct mt7915_phy { struct mt7915_air_monitor_ctrl amnt_ctrl; #endif @@ -322,7 +319,7 @@ index 03ec7e2..3daec29 100644 }; #ifdef MTK_DEBUG -@@ -476,6 +486,8 @@ struct mt7915_dev { +@@ -493,6 +503,8 @@ struct mt7915_dev { } adie[ADIE_MAX_CNT]; #endif @@ -331,7 +328,7 @@ index 03ec7e2..3daec29 100644 bool wmm_pbc_enable; struct work_struct wmm_pbc_work; u32 adie_type; -@@ -803,6 +815,8 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val); +@@ -821,6 +833,8 @@ int mt7915_mcu_sw_aci_set(struct mt7915_dev *dev, bool val); int mt7915_mcu_ipi_hist_ctrl(struct mt7915_phy *phy, void *data, u8 cmd, bool wait_resp); int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool wait_resp); int mt7915_mcu_enable_obss_spr(struct mt7915_phy *phy, u8 action, u8 val); @@ -341,7 +338,7 @@ index 03ec7e2..3daec29 100644 #ifdef MTK_DEBUG int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index dad5ed7..0953223 100644 +index c8efd266..e60dc850 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3820,6 +3820,29 @@ mt7915_sr_enable_set(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch b/feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch similarity index 85% rename from feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch rename to feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch index 7358d2751..51ad6bcbc 100644 --- a/feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch +++ b/feeds/mediatek-sdk/mt76/patches/1041-wifi-mt76-mt7915-support-thermal-recal-debug-commnad.patch @@ -1,7 +1,8 @@ -From e9f5c9f345503c5653d1a5fd5bedd69cd1bc48f1 Mon Sep 17 00:00:00 2001 +From 71385726a0af02c6cb650a6be60511e6f0f1b3a4 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Thu, 21 Dec 2023 20:35:36 +0800 -Subject: [PATCH] wifi: mt76: mt7915: support thermal recal debug commnad +Subject: [PATCH 1041/1052] wifi: mt76: mt7915: support thermal recal debug + commnad Add thermal recal debug command: $ echo val > debugfs/thermal_recal @@ -20,10 +21,10 @@ Signed-off-by: Howard Hsu 4 files changed, 35 insertions(+) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 247b520..e445046 100644 +index febe3ed4..8a0f5bea 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1232,6 +1232,7 @@ enum { +@@ -1234,6 +1234,7 @@ enum { MCU_EXT_CMD_RED_ENABLE = 0x68, MCU_EXT_CMD_PKT_BUDGET_CTRL = 0x6c, MCU_EXT_CMD_CP_SUPPORT = 0x75, @@ -32,13 +33,14 @@ index 247b520..e445046 100644 MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d, MCU_EXT_CMD_MWDS_SUPPORT = 0x80, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index aa3f9ad..2417251 100644 +index fcbe4da4..2b653bfb 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c -@@ -5357,6 +5357,21 @@ void mt7915_mcu_scs_sta_poll(struct work_struct *work) +@@ -5356,3 +5356,18 @@ void mt7915_mcu_scs_sta_poll(struct work_struct *work) + if (scs_enable_flag) ieee80211_queue_delayed_work(mt76_hw(dev), &dev->scs_work, HZ); } - ++ +int mt7915_mcu_thermal_debug(struct mt7915_dev *dev, u8 mode, u8 action) +{ + struct { @@ -53,15 +55,11 @@ index aa3f9ad..2417251 100644 + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_DEBUG), &req, + sizeof(req), true); +} -+ - int mt7915_mcu_set_qos_map(struct mt7915_dev *dev, struct ieee80211_vif *vif) - { - #define IP_DSCP_NUM 64 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 3daec29..9b52ec4 100644 +index 6b27be9c..496ccd94 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -817,6 +817,7 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w +@@ -835,6 +835,7 @@ int mt7915_mcu_ipi_hist_scan(struct mt7915_phy *phy, void *data, u8 mode, bool w int mt7915_mcu_enable_obss_spr(struct mt7915_phy *phy, u8 action, u8 val); int mt7915_mcu_set_scs_en(struct mt7915_phy *phy, u8 enable); void mt7915_mcu_scs_sta_poll(struct work_struct *work); @@ -70,7 +68,7 @@ index 3daec29..9b52ec4 100644 #ifdef MTK_DEBUG int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 0953223..53294c1 100644 +index e60dc850..0677495c 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3843,6 +3843,22 @@ mt7915_scs_enable_set(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch b/feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch similarity index 93% rename from feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch rename to feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch index c91ad4457..4dbc453ab 100644 --- a/feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch +++ b/feeds/mediatek-sdk/mt76/patches/1042-wifi-mt76-mt7915-Add-support-for-lpi-and-duplicate-m.patch @@ -1,7 +1,8 @@ -From 771d717a6bce6c6a7f7bb06599b42fa3994b560e Mon Sep 17 00:00:00 2001 +From 45dbb4f20ca056bd56f8c723a10d0f5662d92f75 Mon Sep 17 00:00:00 2001 From: Allen Ye Date: Fri, 15 Dec 2023 14:03:11 +0800 -Subject: [PATCH] wifi: mt76: mt7915: Add support for lpi and duplicate mode +Subject: [PATCH 1042/1052] wifi: mt76: mt7915: Add support for lpi and + duplicate mode Add support lpi and duplicate mode. 1. lpi_enable: lpi fw cmd and set psd flag to fw by the country setting. @@ -30,7 +31,7 @@ Signed-off-by: Allen Ye 12 files changed, 210 insertions(+), 17 deletions(-) diff --git a/eeprom.c b/eeprom.c -index 4213e44..2ee262a 100644 +index aa33e7b5..261d65ad 100644 --- a/eeprom.c +++ b/eeprom.c @@ -224,8 +224,9 @@ static bool mt76_string_prop_find(struct property *prop, const char *str) @@ -94,7 +95,7 @@ index 4213e44..2ee262a 100644 return target_power; diff --git a/mt76.h b/mt76.h -index c011812..b023f38 100644 +index 43f3c282..a18b3e57 100644 --- a/mt76.h +++ b/mt76.h @@ -853,6 +853,9 @@ struct mt76_phy { @@ -107,7 +108,7 @@ index c011812..b023f38 100644 u8 antenna_mask; u16 chainmask; -@@ -1744,7 +1747,7 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, +@@ -1753,7 +1756,7 @@ mt76_mcu_skb_send_msg(struct mt76_dev *dev, struct sk_buff *skb, int cmd, void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, u32 clear, u32 set); struct device_node * @@ -117,7 +118,7 @@ index c011812..b023f38 100644 mt76_find_channel_node(struct device_node *np, struct ieee80211_channel *chan); diff --git a/mt76_connac2_mac.h b/mt76_connac2_mac.h -index eb47653..49ba39f 100644 +index eb476536..49ba39ff 100644 --- a/mt76_connac2_mac.h +++ b/mt76_connac2_mac.h @@ -355,6 +355,13 @@ enum tx_port_idx { @@ -135,7 +136,7 @@ index eb47653..49ba39f 100644 MT_TX_FRAG_NONE, MT_TX_FRAG_FIRST, diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index 5ba0255..5f705bb 100644 +index c23d266e..d1708152 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c @@ -572,7 +572,8 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, @@ -160,10 +161,10 @@ index 5ba0255..5f705bb 100644 txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU); diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index cbe8da5..c96621f 100644 +index 8a0f5bea..3148526a 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1257,6 +1257,7 @@ enum { +@@ -1260,6 +1260,7 @@ enum { MCU_EXT_CMD_SWLNA_ACI_CTRL = 0xc0, MCU_EXT_CMD_CSI_CTRL = 0xc2, MCU_EXT_CMD_IPI_HIST_SCAN = 0xc5, @@ -172,7 +173,7 @@ index cbe8da5..c96621f 100644 enum { diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 502b493..b2a4ff4 100644 +index 2c1e1bea..f031b54c 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -1297,7 +1297,6 @@ mt7915_txpower_info_show(struct seq_file *file, void *data) @@ -193,10 +194,10 @@ index 502b493..b2a4ff4 100644 out: diff --git a/mt7915/init.c b/mt7915/init.c -index 373f4f5..b53075b 100644 +index a26e0d69..e8a6fcda 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -287,7 +287,7 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, +@@ -288,7 +288,7 @@ static void __mt7915_init_txpower(struct mt7915_phy *phy, phy->sku_limit_en = true; phy->sku_path_en = true; @@ -205,7 +206,7 @@ index 373f4f5..b53075b 100644 for (i = 0; i < sband->n_channels; i++) { struct ieee80211_channel *chan = &sband->channels[i]; u32 target_power = 0; -@@ -331,8 +331,10 @@ void mt7915_init_txpower(struct mt7915_phy *phy) +@@ -332,8 +332,10 @@ void mt7915_init_txpower(struct mt7915_phy *phy) __mt7915_init_txpower(phy, &phy->mt76->sband_2g.sband); if (phy->mt76->cap.has_5ghz) __mt7915_init_txpower(phy, &phy->mt76->sband_5g.sband); @@ -218,7 +219,7 @@ index 373f4f5..b53075b 100644 static void diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index c5f60c0..e17c61d 100644 +index 2b653bfb..0fba0a6d 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -1522,7 +1522,8 @@ mt7915_mcu_set_spe_idx(struct mt7915_dev *dev, struct ieee80211_vif *vif, @@ -354,10 +355,10 @@ index c5f60c0..e17c61d 100644 u8 en) { diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 1b2f584..ff08d25 100644 +index 496ccd94..74008d4f 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -807,6 +807,7 @@ int mt7915_mcu_set_csi(struct mt7915_phy *phy, u8 mode, +@@ -826,6 +826,7 @@ void mt7915_csi_mac_filter_clear(struct mt7915_phy *phy); void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, struct ieee80211_sta *sta); @@ -366,7 +367,7 @@ index 1b2f584..ff08d25 100644 int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation); int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 53294c1..352b8e9 100644 +index 0677495c..3291aafc 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3945,6 +3945,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir) @@ -378,10 +379,10 @@ index 53294c1..352b8e9 100644 debugfs_create_devm_seqfile(dev->mt76.dev, "eeprom_mode", dir, mt7915_show_eeprom_mode); diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 432d750..566fec0 100644 +index 6446439f..a9e87a17 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -106,6 +106,13 @@ bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = { +@@ -107,6 +107,13 @@ bss_color_ctrl_policy[NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL] = { [MTK_VENDOR_ATTR_AVAL_BSS_COLOR_BMP] = { .type = NLA_U64 }, }; @@ -395,7 +396,7 @@ index 432d750..566fec0 100644 struct csi_null_tone { u8 start; u8 end; -@@ -1335,6 +1342,63 @@ mt7915_vendor_bss_color_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev +@@ -1471,6 +1478,63 @@ mt7915_vendor_bss_color_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev return len; } @@ -459,7 +460,7 @@ index 432d750..566fec0 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1451,6 +1515,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1587,6 +1651,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .dumpit = mt7915_vendor_bss_color_ctrl_dump, .policy = bss_color_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX, @@ -478,7 +479,7 @@ index 432d750..566fec0 100644 }; diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 03d1660..5b8a1fb 100644 +index 11ccd0d8..3040007f 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds { @@ -489,7 +490,7 @@ index 03d1660..5b8a1fb 100644 }; -@@ -274,4 +275,18 @@ enum mtk_vendor_attr_bss_color_ctrl { +@@ -287,4 +288,18 @@ enum mtk_vendor_attr_bss_color_ctrl { MTK_VENDOR_ATTR_BSS_COLOR_CTRL_MAX = NUM_MTK_VENDOR_ATTRS_BSS_COLOR_CTRL - 1 }; diff --git a/feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch b/feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch similarity index 93% rename from feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch rename to feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch index fa23d7d98..c568929fb 100644 --- a/feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-testmode-add-cheetah-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/1043-wifi-mt76-testmode-add-cheetah-support.patch @@ -1,7 +1,7 @@ -From e9b737f036595d84f680ff9ee15cfffe5cd08efc Mon Sep 17 00:00:00 2001 +From 3eec1f57a5ad5fd0322ac69360cac993ef9f8902 Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Tue, 31 Oct 2023 16:29:13 +0800 -Subject: [PATCH 1044/1053] wifi: mt76: testmode: add cheetah support +Subject: [PATCH 1043/1052] wifi: mt76: testmode: add cheetah support Signed-off-by: StanleyYP Wang --- @@ -9,7 +9,7 @@ Signed-off-by: StanleyYP Wang 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index faf6014..ecd6271 100644 +index faf60146..ecd62712 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -2151,7 +2151,7 @@ mt7915_tm_group_prek(struct mt7915_phy *phy, enum mt76_testmode_state state) diff --git a/feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch b/feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch similarity index 87% rename from feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch rename to feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch index d0fd257aa..bcc045025 100644 --- a/feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch +++ b/feeds/mediatek-sdk/mt76/patches/1044-wifi-mt76-mt7915-add-no_beacon-vendor-command-for-ce.patch @@ -1,7 +1,7 @@ -From 966bba87073d983aa136f1f762d1b787a81ec767 Mon Sep 17 00:00:00 2001 +From e91a2d40ac3cb7c76827b894c03e31e577944f68 Mon Sep 17 00:00:00 2001 From: MeiChia Chiu Date: Wed, 24 Jan 2024 14:39:14 +0800 -Subject: [PATCH 1045/1053] wifi: mt76: mt7915: add no_beacon vendor command +Subject: [PATCH 1044/1052] wifi: mt76: mt7915: add no_beacon vendor command for cert Add the vendor command to disable/enable beacon @@ -21,7 +21,7 @@ Signed-off-by: MeiChia Chiu 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index e17c61d..ddb738c 100644 +index 0fba0a6d..b1cb7747 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -5101,6 +5101,17 @@ int mt7915_mcu_set_rfeature_trig_type(struct mt7915_phy *phy, u8 enable, u8 trig @@ -43,10 +43,10 @@ index e17c61d..ddb738c 100644 #ifdef MTK_DEBUG diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index ff08d25..34f1a35 100644 +index 74008d4f..8b2e360e 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -808,6 +808,7 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); +@@ -827,6 +827,7 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb); int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy, struct ieee80211_sta *sta); int mt7915_mcu_set_lpi(struct mt7915_phy *phy, bool en); @@ -55,10 +55,10 @@ index ff08d25..34f1a35 100644 int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value, s8 compensation); int mt7915_mcu_get_edcca(struct mt7915_phy *phy, u8 mode, s8 *value); diff --git a/mt7915/vendor.c b/mt7915/vendor.c -index 566fec0..6154d1a 100644 +index a9e87a17..309480d1 100644 --- a/mt7915/vendor.c +++ b/mt7915/vendor.c -@@ -113,6 +113,11 @@ txpower_ctrl_policy[NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL] = { +@@ -114,6 +114,11 @@ txpower_ctrl_policy[NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL] = { [MTK_VENDOR_ATTR_TXPOWER_CTRL_BCN_DUP] = { .type = NLA_U8 }, }; @@ -70,7 +70,7 @@ index 566fec0..6154d1a 100644 struct csi_null_tone { u8 start; u8 end; -@@ -1399,6 +1404,30 @@ static int mt7915_vendor_txpower_ctrl(struct wiphy *wiphy, +@@ -1535,6 +1540,30 @@ static int mt7915_vendor_txpower_ctrl(struct wiphy *wiphy, return 0; } @@ -101,7 +101,7 @@ index 566fec0..6154d1a 100644 static const struct wiphy_vendor_command mt7915_vendor_commands[] = { { .info = { -@@ -1526,7 +1555,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { +@@ -1662,7 +1691,18 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = { .doit = mt7915_vendor_txpower_ctrl, .policy = txpower_ctrl_policy, .maxattr = MTK_VENDOR_ATTR_TXPOWER_CTRL_MAX, @@ -122,7 +122,7 @@ index 566fec0..6154d1a 100644 void mt7915_vendor_register(struct mt7915_phy *phy) diff --git a/mt7915/vendor.h b/mt7915/vendor.h -index 5b8a1fb..661d636 100644 +index 3040007f..bcde5d3c 100644 --- a/mt7915/vendor.h +++ b/mt7915/vendor.h @@ -16,6 +16,7 @@ enum mtk_nl80211_vendor_subcmds { @@ -133,7 +133,7 @@ index 5b8a1fb..661d636 100644 MTK_NL80211_VENDOR_SUBCMD_TXPOWER_CTRL = 0xce, }; -@@ -289,4 +290,15 @@ enum mtk_vendor_attr_txpower_ctrl { +@@ -302,4 +303,15 @@ enum mtk_vendor_attr_txpower_ctrl { NUM_MTK_VENDOR_ATTRS_TXPOWER_CTRL - 1 }; diff --git a/feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch b/feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch similarity index 96% rename from feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch rename to feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch index 65882778c..495efa199 100644 --- a/feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch +++ b/feeds/mediatek-sdk/mt76/patches/1045-wifi-mt76-mt7915-support-spatial-reuse-debug-command.patch @@ -1,7 +1,7 @@ -From 3a8ffe4b10bd9949dcd689406d5378a1b93c201d Mon Sep 17 00:00:00 2001 +From 40e0945208ca6569cc032b59f935223b8fac19f4 Mon Sep 17 00:00:00 2001 From: Howard Hsu Date: Thu, 15 Feb 2024 11:16:16 +0800 -Subject: [PATCH 1046/1053] wifi: mt76: mt7915: support spatial reuse debug +Subject: [PATCH 1045/1052] wifi: mt76: mt7915: support spatial reuse debug commands Support 3 spatial reuse debug commands: @@ -19,10 +19,10 @@ Signed-off-by: Howard Hsu 5 files changed, 191 insertions(+), 4 deletions(-) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index c96621f..dc60e35 100644 +index 3148526a..d8b001f1 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1031,6 +1031,7 @@ enum { +@@ -1032,6 +1032,7 @@ enum { MCU_EXT_EVENT_WA_TX_STAT = 0x74, MCU_EXT_EVENT_BCC_NOTIFY = 0x75, MCU_EXT_EVENT_MURU_CTRL = 0x9f, @@ -31,7 +31,7 @@ index c96621f..dc60e35 100644 }; diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index ddb738c..b3faf77 100644 +index b1cb7747..e505664e 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -452,6 +452,91 @@ mt7915_mcu_rx_bss_acq_pkt_cnt(struct mt7915_dev *dev, struct sk_buff * skb) @@ -158,7 +158,7 @@ index ddb738c..b3faf77 100644 return 0; diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 742a785..f476767 100644 +index 742a7855..f4767671 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -42,6 +42,45 @@ struct mt7915_mcu_thermal_notify { @@ -233,10 +233,10 @@ index 742a785..f476767 100644 THERMAL_PROTECT_PARAMETER_CTRL, THERMAL_PROTECT_BASIC_INFO, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 34f1a35..47f7d16 100644 +index 8b2e360e..10d48495 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -354,6 +354,9 @@ struct mt7915_phy { +@@ -371,6 +371,9 @@ struct mt7915_phy { struct mt7915_air_monitor_ctrl amnt_ctrl; #endif struct mt7915_scs_ctrl scs_ctrl; @@ -247,7 +247,7 @@ index 34f1a35..47f7d16 100644 #ifdef MTK_DEBUG diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index d3d3b17..78ac4e5 100644 +index 3291aafc..c8dd569c 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -3809,16 +3809,34 @@ mt7915_sw_aci_set(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-try-more-times-when-send-message-timeout.patch b/feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-try-more-times-when-send-message-timeout.patch similarity index 90% rename from feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-try-more-times-when-send-message-timeout.patch rename to feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-try-more-times-when-send-message-timeout.patch index ed1ac982f..cec5940f4 100644 --- a/feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-try-more-times-when-send-message-timeout.patch +++ b/feeds/mediatek-sdk/mt76/patches/1046-wifi-mt76-try-more-times-when-send-message-timeout.patch @@ -1,10 +1,9 @@ -From b0e4d25607d3a52f93139919c85482f87087f145 Mon Sep 17 00:00:00 2001 +From 73508da4263fcc10cd059fd89ef4017f9725324d Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Thu, 7 Mar 2024 11:13:45 +0800 -Subject: [PATCH 1047/1053] wifi: mt76: try more times when send message +Subject: [PATCH 1046/1052] wifi: mt76: try more times when send message timeout. -CR-Id: WCNCR00334773 Signed-off-by: Bo Jiao --- dma.c | 7 ++++-- @@ -13,7 +12,7 @@ Signed-off-by: Bo Jiao 3 files changed, 64 insertions(+), 52 deletions(-) diff --git a/dma.c b/dma.c -index bc8afcf..133a50d 100644 +index bc8afcff..133a50dc 100644 --- a/dma.c +++ b/dma.c @@ -504,9 +504,12 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, @@ -40,7 +39,7 @@ index bc8afcf..133a50d 100644 static int diff --git a/mcu.c b/mcu.c -index fa4b054..de185cc 100644 +index fa4b0544..de185cc9 100644 --- a/mcu.c +++ b/mcu.c @@ -4,6 +4,7 @@ @@ -133,10 +132,10 @@ index fa4b054..de185cc 100644 return ret; diff --git a/mt7915/mac.c b/mt7915/mac.c -index 2e4a8f8..dbc1095 100644 +index fb989405..b3c91633 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1389,12 +1389,6 @@ mt7915_mac_restart(struct mt7915_dev *dev) +@@ -1348,12 +1348,6 @@ mt7915_mac_restart(struct mt7915_dev *dev) } } @@ -149,7 +148,7 @@ index 2e4a8f8..dbc1095 100644 /* lock/unlock all queues to ensure that no tx is pending */ mt76_txq_schedule_all(&dev->mphy); if (ext_phy) -@@ -1495,11 +1489,18 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) +@@ -1454,11 +1448,18 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) dev->recovery.hw_full_reset = true; @@ -169,7 +168,7 @@ index 2e4a8f8..dbc1095 100644 cancel_delayed_work_sync(&dev->mphy.mac_work); if (ext_phy) cancel_delayed_work_sync(&ext_phy->mac_work); -@@ -1587,20 +1588,15 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1546,20 +1547,15 @@ void mt7915_mac_reset_work(struct work_struct *work) set_bit(MT76_RESET, &dev->mphy.state); set_bit(MT76_MCU_RESET, &dev->mphy.state); @@ -193,7 +192,7 @@ index 2e4a8f8..dbc1095 100644 if (mtk_wed_device_active(&dev->mt76.mmio.wed)) mtk_wed_device_stop(&dev->mt76.mmio.wed); -@@ -1624,8 +1620,8 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1583,8 +1579,8 @@ void mt7915_mac_reset_work(struct work_struct *work) clear_bit(MT76_MCU_RESET, &dev->mphy.state); clear_bit(MT76_RESET, &dev->mphy.state); @@ -204,7 +203,7 @@ index 2e4a8f8..dbc1095 100644 local_bh_disable(); mt76_for_each_q_rx(&dev->mt76, i) { -@@ -1647,21 +1643,8 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1606,21 +1602,8 @@ void mt7915_mac_reset_work(struct work_struct *work) if (ext_phy) ieee80211_wake_queues(ext_phy->hw); diff --git a/feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-SER-overlap-handle.patch b/feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-mt7915-add-SER-overlap-handle.patch similarity index 88% rename from feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-SER-overlap-handle.patch rename to feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-mt7915-add-SER-overlap-handle.patch index 28a07af25..d7f724471 100644 --- a/feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-SER-overlap-handle.patch +++ b/feeds/mediatek-sdk/mt76/patches/1047-wifi-mt76-mt7915-add-SER-overlap-handle.patch @@ -1,9 +1,8 @@ -From 6b84e5955fac1b324c5ad7bf2ea585e6531697a7 Mon Sep 17 00:00:00 2001 +From 1b93f1495d5f28a7620add2ebea0f691ff6e8a0d Mon Sep 17 00:00:00 2001 From: Bo Jiao Date: Tue, 6 Feb 2024 14:46:59 +0800 -Subject: [PATCH 1048/1053] wifi: mt76: mt7915: add SER overlap handle +Subject: [PATCH 1047/1052] wifi: mt76: mt7915: add SER overlap handle -CR-ID: WCNCR00355921 Signed-off-by: Bo Jiao --- dma.c | 3 ++- @@ -14,7 +13,7 @@ Signed-off-by: Bo Jiao 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/dma.c b/dma.c -index 133a50d..100d2af 100644 +index 133a50dc..100d2aff 100644 --- a/dma.c +++ b/dma.c @@ -506,7 +506,8 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q, @@ -28,7 +27,7 @@ index 133a50d..100d2af 100644 goto error; } diff --git a/mcu.c b/mcu.c -index de185cc..1bc94e8 100644 +index de185cc9..1bc94e85 100644 --- a/mcu.c +++ b/mcu.c @@ -42,7 +42,9 @@ struct sk_buff *mt76_mcu_get_response(struct mt76_dev *dev, @@ -53,7 +52,7 @@ index de185cc..1bc94e8 100644 dev_err(dev->dev, "send message %08x timeout, try again(%d).\n", cmd, (MT76_MSG_MAX_RETRY_CNT - retry_cnt)); diff --git a/mt76.h b/mt76.h -index b023f38..fb50d88 100644 +index a18b3e57..49ddaade 100644 --- a/mt76.h +++ b/mt76.h @@ -478,6 +478,14 @@ enum { @@ -80,10 +79,10 @@ index b023f38..fb50d88 100644 u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; diff --git a/mt7915/mac.c b/mt7915/mac.c -index dbc1095..e9f50a3 100644 +index b3c91633..c84b9573 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c -@@ -1579,6 +1579,7 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1538,6 +1538,7 @@ void mt7915_mac_reset_work(struct work_struct *work) if (!(READ_ONCE(dev->recovery.state) & MT_MCU_CMD_STOP_DMA)) return; @@ -91,7 +90,7 @@ index dbc1095..e9f50a3 100644 dev_info(dev->mt76.dev,"\n%s L1 SER recovery start.", wiphy_name(dev->mt76.hw->wiphy)); -@@ -1645,6 +1646,7 @@ void mt7915_mac_reset_work(struct work_struct *work) +@@ -1604,6 +1605,7 @@ void mt7915_mac_reset_work(struct work_struct *work) mt7915_update_beacons(dev); @@ -99,7 +98,7 @@ index dbc1095..e9f50a3 100644 dev_info(dev->mt76.dev,"\n%s L1 SER recovery completed.", wiphy_name(dev->mt76.hw->wiphy)); } -@@ -1783,6 +1785,15 @@ void mt7915_reset(struct mt7915_dev *dev) +@@ -1742,6 +1744,15 @@ void mt7915_reset(struct mt7915_dev *dev) return; } @@ -116,7 +115,7 @@ index dbc1095..e9f50a3 100644 wake_up(&dev->reset_wait); } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index b3faf77..f71688e 100644 +index e505664e..272db06a 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -198,6 +198,13 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, diff --git a/feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch b/feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch similarity index 58% rename from feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch rename to feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch index bfd88aa25..e9c86630c 100644 --- a/feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch +++ b/feeds/mediatek-sdk/mt76/patches/1048-wifi-mt76-mt7915-add-background-radar-hw-cap-check.patch @@ -1,25 +1,26 @@ -From 016069539c9436262f37516462e9396e6f63b550 Mon Sep 17 00:00:00 2001 +From ae7cf2b772c6f4f9e151f7a60b3cf726780f03ae Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Mon, 4 Mar 2024 11:29:06 +0800 -Subject: [PATCH 1049/1053] wifi: mt76: mt7915: add background radar hw cap - check +Subject: [PATCH] wifi: mt76: mt7915: add background radar hw cap check Signed-off-by: StanleyYP Wang --- mt7915/debugfs.c | 5 +++++ - mt7915/eeprom.h | 30 ++++++++++++++++++++++++++++++ + mt7915/eeprom.c | 29 +++++++++++++++++++++++++++++ + mt7915/eeprom.h | 1 + mt7915/init.c | 7 ++++--- - 3 files changed, 39 insertions(+), 3 deletions(-) + mt7915/mt7915.h | 1 + + 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index b2a4ff4..03daf44 100644 +index f031b54..d26816a 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -459,6 +459,11 @@ mt7915_rdd_monitor(struct seq_file *s, void *data) mutex_lock(&dev->mt76.mutex); -+ if (!mt7915_get_background_radar_cap(dev)) { ++ if (!mt7915_eeprom_has_background_radar(dev)) { + seq_puts(s, "no background radar capability\n"); + goto out; + } @@ -27,31 +28,23 @@ index b2a4ff4..03daf44 100644 if (!cfg80211_chandef_valid(chandef)) { ret = -EINVAL; goto out; -diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h -index 70fca0b..adeee10 100644 ---- a/mt7915/eeprom.h -+++ b/mt7915/eeprom.h -@@ -55,6 +55,7 @@ enum mt7915_eeprom_field { - #define MT_EE_CAL_DPD_SIZE_V2_7981 (102 * MT_EE_CAL_UNIT) /* no 6g dpd data */ - - #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0) -+#define MT_EE_WIFI_CONF0_RX_PATH GENMASK(5, 3) - #define MT_EE_WIFI_CONF0_BAND_SEL GENMASK(7, 6) - #define MT_EE_WIFI_CONF1_BAND_SEL GENMASK(7, 6) - #define MT_EE_WIFI_CONF_STREAM_NUM GENMASK(7, 5) -@@ -206,6 +207,35 @@ mt7915_get_cal_dpd_size(struct mt7915_dev *dev) - return MT_EE_CAL_DPD_SIZE_V2; +diff --git a/mt7915/eeprom.c b/mt7915/eeprom.c +index df5e396..6a910b0 100644 +--- a/mt7915/eeprom.c ++++ b/mt7915/eeprom.c +@@ -618,6 +618,35 @@ s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band) + return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta; } -+static inline bool -+mt7915_get_background_radar_cap(struct mt7915_dev *dev) ++bool ++mt7915_eeprom_has_background_radar(struct mt7915_dev *dev) +{ + u8 buf[MT7915_EEPROM_BLOCK_SIZE]; + int val, band_sel, tx_path, rx_path, offs = MT_EE_WIFI_CONF + 1; + + switch (mt76_chip(&dev->mt76)) { + case 0x7915: -+ return 1; ++ return true; + case 0x7906: + if (!mt7915_mcu_get_eeprom(dev, offs, buf)) { + val = buf[offs % MT7915_EEPROM_BLOCK_SIZE]; @@ -69,30 +62,54 @@ index 70fca0b..adeee10 100644 + break; + } + -+ return 0; ++ return false; +} + - extern const u8 mt7915_sku_group_len[MAX_SKU_RATE_GROUP_NUM]; + const u8 mt7915_sku_group_len[] = { + [SKU_CCK] = 4, + [SKU_OFDM] = 8, +diff --git a/mt7915/eeprom.h b/mt7915/eeprom.h +index 70fca0b..22df5a9 100644 +--- a/mt7915/eeprom.h ++++ b/mt7915/eeprom.h +@@ -55,6 +55,7 @@ enum mt7915_eeprom_field { + #define MT_EE_CAL_DPD_SIZE_V2_7981 (102 * MT_EE_CAL_UNIT) /* no 6g dpd data */ - #endif + #define MT_EE_WIFI_CONF0_TX_PATH GENMASK(2, 0) ++#define MT_EE_WIFI_CONF0_RX_PATH GENMASK(5, 3) + #define MT_EE_WIFI_CONF0_BAND_SEL GENMASK(7, 6) + #define MT_EE_WIFI_CONF1_BAND_SEL GENMASK(7, 6) + #define MT_EE_WIFI_CONF_STREAM_NUM GENMASK(7, 5) diff --git a/mt7915/init.c b/mt7915/init.c -index b53075b..26ae63f 100644 +index ec26909..813aa43 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -404,9 +404,10 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -405,9 +405,10 @@ mt7915_init_wiphy(struct mt7915_phy *phy) if (!is_mt7915(&dev->mt76)) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); - if (!mdev->dev->of_node || - !of_property_read_bool(mdev->dev->of_node, - "mediatek,disable-radar-background")) -+ if (mt7915_get_background_radar_cap(phy->dev) && ++ if (mt7915_eeprom_has_background_radar(phy->dev) && + (!mdev->dev->of_node || + !of_property_read_bool(mdev->dev->of_node, + "mediatek,disable-radar-background"))) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RADAR_BACKGROUND); +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index 2351c1f..b5a39d7 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -618,6 +618,7 @@ int mt7915_eeprom_get_target_power(struct mt7915_dev *dev, + struct ieee80211_channel *chan, + u8 chain_idx); + s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band); ++bool mt7915_eeprom_has_background_radar(struct mt7915_dev *dev); + int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2); + void mt7915_dma_prefetch(struct mt7915_dev *dev); + void mt7915_dma_cleanup(struct mt7915_dev *dev); -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch b/feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch similarity index 85% rename from feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch rename to feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch index 5c966ecdf..e6265355a 100644 --- a/feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch +++ b/feeds/mediatek-sdk/mt76/patches/1049-wifi-mt76-mt7915-add-foolproof-mechanism-for-ZWDFS-d.patch @@ -1,7 +1,7 @@ -From 25eef0359cbdfb1a1e7730da256ac35a943242ea Mon Sep 17 00:00:00 2001 +From 7f45a6881d88e92180fe2b162800b8334d005a5f Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Wed, 6 Mar 2024 11:30:34 +0800 -Subject: [PATCH 1051/1053] wifi: mt76: mt7915: add foolproof mechanism for +Subject: [PATCH 1049/1052] wifi: mt76: mt7915: add foolproof mechanism for ZWDFS during radar detected & triggered Signed-off-by: StanleyYP Wang @@ -11,7 +11,7 @@ Signed-off-by: StanleyYP Wang 2 files changed, 8 insertions(+) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 03daf44..d8ca90a 100644 +index 3fd1654c..522e2999 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -231,6 +231,11 @@ mt7915_radar_trigger(void *data, u64 val) @@ -27,7 +27,7 @@ index 03daf44..d8ca90a 100644 val, 0, 0); } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index f71688e..d857658 100644 +index 272db06a..250b05ec 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -302,6 +302,9 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb) diff --git a/feeds/mediatek-sdk/mt76/patches/1052-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch b/feeds/mediatek-sdk/mt76/patches/1050-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch similarity index 85% rename from feeds/mediatek-sdk/mt76/patches/1052-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch rename to feeds/mediatek-sdk/mt76/patches/1050-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch index 8f766d065..05e22ba47 100644 --- a/feeds/mediatek-sdk/mt76/patches/1052-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch +++ b/feeds/mediatek-sdk/mt76/patches/1050-mtk-wifi-mt76-mt7915-assign-DEAUTH-to-ALTX-queue-for.patch @@ -1,7 +1,7 @@ -From 93810a9bad2fd59c8e4742195a3b5c53878116ef Mon Sep 17 00:00:00 2001 +From 2ed70c162a13b4b4af3bfc7a806e8cfab29126f7 Mon Sep 17 00:00:00 2001 From: Michael-CY Lee Date: Tue, 19 Mar 2024 08:35:26 +0800 -Subject: [PATCH 1052/1053] mtk: wifi: mt76: mt7915: assign DEAUTH to ALTX +Subject: [PATCH 1050/1052] mtk: wifi: mt76: mt7915: assign DEAUTH to ALTX queue for CERT Signed-off-by: Michael-CY Lee @@ -10,7 +10,7 @@ Signed-off-by: Michael-CY Lee 1 file changed, 10 insertions(+) diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index d41f004..0510296 100644 +index d1708152..21dadb55 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c @@ -385,6 +385,8 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, @@ -22,7 +22,7 @@ index d41f004..0510296 100644 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -@@ -394,6 +396,14 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, +@@ -395,6 +397,14 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, u8 fc_type, fc_stype; u32 val; diff --git a/feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch b/feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch similarity index 86% rename from feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch rename to feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch index e9c88e1a0..eabad848e 100644 --- a/feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch +++ b/feeds/mediatek-sdk/mt76/patches/1051-wifi-mt76-mt7915-set-channel-after-sta-is-associated.patch @@ -1,7 +1,7 @@ -From 124ffa4206375bcbcb8bfaa0032045e3063ad286 Mon Sep 17 00:00:00 2001 +From 1d18008ab9d67f318932ed993103bd46d9f0215d Mon Sep 17 00:00:00 2001 From: StanleyYP Wang Date: Thu, 21 Mar 2024 16:52:34 +0800 -Subject: [PATCH 1053/1053] wifi: mt76: mt7915: set channel after sta is +Subject: [PATCH 1051/1052] wifi: mt76: mt7915: set channel after sta is associated to adjust switch reason when sta is associated to AP operating in DFS channel, a channel @@ -16,10 +16,10 @@ Signed-off-by: StanleyYP Wang 1 file changed, 26 insertions(+) diff --git a/mt7915/main.c b/mt7915/main.c -index 69fcf4c..41fa450 100644 +index 04301300..eab45737 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -792,6 +792,31 @@ out: +@@ -794,6 +794,31 @@ out: return ret; } @@ -51,7 +51,7 @@ index 69fcf4c..41fa450 100644 int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { -@@ -1771,6 +1796,7 @@ const struct ieee80211_ops mt7915_ops = { +@@ -1835,6 +1860,7 @@ const struct ieee80211_ops mt7915_ops = { .set_sar_specs = mt7915_set_sar_specs, .channel_switch_beacon = mt7915_channel_switch_beacon, .post_channel_switch = mt7915_post_channel_switch, diff --git a/feeds/mediatek-sdk/mt76/patches/1052-wifi-mt76-mt7915-Clear-private-driver-data-in-case-o.patch b/feeds/mediatek-sdk/mt76/patches/1052-wifi-mt76-mt7915-Clear-private-driver-data-in-case-o.patch new file mode 100644 index 000000000..8e444e132 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1052-wifi-mt76-mt7915-Clear-private-driver-data-in-case-o.patch @@ -0,0 +1,28 @@ +From 3b8af1b07109458e7274bc032b27c3c2e331acb3 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Fri, 5 Jul 2024 17:50:29 +0800 +Subject: [PATCH] wifi: mt76: mt7915: Clear private driver data in case of + reuse + +Signed-off-by: Rex Lu +--- + mt7915/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/mt7915/main.c b/mt7915/main.c +index f9ce1ba7..d5ea85d6 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -230,6 +230,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e + bool ext_phy = phy != &dev->phy; + int idx, i, ret = 0; + ++ /* Clear private driver data in case of reuse */ ++ memset(mvif, 0, sizeof(struct mt7915_vif)); ++ + /* To differentiate the mac address of TXD and TXCMD interface */ + vif->addr[0] |= bf_en; + +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch b/feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch new file mode 100644 index 000000000..33b48fff4 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1053-wifi-mt76-mt7915-fix-TX-RX-hang-without-SER-hw-bit-t.patch @@ -0,0 +1,132 @@ +From ef27c50654dd962bd941a1e0ddd4181dd6473cc4 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Thu, 12 Sep 2024 16:17:51 +0800 +Subject: [PATCH] wifi: mt76: mt7915: fix TX/RX hang without SER hw bit to do + L1 recovery issue + +--- + mcu.c | 4 +++- + mt76.h | 2 +- + mt76_connac_mcu.c | 18 +++++++++++++++++- + mt7915/mcu.c | 10 +++++++++- + mt7915/regs.h | 2 +- + 5 files changed, 31 insertions(+), 5 deletions(-) + +diff --git a/mcu.c b/mcu.c +index 1bc94e8..d331d81 100644 +--- a/mcu.c ++++ b/mcu.c +@@ -82,6 +82,7 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, + int ret, seq, retry_cnt; + struct sk_buff *skb_tmp; + bool retry = wait_resp && is_connac_v2(dev); ++ bool force_ser = false; + + if (ret_skb) + *ret_skb = NULL; +@@ -99,9 +100,10 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, + usleep_range(200000, 500000); + dev_err(dev->dev, "send message %08x timeout, try again(%d).\n", + cmd, (MT76_MSG_MAX_RETRY_CNT - retry_cnt)); ++ force_ser = true; + } + +- ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq); ++ ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb_tmp, cmd, &seq, force_ser); + if (ret < 0 && ret != -EAGAIN) + goto out; + +diff --git a/mt76.h b/mt76.h +index fd59fdf..dbf0fba 100644 +--- a/mt76.h ++++ b/mt76.h +@@ -245,7 +245,7 @@ struct mt76_mcu_ops { + int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data, + int len, bool wait_resp); + int (*mcu_skb_send_msg)(struct mt76_dev *dev, struct sk_buff *skb, +- int cmd, int *seq); ++ int cmd, int *seq, bool force_ser); + int (*mcu_parse_response)(struct mt76_dev *dev, int cmd, + struct sk_buff *skb, int seq); + u32 (*mcu_rr)(struct mt76_dev *dev, u32 offset); +diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c +index 0ce7ecd..b6c61b4 100644 +--- a/mt76_connac_mcu.c ++++ b/mt76_connac_mcu.c +@@ -3065,6 +3065,22 @@ out: + } + EXPORT_SYMBOL_GPL(mt76_connac2_load_patch); + ++static int mt76_connac2_mcu_timeout_value(int cmd) ++{ ++ u8 ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd); ++ int timeout = 3 * HZ; ++ ++ switch (ext_cid) { ++ case MCU_EXT_CMD_EFUSE_BUFFER_MODE: ++ timeout = 20 * HZ; ++ break; ++ default: ++ break; ++ } ++ ++ return timeout; ++} ++ + int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb, + int cmd, int *wait_seq) + { +@@ -3076,7 +3092,7 @@ int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb, + u8 seq; + + /* TODO: make dynamic based on msg type */ +- dev->mcu.timeout = 20 * HZ; ++ dev->mcu.timeout = mt76_connac2_mcu_timeout_value(cmd); + + seq = ++dev->mcu.msg_seq & 0xf; + if (!seq) +diff --git a/mt7915/mcu.c b/mt7915/mcu.c +index 250b05e..bd32b0a 100644 +--- a/mt7915/mcu.c ++++ b/mt7915/mcu.c +@@ -192,7 +192,7 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd, + + static int + mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, +- int cmd, int *wait_seq) ++ int cmd, int *wait_seq, bool force_ser) + { + struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76); + enum mt76_mcuq_id qid; +@@ -205,6 +205,14 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, + return -EPERM; + } + ++ if (force_ser && mdev->recovery_state == MT76_RECOVERY_INIT) { ++ dev_info(dev->mt76.dev,"\n%s TX/RX hang force trigger L1 SER recovery, drop message %08x.", ++ wiphy_name(dev->mt76.hw->wiphy), cmd); ++ mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_SER_TRIGGER); ++ dev_kfree_skb(skb); ++ return -EPERM; ++ } ++ + ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, wait_seq); + + if (ret) +diff --git a/mt7915/regs.h b/mt7915/regs.h +index ca355d1..24778d3 100644 +--- a/mt7915/regs.h ++++ b/mt7915/regs.h +@@ -141,8 +141,8 @@ enum offs_rev { + #define MT_MCU_INT_EVENT __REG(INT_MCU_CMD_EVENT) + #define MT_MCU_INT_EVENT_DMA_STOPPED BIT(0) + #define MT_MCU_INT_EVENT_DMA_INIT BIT(1) +-#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(2) + #define MT_MCU_INT_EVENT_RESET_DONE BIT(3) ++#define MT_MCU_INT_EVENT_SER_TRIGGER BIT(4) + + /* PLE */ + #define MT_PLE_BASE 0x820c0000 +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/1054-wifi-mt76-mt7915-remove-rts-and-cts-protection-enabl.patch b/feeds/mediatek-sdk/mt76/patches/1054-wifi-mt76-mt7915-remove-rts-and-cts-protection-enabl.patch new file mode 100644 index 000000000..6bb523985 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1054-wifi-mt76-mt7915-remove-rts-and-cts-protection-enabl.patch @@ -0,0 +1,65 @@ +From 01a42eca7e7ac3362e4108efc4d9b1938ff4c5ee Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Wed, 16 Oct 2024 13:48:03 +0800 +Subject: [PATCH] wifi: mt76: mt7915: remove rts and cts protection enable flow + +--- + mt7915/mac.c | 13 ------------- + mt7915/main.c | 3 --- + mt7915/mt7915.h | 2 -- + 3 files changed, 18 deletions(-) + +diff --git a/mt7915/mac.c b/mt7915/mac.c +index 677c339..b4f115e 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -216,19 +216,6 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev) + rcu_read_unlock(); + } + +-void mt7915_mac_enable_rtscts(struct mt7915_dev *dev, +- struct ieee80211_vif *vif, bool enable) +-{ +- struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; +- u32 addr; +- +- addr = mt7915_mac_wtbl_lmac_addr(dev, mvif->sta.wcid.idx, 5); +- if (enable) +- mt76_set(dev, addr, BIT(5)); +- else +- mt76_clear(dev, addr, BIT(5)); +-} +- + static void + mt7915_wed_check_ppe(struct mt7915_dev *dev, struct mt76_queue *q, + struct mt7915_sta *msta, struct sk_buff *skb, +diff --git a/mt7915/main.c b/mt7915/main.c +index d5ea85d..ea427d1 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -681,9 +681,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, + if (set_sta == 1) + mt7915_mcu_add_sta(dev, vif, NULL, true); + +- if (changed & BSS_CHANGED_ERP_CTS_PROT) +- mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot); +- + if (changed & BSS_CHANGED_ERP_SLOT) { + int slottime = info->use_short_slot ? 9 : 20; + +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index 7c185a1..01d8552 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -760,8 +760,6 @@ bool mt7915_mac_wtbl_update(struct mt7915_dev *dev, int idx, u32 mask); + void mt7915_mac_reset_counters(struct mt7915_phy *phy); + void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy); + void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy); +-void mt7915_mac_enable_rtscts(struct mt7915_dev *dev, +- struct ieee80211_vif *vif, bool enable); + void mt7915_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, + struct sk_buff *skb, struct mt76_wcid *wcid, int pid, + struct ieee80211_key_conf *key, +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/1055-wifi-mt76-testmode-add-interface-addition-deletion-c.patch b/feeds/mediatek-sdk/mt76/patches/1055-wifi-mt76-testmode-add-interface-addition-deletion-c.patch new file mode 100644 index 000000000..a33863aaf --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1055-wifi-mt76-testmode-add-interface-addition-deletion-c.patch @@ -0,0 +1,180 @@ +From b4f66803c2096c386411bc4a211b4b56fb4496d2 Mon Sep 17 00:00:00 2001 +From: StanleyYP Wang +Date: Fri, 18 Oct 2024 09:43:43 +0800 +Subject: [PATCH] wifi: mt76: testmode: add interface addition/deletion command + in mt76-test + +Add mt76-test phyX add/del command to align Wi-Fi 7 codebase + +CR-Id: WCNCR00274293 +Signed-off-by: StanleyYP Wang +--- + tools/main.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 124 insertions(+) + +diff --git a/tools/main.c b/tools/main.c +index 699a9ee..76b87c8 100644 +--- a/tools/main.c ++++ b/tools/main.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + #include "mt76-test.h" + + struct unl unl; +@@ -25,6 +26,7 @@ static int phy_lookup_idx(const char *name) + FILE *f; + int len; + ++ /* TODO: Handle single wiphy radio index */ + snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name); + f = fopen(buf, "r"); + if (!f) +@@ -43,6 +45,8 @@ static int phy_lookup_idx(const char *name) + void usage(void) + { + static const char *const commands[] = { ++ "add ", ++ "del ", + "set = [...]", + "dump [stats]", + "eeprom file", +@@ -164,6 +168,122 @@ static int mt76_set(int phy, int argc, char **argv) + return ret; + } + ++static int mt76_set_state(int phy, char *state) ++{ ++ const struct tm_field *fields = msg_field.fields; ++ struct nl_msg *msg; ++ void *data; ++ int ret, i; ++ ++ msg = unl_genl_msg(&unl, NL80211_CMD_TESTMODE, false); ++ nla_put_u32(msg, NL80211_ATTR_WIPHY, phy); ++ ++ data = nla_nest_start(msg, NL80211_ATTR_TESTDATA); ++ for (i = 0; i < msg_field.len; i++) { ++ if (!fields[i].parse) ++ continue; ++ ++ if (!strcmp(fields[i].name, "state")) ++ break; ++ } ++ ++ if (!fields[i].parse(&fields[i], i, msg, state)) ++ return 1; ++ ++ tm_set_changed(i); ++ nla_nest_end(msg, data); ++ ++ ret = unl_genl_request(&unl, msg, NULL, NULL); ++ if (ret) ++ fprintf(stderr, "Failed to turn off testmode: %s\n", strerror(-ret)); ++ ++ return ret; ++} ++ ++static void mt76_set_tm_reg(void) ++{ ++ struct nl_msg *msg; ++ char reg[3] = "VV\0"; ++ int ret; ++ ++ msg = unl_genl_msg(&unl, NL80211_CMD_REQ_SET_REG, false); ++ nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, reg); ++ ++ ret = unl_genl_request(&unl, msg, NULL, NULL); ++ if (ret) ++ fprintf(stderr, "Failed to set reg %s: %s\n", reg, strerror(-ret)); ++} ++ ++static int mt76_add_iface(int phy, int argc, char **argv) ++{ ++ struct nl_msg *msg; ++ char *name, cmd[64]; ++ int ret; ++ ++ mt76_set_tm_reg(); ++ ++ if (argc < 1) ++ return 1; ++ ++ name = argv[0]; ++ msg = unl_genl_msg(&unl, NL80211_CMD_NEW_INTERFACE, false); ++ /* TODO: Handle single wiphy radio index */ ++ nla_put_u32(msg, NL80211_ATTR_WIPHY, phy); ++ nla_put_u32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); ++ nla_put_string(msg, NL80211_ATTR_IFNAME, name); ++ ++ ret = unl_genl_request(&unl, msg, NULL, NULL); ++ if (ret) { ++ fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret)); ++ return ret; ++ } ++ ++ sprintf(cmd, "ifconfig %s up", name); ++ system(cmd); ++ ++ /* turn on testmode */ ++ ret = mt76_set_state(phy, "idle"); ++ return ret; ++} ++ ++static int mt76_delete_iface(int phy, int argc, char **argv) ++{ ++ unsigned int devidx; ++ struct nl_msg *msg; ++ char *name, cmd[64]; ++ int ret; ++ ++ if (argc < 1) ++ return 1; ++ ++ name = argv[0]; ++ devidx = if_nametoindex(name); ++ if (!devidx) { ++ fprintf(stderr, "Failed to find ifindex for %s: %s\n", ++ name, strerror(errno)); ++ return 2; ++ } ++ ++ /* turn off testmode before deleting interface */ ++ ret = mt76_set_state(phy, "off"); ++ if (ret) ++ return ret; ++ ++ sprintf(cmd, "ifconfig %s down", name); ++ system(cmd); ++ ++ /* delete interface */ ++ msg = unl_genl_msg(&unl, NL80211_CMD_DEL_INTERFACE, false); ++ nla_put_u32(msg, NL80211_ATTR_WIPHY, phy); ++ nla_put_u32(msg, NL80211_ATTR_IFINDEX, devidx); ++ ++ ret = unl_genl_request(&unl, msg, NULL, NULL); ++ if (ret) ++ fprintf(stderr, "nl80211 call failed: %s\n", strerror(-ret)); ++ ++ return ret; ++} ++ + int main(int argc, char **argv) + { + const char *cmd, *phyname; +@@ -194,6 +314,10 @@ int main(int argc, char **argv) + ret = mt76_dump(phy, argc, argv); + else if (!strcmp(cmd, "set")) + ret = mt76_set(phy, argc, argv); ++ else if (!strcmp(cmd, "add")) ++ ret = mt76_add_iface(phy, argc, argv); ++ else if (!strcmp(cmd, "del")) ++ ret = mt76_delete_iface(phy, argc, argv); + else if (!strcmp(cmd, "eeprom")) + ret = mt76_eeprom(phy, argc, argv); + else if (!strcmp(cmd, "fwlog")) +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-mt7915-rework-radar-rdd-idx.patch b/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-mt7915-rework-radar-rdd-idx.patch new file mode 100644 index 000000000..094bf18f1 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-mt7915-rework-radar-rdd-idx.patch @@ -0,0 +1,355 @@ +From 5cfa5da26a0d68168b9771a0b2777e26edcdb8f7 Mon Sep 17 00:00:00 2001 +From: StanleyYP Wang +Date: Mon, 3 Mar 2025 14:51:20 +0800 +Subject: [PATCH] wifi: mt76: mt7915: rework radar rdd idx + +The definition of MT_RX_SEL (for rdd_rx_sel) is mixed with the definition of HWRDD idx. +For example, MT_RX_SEL2 is for background HWRDD idx, not an option of rdd_rx_sel. +Therefore, add mt7915_get_rdd_idx as a helper function to get the HWRDD idx for each +variants. + +Additionally, remove some parts of the code inherited from the legacy chips. +For instance, +1. rdd_state is used for single-band-dual-HWRDD chips (for 80+80), +especially the 76xx series. +2. rdd_rx_sel is also used for single-band-dual-HWRDD chips +rx_sel = 0 => RDD0 for WF0, RDD1 for WF2 +rx_sel = 1 => RDD0 for WF1, RDD1 for WF3 + +Chip Variants | 5G HWRDD Index (= band idx) | Background HWRDD Index +-----------------------------------------|-----------------------------|------------------------ +MT7915A (single band, 2G or 5G) | 0 | 2 +MT7915D (DBDC 2G + 5G) | 1 | 2 +MT7916 2G + 5G (2T2R + ZWDFS) | 1 | 2 +MT7916 2G + 5G (3T3R) | 1 | N/A +MT7981 2G + 5G | 1 | N/A +MT7986 2G + 5G (one adie DBDC, AX4200) | 1 | N/A +MT7986 5G single band (one adie, AX7800) | 1(first band idx = MT_BAND1)| N/A +MT7986 2G + 5G (dual adie, AX6000) | 1 | N/A + +Signed-off-by: StanleyYP Wang +--- + mt7915/debugfs.c | 20 ++++++++++++---- + mt7915/mac.c | 60 +++++++++++++++++------------------------------- + mt7915/mcu.c | 41 +++++++++++++++++++++++---------- + mt7915/mcu.h | 2 +- + mt7915/mt7915.h | 22 +++++++++++++----- + 5 files changed, 82 insertions(+), 63 deletions(-) + +diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c +index 2043c77..fc7d0ee 100644 +--- a/mt7915/debugfs.c ++++ b/mt7915/debugfs.c +@@ -226,18 +226,28 @@ static const struct file_operations mt7915_sys_recovery_ops = { + static int + mt7915_radar_trigger(void *data, u64 val) + { +- struct mt7915_dev *dev = data; ++#define RADAR_MAIN_CHAIN 1 ++#define RADAR_BACKGROUND 2 ++ struct mt7915_phy *phy = data; ++ struct mt7915_dev *dev = phy->dev; ++ int rdd_idx; + +- if (val > MT_RX_SEL2) ++ if (!val || val > RADAR_BACKGROUND) + return -EINVAL; + +- if (val == MT_RX_SEL2 && !dev->rdd2_phy) { ++ if (val == RADAR_BACKGROUND && !dev->rdd2_phy) { + dev_err(dev->mt76.dev, "Background radar is not enabled\n"); + return -EINVAL; + } + ++ rdd_idx = mt7915_get_rdd_idx(phy, val == RADAR_BACKGROUND); ++ if (rdd_idx < 0) { ++ dev_err(dev->mt76.dev, "No RDD found\n"); ++ return -EINVAL; ++ } ++ + return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_RADAR_EMULATE, +- val, 0, 0); ++ rdd_idx, 0, 0); + } + + DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_trigger, NULL, +@@ -1575,7 +1585,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) + if (!dev->dbdc_support || phy->mt76->band_idx) { + debugfs_create_u32("dfs_hw_pattern", 0400, dir, + &dev->hw_pattern); +- debugfs_create_file("radar_trigger", 0200, dir, dev, ++ debugfs_create_file("radar_trigger", 0200, dir, phy, + &fops_radar_trigger); + debugfs_create_devm_seqfile(dev->mt76.dev, "rdd_monitor", dir, + mt7915_rdd_monitor); +diff --git a/mt7915/mac.c b/mt7915/mac.c +index cff604e..30f54d2 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -2127,16 +2127,15 @@ void mt7915_mac_work(struct work_struct *work) + static void mt7915_dfs_stop_radar_detector(struct mt7915_phy *phy) + { + struct mt7915_dev *dev = phy->dev; ++ int rdd_idx = mt7915_get_rdd_idx(phy, false); + +- if (phy->rdd_state & BIT(0)) +- mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, 0, +- MT_RX_SEL0, 0); +- if (phy->rdd_state & BIT(1)) +- mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, 1, +- MT_RX_SEL0, 0); ++ if (rdd_idx < 0) ++ return; ++ ++ mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, rdd_idx, 0, 0); + } + +-static int mt7915_dfs_start_rdd(struct mt7915_dev *dev, int chain) ++static int mt7915_dfs_start_rdd(struct mt7915_dev *dev, int rdd_idx) + { + int err, region; + +@@ -2153,52 +2152,38 @@ static int mt7915_dfs_start_rdd(struct mt7915_dev *dev, int chain) + break; + } + +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_START, chain, +- MT_RX_SEL0, region); ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_START, rdd_idx, 0, region); + if (err < 0) + return err; + + if (is_mt7915(&dev->mt76)) { +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_SET_WF_ANT, chain, ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_SET_WF_ANT, rdd_idx, + 0, dev->dbdc_support ? 2 : 0); + if (err < 0) + return err; + } + +- return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_DET_MODE, chain, +- MT_RX_SEL0, 1); ++ return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_DET_MODE, rdd_idx, 0, 1); + } + + static int mt7915_dfs_start_radar_detector(struct mt7915_phy *phy) + { +- struct cfg80211_chan_def *chandef = &phy->mt76->chandef; + struct mt7915_dev *dev = phy->dev; +- int err; ++ int err, rdd_idx; ++ ++ rdd_idx = mt7915_get_rdd_idx(phy, false); ++ if (rdd_idx < 0) ++ return -EINVAL; + + /* start CAC */ +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_CAC_START, +- phy->mt76->band_idx, MT_RX_SEL0, 0); ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_CAC_START, rdd_idx, 0, 0); + if (err < 0) + return err; + +- err = mt7915_dfs_start_rdd(dev, phy->mt76->band_idx); ++ err = mt7915_dfs_start_rdd(dev, rdd_idx); + if (err < 0) + return err; + +- phy->rdd_state |= BIT(phy->mt76->band_idx); +- +- if (!is_mt7915(&dev->mt76)) +- return 0; +- +- if (chandef->width == NL80211_CHAN_WIDTH_160 || +- chandef->width == NL80211_CHAN_WIDTH_80P80) { +- err = mt7915_dfs_start_rdd(dev, 1); +- if (err < 0) +- return err; +- +- phy->rdd_state |= BIT(1); +- } +- + return 0; + } + +@@ -2240,12 +2225,12 @@ int mt7915_dfs_init_radar_detector(struct mt7915_phy *phy) + { + struct mt7915_dev *dev = phy->dev; + enum mt76_dfs_state dfs_state, prev_state; +- int err; ++ int err, rdd_idx = mt7915_get_rdd_idx(phy, false); + + prev_state = phy->mt76->dfs_state; + dfs_state = mt76_phy_dfs_state(phy->mt76); + +- if (prev_state == dfs_state) ++ if (prev_state == dfs_state || rdd_idx < 0) + return 0; + + if (prev_state == MT_DFS_STATE_UNKNOWN) +@@ -2269,8 +2254,7 @@ int mt7915_dfs_init_radar_detector(struct mt7915_phy *phy) + if (dfs_state == MT_DFS_STATE_CAC) + return 0; + +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_CAC_END, +- phy->mt76->band_idx, MT_RX_SEL0, 0); ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_CAC_END, rdd_idx, 0, 0); + if (err < 0) { + phy->mt76->dfs_state = MT_DFS_STATE_UNKNOWN; + return err; +@@ -2280,15 +2264,13 @@ int mt7915_dfs_init_radar_detector(struct mt7915_phy *phy) + return 0; + + stop: +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_NORMAL_START, +- phy->mt76->band_idx, MT_RX_SEL0, 0); ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_NORMAL_START, rdd_idx, 0, 0); + if (err < 0) + return err; + + if (is_mt7915(&dev->mt76)) { + err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_SET_WF_ANT, +- phy->mt76->band_idx, 0, +- dev->dbdc_support ? 2 : 0); ++ rdd_idx, 0, dev->dbdc_support ? 2 : 0); + if (err < 0) + return err; + } +diff --git a/mt7915/mcu.c b/mt7915/mcu.c +index bd32b0a..993d390 100644 +--- a/mt7915/mcu.c ++++ b/mt7915/mcu.c +@@ -304,20 +304,35 @@ mt7915_mcu_rx_radar_detected(struct mt7915_dev *dev, struct sk_buff *skb) + { + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt7915_mcu_rdd_report *r; ++ u32 sku; + + r = (struct mt7915_mcu_rdd_report *)skb->data; + +- if (r->band_idx > MT_RX_SEL2) ++ switch (r->rdd_idx) { ++ case MT_RDD_IDX_BAND0: ++ break; ++ case MT_RDD_IDX_BAND1: ++ sku = mt7915_check_adie(dev, true); ++ /* the main phy is bound to band 1 for this sku */ ++ if (is_mt7986(&dev->mt76) && ++ (sku == MT7975_ONE_ADIE || sku == MT7976_ONE_ADIE)) ++ break; ++ mphy = dev->mt76.phys[MT_BAND1]; ++ break; ++ case MT_RDD_IDX_BACKGROUND: ++ if (!dev->rdd2_phy) ++ return; ++ mphy = dev->rdd2_phy->mt76; ++ break; ++ default: ++ dev_err(dev->mt76.dev, "Unknown RDD idx %d\n", r->rdd_idx); + return; ++ } + +- if (r->band_idx == MT_RX_SEL2 && !dev->rdd2_phy) ++ if (!mphy) + return; + +- if ((r->band_idx && !dev->phy.mt76->band_idx) && +- dev->mt76.phys[MT_BAND1]) +- mphy = dev->mt76.phys[MT_BAND1]; +- +- if (r->band_idx == MT_RX_SEL2) ++ if (r->rdd_idx == MT_RDD_IDX_BACKGROUND) + cfg80211_background_radar_event(mphy->hw->wiphy, + &dev->rdd2_chandef, + GFP_ATOMIC); +@@ -2907,11 +2922,14 @@ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, + struct cfg80211_chan_def *chandef) + { + struct mt7915_dev *dev = phy->dev; +- int err, region; ++ int err, region, rdd_idx; ++ ++ rdd_idx = mt7915_get_rdd_idx(phy, true); ++ if (rdd_idx < 0) ++ return -EINVAL; + + if (!chandef) { /* disable offchain */ +- err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, MT_RX_SEL2, +- 0, 0); ++ err = mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_STOP, rdd_idx, 0, 0); + if (err) + return err; + +@@ -2937,8 +2955,7 @@ int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, + break; + } + +- return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_START, MT_RX_SEL2, +- 0, region); ++ return mt76_connac_mcu_rdd_cmd(&dev->mt76, RDD_START, rdd_idx, 0, region); + } + + int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) +diff --git a/mt7915/mcu.h b/mt7915/mcu.h +index f476767..458263d 100644 +--- a/mt7915/mcu.h ++++ b/mt7915/mcu.h +@@ -102,7 +102,7 @@ struct mt7915_mcu_bcc_notify { + struct mt7915_mcu_rdd_report { + struct mt76_connac2_mcu_rxd rxd; + +- u8 band_idx; ++ u8 rdd_idx; + u8 long_detected; + u8 constant_prf_detected; + u8 staggered_prf_detected; +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index 6a823b8..afd9850 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -316,8 +316,6 @@ struct mt7915_phy { + s16 coverage_class; + u8 slottime; + +- u8 rdd_state; +- + u32 trb_ts; + + u32 rx_ampdu_ts; +@@ -523,10 +521,10 @@ enum { + __MT_WFDMA_MAX, + }; + +-enum { +- MT_RX_SEL0, +- MT_RX_SEL1, +- MT_RX_SEL2, /* monitor chain */ ++enum rdd_idx { ++ MT_RDD_IDX_BAND0, /* RDD idx for band idx 0 (single-band) */ ++ MT_RDD_IDX_BAND1, /* RDD idx for band idx 1 */ ++ MT_RDD_IDX_BACKGROUND, /* RDD idx for background chain */ + }; + + enum mt7915_rdd_cmd { +@@ -546,6 +544,18 @@ enum mt7915_rdd_cmd { + RDD_IRQ_OFF, + }; + ++static inline int ++mt7915_get_rdd_idx(struct mt7915_phy *phy, bool is_background) ++{ ++ if (!phy->mt76->cap.has_5ghz) ++ return -1; ++ ++ if (is_background) ++ return MT_RDD_IDX_BACKGROUND; ++ ++ return phy->mt76->band_idx; ++} ++ + static inline struct mt7915_phy * + mt7915_hw_phy(struct ieee80211_hw *hw) + { +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-testmode-fix-rx-stats-issue.patch b/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-testmode-fix-rx-stats-issue.patch new file mode 100644 index 000000000..b612092c4 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/1056-wifi-mt76-testmode-fix-rx-stats-issue.patch @@ -0,0 +1,470 @@ +From d43a156e8d7191a8643cf4d5975cd670f3c17aa6 Mon Sep 17 00:00:00 2001 +From: StanleyYP Wang +Date: Thu, 13 Mar 2025 15:25:31 +0800 +Subject: [PATCH] wifi: mt76: testmode: fix rx stats issue + +Originally, RX ok count is calculated by RX MDRDY count - FCS err count +- len mismatch count. +However, this is incorrect as the other err counts are not included in +the FW event. +Therefore, just use the RX ok count reported from FW. + +Additionally, rework testmode dump stats for dump order +The orignal dump order is determined by the order of MT76 testmode +attribute enums, and the order of the attribute enum cannot be exchanged. +If a new attribute which is related to the previous attribute, the dump +info of these two attributes will be separated. +Therefore, use nla_for_each_nested instead of for loop to dump info, so +that the dump order will be determined by the order of nla_put +in driver. + +Finally, adjust the dump stats flow to adjust the order of dump +info. + +Signed-off-by: StanleyYP Wang +--- + mac80211.c | 4 +-- + mt76.h | 17 ++++++++-- + mt7915/mac.c | 12 +++---- + mt7915/mt7915.h | 9 ----- + mt7915/testmode.c | 69 ++++++++------------------------------- + testmode.c | 83 ++++++++++++++++++++++++++++++++++++++++++----- + testmode.h | 5 ++- + tools/fields.c | 30 ++++++++++------- + 8 files changed, 132 insertions(+), 97 deletions(-) + +diff --git a/mac80211.c b/mac80211.c +index 750a642..ffff8a5 100644 +--- a/mac80211.c ++++ b/mac80211.c +@@ -818,9 +818,9 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) + #ifdef CONFIG_NL80211_TESTMODE + if (!(phy->test.flag & MT_TM_FW_RX_COUNT) && + phy->test.state == MT76_TM_STATE_RX_FRAMES) { +- phy->test.rx_stats.packets[q]++; ++ phy->test.rx_stats[q].packets++; + if (status->flag & RX_FLAG_FAILED_FCS_CRC) +- phy->test.rx_stats.fcs_error[q]++; ++ phy->test.rx_stats[q].fcs_error++; + } + #endif + +diff --git a/mt76.h b/mt76.h +index 17400fd..67e3b2f 100644 +--- a/mt76.h ++++ b/mt76.h +@@ -811,10 +811,21 @@ struct mt76_testmode_data { + u16 tx_queued_limit; + u32 tx_done; + struct { +- u64 packets[__MT_RXQ_MAX]; +- u64 fcs_error[__MT_RXQ_MAX]; ++ u64 packets; ++ u64 rx_success; ++ u64 fcs_error; + u64 len_mismatch; +- } rx_stats; ++ } rx_stats[__MT_RXQ_MAX]; ++ ++ struct { ++ s32 freq_offset; ++ u8 path; ++ u8 *rcpi; ++ s8 *rssi; ++ s8 *ib_rssi; ++ s8 *wb_rssi; ++ u8 snr; ++ } last_rx; + + u8 offchan_ch; + u8 offchan_center_ch; +diff --git a/mt7915/mac.c b/mt7915/mac.c +index cff604e..46cfe35 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -572,10 +572,10 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb) + if (i == 3) + wb_rssi = le32_to_cpu(rxv[9]); + +- phy->test.last_rcpi[i] = rcpi & 0xff; +- phy->test.last_rssi[i] = to_rssi(GENMASK(7, 0), rcpi); +- phy->test.last_ib_rssi[i] = ib_rssi & 0xff; +- phy->test.last_wb_rssi[i] = wb_rssi & 0xff; ++ phy->mt76->test.last_rx.rcpi[i] = rcpi & 0xff; ++ phy->mt76->test.last_rx.rssi[i] = to_rssi(GENMASK(7, 0), rcpi); ++ phy->mt76->test.last_rx.ib_rssi[i] = ib_rssi & 0xff; ++ phy->mt76->test.last_rx.wb_rssi[i] = wb_rssi & 0xff; + } + + v20 = le32_to_cpu(rxv[20]); +@@ -586,8 +586,8 @@ mt7915_mac_fill_rx_vector(struct mt7915_dev *dev, struct sk_buff *skb) + + snr = FIELD_GET(MT_CRXV_SNR, v20) - 16; + +- phy->test.last_freq_offset = foe; +- phy->test.last_snr = snr; ++ phy->mt76->test.last_rx.freq_offset = foe; ++ phy->mt76->test.last_rx.snr = snr; + out: + #endif + dev_kfree_skb(skb); +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index 073e65d..c67a9bb 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -339,16 +339,7 @@ struct mt7915_phy { + #ifdef CONFIG_NL80211_TESTMODE + struct { + u32 *reg_backup; +- +- s32 last_freq_offset; +- u8 last_rcpi[4]; +- s8 last_rssi[4]; +- s8 last_ib_rssi[4]; +- s8 last_wb_rssi[4]; +- u8 last_snr; +- + u8 spe_idx; +- + bool bf_ever_en; + } test; + #endif +diff --git a/mt7915/testmode.c b/mt7915/testmode.c +index 8398edd..72cee21 100644 +--- a/mt7915/testmode.c ++++ b/mt7915/testmode.c +@@ -1965,9 +1965,10 @@ mt7915_tm_get_rx_stats(struct mt7915_phy *phy, bool clear) + if (!clear) { + enum mt76_rxq_id q = req.band ? MT_RXQ_BAND1 : MT_RXQ_MAIN; + +- td->rx_stats.packets[q] += le32_to_cpu(rs_band->mdrdy_cnt); +- td->rx_stats.fcs_error[q] += le16_to_cpu(rs_band->fcs_err); +- td->rx_stats.len_mismatch += le16_to_cpu(rs_band->len_mismatch); ++ td->rx_stats[q].packets += le32_to_cpu(rs_band->mdrdy_cnt); ++ td->rx_stats[q].rx_success += le16_to_cpu(rs_band->fcs_succ); ++ td->rx_stats[q].fcs_error += le16_to_cpu(rs_band->fcs_err); ++ td->rx_stats[q].len_mismatch += le16_to_cpu(rs_band->len_mismatch); + } + + dev_kfree_skb(skb); +@@ -2560,62 +2561,18 @@ mt7915_tm_set_params(struct mt76_phy *mphy, struct nlattr **tb, + static int + mt7915_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg) + { ++ struct mt76_testmode_data *td = &mphy->test; + struct mt7915_phy *phy = mphy->priv; + struct mt7915_dev *dev = phy->dev; +- void *rx, *rssi; +- int i; +- +- rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX); +- if (!rx) +- return -ENOMEM; +- +- if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, phy->test.last_freq_offset)) +- return -ENOMEM; +- +- rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI); +- if (!rssi) +- return -ENOMEM; +- +- for (i = 0; i < ARRAY_SIZE(phy->test.last_rcpi); i++) +- if (nla_put_u8(msg, i, phy->test.last_rcpi[i])) +- return -ENOMEM; +- +- nla_nest_end(msg, rssi); +- +- rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RSSI); +- if (!rssi) +- return -ENOMEM; +- +- for (i = 0; i < ARRAY_SIZE(phy->test.last_rssi); i++) +- if (nla_put_s8(msg, i, phy->test.last_rssi[i])) +- return -ENOMEM; ++ int band_idx = mphy->band_idx; + +- nla_nest_end(msg, rssi); +- +- rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI); +- if (!rssi) +- return -ENOMEM; +- +- for (i = 0; i < ARRAY_SIZE(phy->test.last_ib_rssi); i++) +- if (nla_put_s8(msg, i, phy->test.last_ib_rssi[i])) +- return -ENOMEM; +- +- nla_nest_end(msg, rssi); +- +- rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_WB_RSSI); +- if (!rssi) +- return -ENOMEM; +- +- for (i = 0; i < ARRAY_SIZE(phy->test.last_wb_rssi); i++) +- if (nla_put_s8(msg, i, phy->test.last_wb_rssi[i])) +- return -ENOMEM; +- +- nla_nest_end(msg, rssi); +- +- if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, phy->test.last_snr)) +- return -ENOMEM; +- +- nla_nest_end(msg, rx); ++ if (!td->last_rx.path) { ++ td->last_rx.path = hweight32(mphy->chainmask >> (dev->chainshift * band_idx)); ++ td->last_rx.rcpi = devm_kzalloc(dev->mt76.dev, td->last_rx.path, GFP_KERNEL); ++ td->last_rx.rssi = devm_kzalloc(dev->mt76.dev, td->last_rx.path, GFP_KERNEL); ++ td->last_rx.ib_rssi = devm_kzalloc(dev->mt76.dev, td->last_rx.path, GFP_KERNEL); ++ td->last_rx.wb_rssi = devm_kzalloc(dev->mt76.dev, td->last_rx.path, GFP_KERNEL); ++ } + + if (mphy->test.tx_rate_mode == MT76_TM_TX_MODE_HE_MU) + mphy->test.tx_done += mt76_rr(dev, MT_MIB_DR8(phy != &dev->phy)); +diff --git a/testmode.c b/testmode.c +index 56b9205..c041b35 100644 +--- a/testmode.c ++++ b/testmode.c +@@ -454,9 +454,8 @@ __mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state) + + if (state == MT76_TM_STATE_TX_FRAMES) + mt76_testmode_tx_start(phy); +- else if (state == MT76_TM_STATE_RX_FRAMES) { ++ else if (state == MT76_TM_STATE_RX_FRAMES) + memset(&phy->test.rx_stats, 0, sizeof(phy->test.rx_stats)); +- } + + phy->test.state = state; + +@@ -769,13 +768,77 @@ out: + } + EXPORT_SYMBOL(mt76_testmode_cmd); + ++static int ++mt76_testmode_dump_last_rx_stats(struct mt76_phy *phy, struct sk_buff *msg) ++{ ++ struct mt76_testmode_data *td = &phy->test; ++ void *rx, *rssi; ++ int i; ++ ++ rx = nla_nest_start(msg, MT76_TM_STATS_ATTR_LAST_RX); ++ if (!rx) ++ return -ENOMEM; ++ ++ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RSSI); ++ if (!rssi) ++ return -ENOMEM; ++ ++ for (i = 0; i < td->last_rx.path; i++) ++ if (nla_put_s8(msg, i, td->last_rx.rssi[i])) ++ return -ENOMEM; ++ ++ nla_nest_end(msg, rssi); ++ ++ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_RCPI); ++ if (!rssi) ++ return -ENOMEM; ++ ++ for (i = 0; i < td->last_rx.path; i++) ++ if (nla_put_u8(msg, i, td->last_rx.rcpi[i])) ++ return -ENOMEM; ++ ++ nla_nest_end(msg, rssi); ++ ++ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_IB_RSSI); ++ if (!rssi) ++ return -ENOMEM; ++ ++ for (i = 0; i < td->last_rx.path; i++) ++ if (nla_put_s8(msg, i, td->last_rx.ib_rssi[i])) ++ return -ENOMEM; ++ ++ nla_nest_end(msg, rssi); ++ ++ rssi = nla_nest_start(msg, MT76_TM_RX_ATTR_WB_RSSI); ++ if (!rssi) ++ return -ENOMEM; ++ ++ for (i = 0; i < td->last_rx.path; i++) ++ if (nla_put_s8(msg, i, td->last_rx.wb_rssi[i])) ++ return -ENOMEM; ++ ++ nla_nest_end(msg, rssi); ++ ++ if (nla_put_s32(msg, MT76_TM_RX_ATTR_FREQ_OFFSET, td->last_rx.freq_offset)) ++ return -ENOMEM; ++ ++ if (nla_put_u8(msg, MT76_TM_RX_ATTR_SNR, td->last_rx.snr)) ++ return -ENOMEM; ++ ++ nla_nest_end(msg, rx); ++ ++ return 0; ++} ++ + static int + mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg) + { + struct mt76_testmode_data *td = &phy->test; + struct mt76_dev *dev = phy->dev; + u64 rx_packets = 0; ++ u64 rx_success = 0; + u64 rx_fcs_error = 0; ++ u64 rx_len_mismatch = 0; + int i; + + if (dev->test_ops->dump_stats) { +@@ -786,9 +849,11 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg) + return ret; + } + +- for (i = 0; i < ARRAY_SIZE(td->rx_stats.packets); i++) { +- rx_packets += td->rx_stats.packets[i]; +- rx_fcs_error += td->rx_stats.fcs_error[i]; ++ for (i = 0; i < ARRAY_SIZE(td->rx_stats); i++) { ++ rx_packets += td->rx_stats[i].packets; ++ rx_success += td->rx_stats[i].rx_success; ++ rx_fcs_error += td->rx_stats[i].fcs_error; ++ rx_len_mismatch += td->rx_stats[i].len_mismatch; + } + + if (nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_PENDING, td->tx_pending) || +@@ -796,14 +861,15 @@ mt76_testmode_dump_stats(struct mt76_phy *phy, struct sk_buff *msg) + nla_put_u32(msg, MT76_TM_STATS_ATTR_TX_DONE, td->tx_done) || + nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_PACKETS, rx_packets, + MT76_TM_STATS_ATTR_PAD) || ++ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_SUCCESS, rx_success, ++ MT76_TM_STATS_ATTR_PAD) || + nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_FCS_ERROR, rx_fcs_error, + MT76_TM_STATS_ATTR_PAD) || +- nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_LEN_MISMATCH, +- td->rx_stats.len_mismatch, ++ nla_put_u64_64bit(msg, MT76_TM_STATS_ATTR_RX_LEN_MISMATCH, rx_len_mismatch, + MT76_TM_STATS_ATTR_PAD)) + return -EMSGSIZE; + +- return 0; ++ return mt76_testmode_dump_last_rx_stats(phy, msg); + } + + int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, +@@ -845,6 +911,7 @@ int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *msg, + goto out; + } + ++ /* the dump order follows the order of nla_put for each attribute */ + if (tb[MT76_TM_ATTR_STATS]) { + err = -EINVAL; + +diff --git a/testmode.h b/testmode.h +index 14ce948..d1be530 100644 +--- a/testmode.h ++++ b/testmode.h +@@ -160,12 +160,14 @@ enum mt76_testmode_attr { + * @MT76_TM_STATS_ATTR_TX_QUEUED: queued tx frames (u32) + * @MT76_TM_STATS_ATTR_TX_QUEUED: completed tx frames (u32) + * +- * @MT76_TM_STATS_ATTR_RX_PACKETS: number of rx packets (u64) ++ * @MT76_TM_STATS_ATTR_RX_PACKETS: number of rx mdrdy packets ++ * with successfully parsed headers (u64) + * @MT76_TM_STATS_ATTR_RX_FCS_ERROR: number of rx packets with FCS error (u64) + * @MT76_TM_STATS_ATTR_LAST_RX: information about the last received packet + * see &enum mt76_testmode_rx_attr + * @MT76_TM_STATS_ATTR_RX_LEN_MISMATCH: number of rx packets with length + * mismatch error (u64) ++ * @MT76_TM_STATS_ATTR_RX_SUCCESS: number of successfully rx packets (u64) + */ + enum mt76_testmode_stats_attr { + MT76_TM_STATS_ATTR_UNSPEC, +@@ -179,6 +181,7 @@ enum mt76_testmode_stats_attr { + MT76_TM_STATS_ATTR_RX_FCS_ERROR, + MT76_TM_STATS_ATTR_LAST_RX, + MT76_TM_STATS_ATTR_RX_LEN_MISMATCH, ++ MT76_TM_STATS_ATTR_RX_SUCCESS, + + /* keep last */ + NUM_MT76_TM_STATS_ATTRS, +diff --git a/tools/fields.c b/tools/fields.c +index 027b8cd..2cf8af0 100644 +--- a/tools/fields.c ++++ b/tools/fields.c +@@ -203,17 +203,14 @@ static void print_array(const struct tm_field *field, struct nlattr *attr) + + static void print_nested(const struct tm_field *field, struct nlattr *attr) + { +- struct nlattr **tb = alloca(field->len * sizeof(struct nlattr *)); + const struct tm_field *fields = field->fields; +- int i; ++ struct nlattr *cur; ++ int i, rem; + +- nla_parse_nested(tb, field->len - 1, attr, field->policy); +- for (i = 0; i < field->len; i++) { ++ nla_for_each_nested(cur, attr, rem) { + int prefix_len = 0; + +- if (!tb[i]) +- continue; +- ++ i = nla_type(cur); + if (!fields[i].print) + continue; + +@@ -226,7 +223,7 @@ static void print_nested(const struct tm_field *field, struct nlattr *attr) + sizeof(prefix) - prefix_len - 1); + } + +- fields[i].print(&fields[i], tb[i]); ++ fields[i].print(&fields[i], cur); + if (fields[i].prefix) + prefix[prefix_len] = 0; + +@@ -234,20 +231,25 @@ static void print_nested(const struct tm_field *field, struct nlattr *attr) + printf("\n"); + } + +- if (field->print_extra) ++ if (field->print_extra) { ++ struct nlattr **tb = alloca(field->len * sizeof(struct nlattr *)); ++ ++ nla_parse_nested(tb, field->len - 1, attr, field->policy); + field->print_extra(field, tb); ++ } + } + + static void print_extra_stats(const struct tm_field *field, struct nlattr **tb) + { +- float total, failed; ++ float total, success, failed; + + if (!tb[MT76_TM_STATS_ATTR_RX_PACKETS] || +- !tb[MT76_TM_STATS_ATTR_RX_FCS_ERROR]) ++ !tb[MT76_TM_STATS_ATTR_RX_SUCCESS]) + return; + + total = nla_get_u64(tb[MT76_TM_STATS_ATTR_RX_PACKETS]); +- failed = nla_get_u64(tb[MT76_TM_STATS_ATTR_RX_FCS_ERROR]); ++ success = nla_get_u64(tb[MT76_TM_STATS_ATTR_RX_SUCCESS]); ++ failed = total - success; + + printf("%srx_per=%.02f%%\n", prefix, 100 * failed / total); + } +@@ -391,6 +393,8 @@ static const struct tm_field stats_fields[NUM_MT76_TM_STATS_ATTRS] = { + FIELD_RO(u32, TX_DONE, "tx_done"), + FIELD_RO(u64, RX_PACKETS, "rx_packets"), + FIELD_RO(u64, RX_FCS_ERROR, "rx_fcs_error"), ++ FIELD_RO(u64, RX_LEN_MISMATCH, "rx_len_mismatch"), ++ FIELD_RO(u64, RX_SUCCESS, "rx_success"), + FIELD_NESTED_RO(LAST_RX, rx, "last_"), + }; + static struct nla_policy stats_policy[NUM_MT76_TM_STATS_ATTRS] = { +@@ -399,6 +403,8 @@ static struct nla_policy stats_policy[NUM_MT76_TM_STATS_ATTRS] = { + [MT76_TM_STATS_ATTR_TX_DONE] = { .type = NLA_U32 }, + [MT76_TM_STATS_ATTR_RX_PACKETS] = { .type = NLA_U64 }, + [MT76_TM_STATS_ATTR_RX_FCS_ERROR] = { .type = NLA_U64 }, ++ [MT76_TM_STATS_ATTR_RX_LEN_MISMATCH] = { .type = NLA_U64 }, ++ [MT76_TM_STATS_ATTR_RX_SUCCESS] = { .type = NLA_U64 }, + }; + #undef FIELD_NAME + +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch b/feeds/mediatek-sdk/mt76/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch index 8d6705ef5..b51c053a3 100644 --- a/feeds/mediatek-sdk/mt76/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch +++ b/feeds/mediatek-sdk/mt76/patches/2000-wifi-mt76-mt7915-wed-add-wed-tx-support.patch @@ -1,7 +1,7 @@ -From 86f4aafcab8e833c7009e453e97adc254628d4d1 Mon Sep 17 00:00:00 2001 +From daf071f6469272be2b7b61cb227efb7ad57c2ddd Mon Sep 17 00:00:00 2001 From: Sujuan Chen Date: Fri, 25 Nov 2022 10:38:53 +0800 -Subject: [PATCH 2000/2014] wifi: mt76: mt7915: wed: add wed tx support +Subject: [PATCH 78/94] wifi: mt76: mt7915: wed: add wed tx support Signed-off-by: Sujuan Chen --- @@ -14,7 +14,7 @@ Signed-off-by: Sujuan Chen 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mt76_connac.h b/mt76_connac.h -index 8e7068c..e1d6ca2 100644 +index e411032..f2006ea 100644 --- a/mt76_connac.h +++ b/mt76_connac.h @@ -130,6 +130,7 @@ struct mt76_connac_sta_key_conf { @@ -26,7 +26,7 @@ index 8e7068c..e1d6ca2 100644 struct mt76_connac_fw_txp { __le16 flags; diff --git a/mt7915/mac.c b/mt7915/mac.c -index c84b957..1c8b873 100644 +index 677c339..543077d 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -878,9 +878,9 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id) @@ -67,10 +67,10 @@ index c84b957..1c8b873 100644 static void diff --git a/mt7915/main.c b/mt7915/main.c -index 41fa450..332b087 100644 +index e3bc373..6f09dda 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -1753,14 +1753,14 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, +@@ -1832,7 +1832,7 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, if (!mtk_wed_device_active(wed)) return -ENODEV; @@ -78,7 +78,8 @@ index 41fa450..332b087 100644 + if (msta->wcid.idx > MT7915_WTBL_STA) return -EIO; - path->type = DEV_PATH_MTK_WDMA; + if (!test_bit((mvif->qos_map[path->mtk_wdma.tid >> 2] + AMPDU_ADDBA_SUCC_SHFT), +@@ -1843,7 +1843,7 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, path->dev = ctx->dev; path->mtk_wdma.wdma_idx = wed->wdma_idx; path->mtk_wdma.bss = mvif->mt76.idx; @@ -88,7 +89,7 @@ index 41fa450..332b087 100644 ctx->dev = NULL; diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 437a9b0..91100f1 100644 +index b1b219c..5364821 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -13,7 +13,7 @@ @@ -109,7 +110,7 @@ index 437a9b0..91100f1 100644 ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32)); if (ret) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 47f7d16..1d0188d 100644 +index 7c185a1..94ea3e1 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -62,7 +62,7 @@ @@ -135,5 +136,5 @@ index f7a3f1b..47c81a2 100644 } EXPORT_SYMBOL_GPL(mt76_wed_offload_disable); -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch b/feeds/mediatek-sdk/mt76/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch index 9ddec3e60..35edec4a7 100644 --- a/feeds/mediatek-sdk/mt76/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch +++ b/feeds/mediatek-sdk/mt76/patches/2001-wifi-mt76-mt7915-wed-add-wds-support-when-wed-is-ena.patch @@ -1,7 +1,7 @@ -From ab7172fb880f05bc6005a78982278c5b365055b4 Mon Sep 17 00:00:00 2001 +From 2845e9a6b55d63d970541c8322eec387bfa252e4 Mon Sep 17 00:00:00 2001 From: Sujuan Chen Date: Tue, 13 Dec 2022 17:51:26 +0800 -Subject: [PATCH 2001/2014] wifi: mt76: mt7915: wed: add wds support when wed +Subject: [PATCH 2001/2015] wifi: mt76: mt7915: wed: add wds support when wed is enabled Signed-off-by: Sujuan Chen @@ -15,7 +15,7 @@ Signed-off-by: Sujuan Chen 6 files changed, 82 insertions(+), 10 deletions(-) diff --git a/mt76.h b/mt76.h -index fb50d88..d3c6ac0 100644 +index 49ddaade..411a9576 100644 --- a/mt76.h +++ b/mt76.h @@ -78,6 +78,12 @@ enum mt76_wed_type { @@ -32,10 +32,10 @@ index fb50d88..d3c6ac0 100644 u32 (*rr)(struct mt76_dev *dev, u32 offset); void (*wr)(struct mt76_dev *dev, u32 offset, u32 val); diff --git a/mt7915/main.c b/mt7915/main.c -index 332b087..ab60159 100644 +index ff0337a6..778c73e9 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -829,8 +829,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, +@@ -834,8 +834,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, #endif int ret, idx; u32 addr; @@ -52,7 +52,7 @@ index 332b087..ab60159 100644 if (idx < 0) return -ENOSPC; -@@ -1321,6 +1328,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, +@@ -1335,6 +1342,13 @@ static void mt7915_sta_set_4addr(struct ieee80211_hw *hw, else clear_bit(MT_WCID_FLAG_4ADDR, &msta->wcid.flags); @@ -66,7 +66,7 @@ index 332b087..ab60159 100644 mt76_connac_mcu_wtbl_update_hdr_trans(&dev->mt76, vif, sta); } -@@ -1760,8 +1774,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, +@@ -1823,8 +1837,12 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, path->dev = ctx->dev; path->mtk_wdma.wdma_idx = wed->wdma_idx; path->mtk_wdma.bss = mvif->mt76.idx; @@ -81,7 +81,7 @@ index 332b087..ab60159 100644 ctx->dev = NULL; diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index d857658..b42afe8 100644 +index 250b05ec..7927a523 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -2588,10 +2588,18 @@ int mt7915_mcu_init_firmware(struct mt7915_dev *dev) @@ -108,7 +108,7 @@ index d857658..b42afe8 100644 ret = mt7915_mcu_set_mwds(dev, 1); if (ret) diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index f476767..52baaa7 100644 +index f4767671..52baaa73 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -392,6 +392,7 @@ enum { @@ -120,7 +120,7 @@ index f476767..52baaa7 100644 MCU_WA_PARAM_RED_SHOW_STA = 0xf, MCU_WA_PARAM_RED_TARGET_DELAY = 0x10, diff --git a/util.c b/util.c -index fc76c66..61b2d30 100644 +index d6c01a2d..995d7880 100644 --- a/util.c +++ b/util.c @@ -42,9 +42,14 @@ bool ____mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, @@ -188,7 +188,7 @@ index fc76c66..61b2d30 100644 int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy) { diff --git a/util.h b/util.h -index 260965d..99b7263 100644 +index 260965dd..99b7263c 100644 --- a/util.h +++ b/util.h @@ -27,7 +27,12 @@ enum { diff --git a/feeds/mediatek-sdk/mt76/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch b/feeds/mediatek-sdk/mt76/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch index 98ec448c6..6e78804fd 100644 --- a/feeds/mediatek-sdk/mt76/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch +++ b/feeds/mediatek-sdk/mt76/patches/2002-wifi-mt76-mt7915-wed-add-fill-receive-path-to-report.patch @@ -1,7 +1,7 @@ -From 6fa429e617e59379bd82c8dbef851e99954676ed Mon Sep 17 00:00:00 2001 +From 0f848ffb35cc45beb156069d3856b14414e9a6ee Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Fri, 19 May 2023 07:05:22 +0800 -Subject: [PATCH 2002/2014] wifi: mt76: mt7915: wed: add fill receive path to +Subject: [PATCH 2002/2015] wifi: mt76: mt7915: wed: add fill receive path to report wed idx Signed-off-by: Sujuan Chen @@ -10,10 +10,10 @@ Signed-off-by: Sujuan Chen 1 file changed, 18 insertions(+) diff --git a/mt7915/main.c b/mt7915/main.c -index ab60159..b3e06aa 100644 +index 778c73e9..abafa5e4 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -1785,6 +1785,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, +@@ -1848,6 +1848,23 @@ mt7915_net_fill_forward_path(struct ieee80211_hw *hw, return 0; } @@ -37,7 +37,7 @@ index ab60159..b3e06aa 100644 #endif const struct ieee80211_ops mt7915_ops = { -@@ -1841,6 +1858,7 @@ const struct ieee80211_ops mt7915_ops = { +@@ -1910,6 +1927,7 @@ const struct ieee80211_ops mt7915_ops = { .set_radar_background = mt7915_set_radar_background, #ifdef CONFIG_NET_MEDIATEK_SOC_WED .net_fill_forward_path = mt7915_net_fill_forward_path, diff --git a/feeds/mediatek-sdk/mt76/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch b/feeds/mediatek-sdk/mt76/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch index 54c520ece..ef367928e 100644 --- a/feeds/mediatek-sdk/mt76/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch +++ b/feeds/mediatek-sdk/mt76/patches/2003-wifi-mt76-mt7915-wed-find-rx-token-by-physical-addre.patch @@ -1,7 +1,7 @@ -From 79d00e5e7ff7653dc6839551f33a5b36d6291169 Mon Sep 17 00:00:00 2001 +From 6d6ae068e478b101556ae723c23533220a8daeb5 Mon Sep 17 00:00:00 2001 From: Sujuan Chen Date: Fri, 25 Nov 2022 14:32:35 +0800 -Subject: [PATCH 2003/2014] wifi: mt76: mt7915: wed: find rx token by physical +Subject: [PATCH 2003/2015] wifi: mt76: mt7915: wed: find rx token by physical address The token id in RxDMAD may be incorrect when it is not the last frame due to @@ -13,7 +13,7 @@ Signed-off-by: Peter Chiu 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/dma.c b/dma.c -index 100d2af..185c6f1 100644 +index 100d2aff..185c6f12 100644 --- a/dma.c +++ b/dma.c @@ -444,9 +444,32 @@ mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx, diff --git a/feeds/mediatek-sdk/mt76/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch b/feeds/mediatek-sdk/mt76/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch index 936d19d43..c81692394 100644 --- a/feeds/mediatek-sdk/mt76/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch +++ b/feeds/mediatek-sdk/mt76/patches/2004-wifi-mt76-mt7915-wed-HW-ATF-support-for-mt7986.patch @@ -1,7 +1,7 @@ -From f4c4eda21841dae1229e6f7942d4a74f385d87a5 Mon Sep 17 00:00:00 2001 +From bd38f1f0988785cb9316c99e0fe144f3a6421b50 Mon Sep 17 00:00:00 2001 From: Lian Chen Date: Mon, 7 Nov 2022 14:47:44 +0800 -Subject: [PATCH 2004/2014] wifi: mt76: mt7915: wed: HW ATF support for mt7986 +Subject: [PATCH] wifi: mt76: mt7915: wed: HW ATF support for mt7986 Signed-off-by: Lian Chen Signed-off-by: Benjamin Lin @@ -11,15 +11,15 @@ Signed-off-by: Benjamin Lin mt7915/init.c | 58 +++++++ mt7915/main.c | 14 ++ mt7915/mcu.c | 169 +++++++++++++++++++- - mt7915/mt7915.h | 69 +++++++++ + mt7915/mt7915.h | 67 ++++++++ mt7915/mtk_debugfs.c | 130 ++++++++++++++++ - 7 files changed, 796 insertions(+), 3 deletions(-) + 7 files changed, 794 insertions(+), 3 deletions(-) diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index dc60e35..03d6a2b 100644 +index d8b001f..1721f9b 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1209,6 +1209,7 @@ enum { +@@ -1211,6 +1211,7 @@ enum { MCU_EXT_CMD_THERMAL_CTRL = 0x2c, MCU_EXT_CMD_WTBL_UPDATE = 0x32, MCU_EXT_CMD_SET_DRR_CTRL = 0x36, @@ -27,7 +27,7 @@ index dc60e35..03d6a2b 100644 MCU_EXT_CMD_SET_RDD_CTRL = 0x3a, MCU_EXT_CMD_ATE_CTRL = 0x3d, MCU_EXT_CMD_PROTECT_CTRL = 0x3e, -@@ -1218,6 +1219,7 @@ enum { +@@ -1220,6 +1221,7 @@ enum { MCU_EXT_CMD_MUAR_UPDATE = 0x48, MCU_EXT_CMD_BCN_OFFLOAD = 0x49, MCU_EXT_CMD_RX_AIRTIME_CTRL = 0x4a, @@ -36,7 +36,7 @@ index dc60e35..03d6a2b 100644 MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f, MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58, diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index d8ca90a..3ae4aca 100644 +index c118492..c612af3 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -12,6 +12,10 @@ @@ -409,7 +409,7 @@ index d8ca90a..3ae4aca 100644 static int mt7915_radar_trigger(void *data, u64 val) { -@@ -1526,6 +1882,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) +@@ -1581,6 +1937,7 @@ int mt7915_init_debugfs(struct mt7915_phy *phy) debugfs_create_devm_seqfile(dev->mt76.dev, "twt_stats", dir, mt7915_twt_stats); debugfs_create_file("rf_regval", 0600, dir, dev, &fops_rf_regval); @@ -418,10 +418,10 @@ index d8ca90a..3ae4aca 100644 if (!dev->dbdc_support || phy->mt76->band_idx) { debugfs_create_u32("dfs_hw_pattern", 0400, dir, diff --git a/mt7915/init.c b/mt7915/init.c -index 9ffeca5..16c3632 100644 +index 813aa43..d1cea0e 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -587,9 +587,64 @@ mt7915_init_led_mux(struct mt7915_dev *dev) +@@ -588,9 +588,64 @@ mt7915_init_led_mux(struct mt7915_dev *dev) } } @@ -484,9 +484,9 @@ index 9ffeca5..16c3632 100644 int i; + struct wiphy *wiphy = dev->phy.mt76->hw->wiphy; - if (!is_mt7915(&dev->mt76)) - mt76_clear(dev, MT_MDP_DCR2, MT_MDP_DCR2_RX_TRANS_SHORT); -@@ -603,6 +658,9 @@ void mt7915_mac_init(struct mt7915_dev *dev) + /* config pse qid6 wfdma port selection */ + if (!is_mt7915(&dev->mt76) && dev->hif2) +@@ -609,6 +664,9 @@ void mt7915_mac_init(struct mt7915_dev *dev) mt7915_mac_init_band(dev, i); mt7915_init_led_mux(dev); @@ -497,7 +497,7 @@ index 9ffeca5..16c3632 100644 int mt7915_txbf_init(struct mt7915_dev *dev) diff --git a/mt7915/main.c b/mt7915/main.c -index b3e06aa..199ce82 100644 +index 35e488f..dd2bc22 100644 --- a/mt7915/main.c +++ b/mt7915/main.c @@ -226,6 +226,7 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e @@ -507,8 +507,8 @@ index b3e06aa..199ce82 100644 + struct wiphy *wiphy = dev->phy.mt76->hw->wiphy; struct mt76_txq *mtxq; bool ext_phy = phy != &dev->phy; - int idx, ret = 0; -@@ -288,6 +289,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e + int idx, i, ret = 0; +@@ -297,6 +298,9 @@ int mt7915_init_vif(struct mt7915_phy *phy, struct ieee80211_vif *vif, bool bf_e mt7915_mcu_add_sta(dev, vif, NULL, true); rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); @@ -518,7 +518,7 @@ index b3e06aa..199ce82 100644 return ret; } -@@ -824,6 +828,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, +@@ -832,6 +836,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv; struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; bool ext_phy = mvif->phy != &dev->phy; @@ -526,7 +526,7 @@ index b3e06aa..199ce82 100644 #ifdef CONFIG_MTK_VENDOR struct mt7915_phy *phy = ext_phy ? mt7915_ext_phy(dev) : &dev->phy; #endif -@@ -874,6 +879,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, +@@ -881,6 +886,15 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, if (phy->muru_onoff & MUMIMO_DL_CERT) mt7915_mcu_set_mimo(phy, 0); #endif @@ -543,10 +543,10 @@ index b3e06aa..199ce82 100644 } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index b42afe8..a153585 100644 +index 1bc1500..5fcffd1 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c -@@ -1866,7 +1866,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif, +@@ -1889,7 +1889,7 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif, { #define MT_STA_BSS_GROUP 1 struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; @@ -555,7 +555,7 @@ index b42afe8..a153585 100644 struct { __le32 action; u8 wlan_idx_lo; -@@ -1877,10 +1877,9 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif, +@@ -1900,10 +1900,9 @@ mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif, u8 rsv1[8]; } __packed req = { .action = cpu_to_le32(MT_STA_BSS_GROUP), @@ -567,7 +567,7 @@ index b42afe8..a153585 100644 req.wlan_idx_lo = to_wcid_lo(msta->wcid.idx); req.wlan_idx_hi = to_wcid_hi(msta->wcid.idx); -@@ -1938,6 +1937,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif, +@@ -1961,6 +1960,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif, mt7915_mcu_sta_bfee_tlv(dev, skb, vif, sta); } @@ -575,7 +575,7 @@ index b42afe8..a153585 100644 ret = mt7915_mcu_add_group(dev, vif, sta); if (ret) { dev_kfree_skb(skb); -@@ -3897,6 +3897,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band) +@@ -3922,6 +3922,169 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band) &req, sizeof(req), false); } @@ -746,10 +746,10 @@ index b42afe8..a153585 100644 { #define MT_BF_PROCESSING 4 diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 1d0188d..d779488 100644 +index 9cdf4d8..b841202 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -141,6 +141,58 @@ struct mt7915_twt_flow { +@@ -143,6 +143,58 @@ struct mt7915_twt_flow { DECLARE_EWMA(avg_signal, 10, 8) @@ -808,7 +808,7 @@ index 1d0188d..d779488 100644 struct mt7915_sta { struct mt76_wcid wcid; /* must be first */ -@@ -161,6 +213,7 @@ struct mt7915_sta { +@@ -162,6 +214,7 @@ struct mt7915_sta { u8 flowid_mask; struct mt7915_twt_flow flow[MT7915_MAX_STA_TWT_AGRT]; } twt; @@ -816,7 +816,7 @@ index 1d0188d..d779488 100644 }; struct mt7915_vif_cap { -@@ -490,6 +543,8 @@ struct mt7915_dev { +@@ -508,6 +561,8 @@ struct mt7915_dev { #endif struct delayed_work scs_work; @@ -825,23 +825,21 @@ index 1d0188d..d779488 100644 bool wmm_pbc_enable; struct work_struct wmm_pbc_work; -@@ -526,6 +581,15 @@ enum mt7915_rdd_cmd { - RDD_IRQ_OFF, - }; +@@ -556,6 +611,13 @@ mt7915_get_rdd_idx(struct mt7915_phy *phy, bool is_background) + return phy->mt76->band_idx; + } +static inline bool +mt7915_is_atf_default_on(struct wiphy *wiphy, struct mt7915_dev *dev) +{ -+ return ((!wiphy_ext_feature_isset(wiphy, -+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) || -+ mtk_wed_device_active(&dev->mt76.mmio.wed)); ++ return !wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS) || ++ mtk_wed_device_active(&dev->mt76.mmio.wed); +} -+ + static inline struct mt7915_phy * mt7915_hw_phy(struct ieee80211_hw *hw) { -@@ -655,6 +719,11 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, +@@ -686,6 +748,11 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable, int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode, u8 en); int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band); @@ -854,7 +852,7 @@ index 1d0188d..d779488 100644 int mt7915_mcu_set_txpower_sku(struct mt7915_phy *phy); int mt7915_mcu_get_txpower_sku(struct mt7915_phy *phy, s8 *txpower, int len, diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 78ac4e5..ead8970 100644 +index 3a58a06..b201492 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -1518,6 +1518,136 @@ static void chip_get_sta_pause(struct mt7915_dev *dev, u32 *sta_pause) @@ -995,5 +993,5 @@ index 78ac4e5..ead8970 100644 { struct mt7915_dev *dev = dev_get_drvdata(s->private); -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch b/feeds/mediatek-sdk/mt76/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch index a5d33494e..ae9b7c02a 100644 --- a/feeds/mediatek-sdk/mt76/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch +++ b/feeds/mediatek-sdk/mt76/patches/2005-wifi-mt76-mt7915-wed-add-rxwi-for-further-in-chip-rr.patch @@ -1,7 +1,7 @@ -From 1cb052dfd4d21367e1c6623721d58a05648c9b2a Mon Sep 17 00:00:00 2001 +From b6184a94736ddea3277b1bea374686edb9aef6b4 Mon Sep 17 00:00:00 2001 From: Sujuan Chen Date: Fri, 6 Jan 2023 18:18:50 +0800 -Subject: [PATCH 2005/2014] wifi: mt76: mt7915: wed: add rxwi for further in +Subject: [PATCH 2005/2015] wifi: mt76: mt7915: wed: add rxwi for further in chip rro Signed-off-by: Sujuan Chen @@ -17,7 +17,7 @@ Signed-off-by: Sujuan Chen 8 files changed, 87 insertions(+), 80 deletions(-) diff --git a/dma.c b/dma.c -index 185c6f1..9cd97d2 100644 +index 185c6f12..9cd97d24 100644 --- a/dma.c +++ b/dma.c @@ -64,17 +64,17 @@ mt76_alloc_txwi(struct mt76_dev *dev) @@ -245,10 +245,10 @@ index 185c6f1..9cd97d2 100644 unmap: for (n--; n > 0; n--) diff --git a/mac80211.c b/mac80211.c -index f9dfdf8..225b290 100644 +index 750a642a..e50c68f8 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -618,7 +618,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size, +@@ -619,7 +619,6 @@ mt76_alloc_device(struct device *pdev, unsigned int size, spin_lock_init(&dev->lock); spin_lock_init(&dev->cc_lock); spin_lock_init(&dev->status_lock); @@ -256,7 +256,7 @@ index f9dfdf8..225b290 100644 mutex_init(&dev->mutex); init_waitqueue_head(&dev->tx_wait); -@@ -651,6 +650,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size, +@@ -652,6 +651,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size, INIT_LIST_HEAD(&dev->txwi_cache); INIT_LIST_HEAD(&dev->rxwi_cache); dev->token_size = dev->drv->token_size; @@ -265,7 +265,7 @@ index f9dfdf8..225b290 100644 for (i = 0; i < ARRAY_SIZE(dev->q_rx); i++) skb_queue_head_init(&dev->rx_skb[i]); diff --git a/mt76.h b/mt76.h -index d3c6ac0..2e7585a 100644 +index 411a9576..40884fd8 100644 --- a/mt76.h +++ b/mt76.h @@ -193,6 +193,7 @@ struct mt76_queue_entry { @@ -312,7 +312,7 @@ index d3c6ac0..2e7585a 100644 spinlock_t lock; spinlock_t cc_lock; -@@ -1630,8 +1636,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) +@@ -1639,8 +1645,8 @@ mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) } void mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t); @@ -323,7 +323,7 @@ index d3c6ac0..2e7585a 100644 void mt76_free_pending_rxwi(struct mt76_dev *dev); void mt76_rx_complete(struct mt76_dev *dev, struct sk_buff_head *frames, struct napi_struct *napi); -@@ -1810,9 +1816,9 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake); +@@ -1831,9 +1837,9 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake); int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi, u8 phy_idx); void __mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked); @@ -336,7 +336,7 @@ index d3c6ac0..2e7585a 100644 static inline void mt76_set_tx_blocked(struct mt76_dev *dev, bool blocked) { diff --git a/mt7915/dma.c b/mt7915/dma.c -index 0baa82c..552410a 100644 +index 0baa82c8..552410aa 100644 --- a/mt7915/dma.c +++ b/mt7915/dma.c @@ -512,7 +512,6 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) @@ -356,7 +356,7 @@ index 0baa82c..552410a 100644 } diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 91100f1..3391a94 100644 +index 53648212..baf35a53 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -725,7 +725,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, @@ -377,7 +377,7 @@ index 91100f1..3391a94 100644 .tx_complete_skb = mt76_connac_tx_complete_skb, .rx_skb = mt7915_queue_rx_skb, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index d779488..e41c7ad 100644 +index 9ea30f1d..55af5c8c 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -64,6 +64,7 @@ @@ -389,7 +389,7 @@ index d779488..e41c7ad 100644 #define MT7915_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ #define MT7915_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ diff --git a/tx.c b/tx.c -index db0d4df..92afbf5 100644 +index db0d4df5..92afbf5d 100644 --- a/tx.c +++ b/tx.c @@ -864,16 +864,16 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi, @@ -434,7 +434,7 @@ index db0d4df..92afbf5 100644 } EXPORT_SYMBOL_GPL(mt76_rx_token_release); diff --git a/wed.c b/wed.c -index 47c81a2..c03b52f 100644 +index 47c81a28..c03b52f9 100644 --- a/wed.c +++ b/wed.c @@ -16,18 +16,18 @@ void mt76_wed_release_rx_buf(struct mtk_wed_device *wed) diff --git a/feeds/mediatek-sdk/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch b/feeds/mediatek-sdk/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch index afee625ba..a0c7a95c9 100644 --- a/feeds/mediatek-sdk/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch +++ b/feeds/mediatek-sdk/mt76/patches/2006-wifi-mt76-add-debugfs-knob-to-show-packet-error-rate.patch @@ -1,7 +1,7 @@ -From 94195c0022e50d9a3e28dc184bbaaa4505648611 Mon Sep 17 00:00:00 2001 +From 35000e804c9cad780ee340efba7cebf461366cd3 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Wed, 11 Jan 2023 10:56:27 +0800 -Subject: [PATCH 2006/2014] wifi: mt76: add debugfs knob to show packet error +Subject: [PATCH 2006/2015] wifi: mt76: add debugfs knob to show packet error rate Get tx count and tx failed from mcu command @@ -15,7 +15,7 @@ Get tx count and tx failed from mcu command 6 files changed, 194 insertions(+), 1 deletion(-) diff --git a/mt76.h b/mt76.h -index 2e7585a..29e0b19 100644 +index 40884fd8..7100934a 100644 --- a/mt76.h +++ b/mt76.h @@ -321,8 +321,10 @@ struct mt76_sta_stats { @@ -30,10 +30,10 @@ index 2e7585a..29e0b19 100644 u64 rx_bytes; u32 rx_packets; diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h -index 03d6a2b..b0d3fe8 100644 +index 1721f9b5..3d00961c 100644 --- a/mt76_connac_mcu.h +++ b/mt76_connac_mcu.h -@@ -1207,6 +1207,7 @@ enum { +@@ -1209,6 +1209,7 @@ enum { MCU_EXT_CMD_EDCA_UPDATE = 0x27, MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A, MCU_EXT_CMD_THERMAL_CTRL = 0x2c, @@ -42,7 +42,7 @@ index 03d6a2b..b0d3fe8 100644 MCU_EXT_CMD_SET_DRR_CTRL = 0x36, MCU_EXT_CMD_SET_FEATURE_CTRL = 0x38, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index a153585..c75db44 100644 +index 570dd171..8733a07d 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4565,6 +4565,114 @@ int mt7915_mcu_get_tx_rate(struct mt7915_phy *phy, u16 wcidx) @@ -161,7 +161,7 @@ index a153585..c75db44 100644 struct cfg80211_he_bss_color *he_bss_color) { diff --git a/mt7915/mcu.h b/mt7915/mcu.h -index 52baaa7..ec7ad7d 100644 +index 52baaa73..ec7ad7db 100644 --- a/mt7915/mcu.h +++ b/mt7915/mcu.h @@ -854,7 +854,8 @@ mt7915_get_power_bound(struct mt7915_phy *phy, s8 txpower) @@ -200,10 +200,10 @@ index 52baaa7..ec7ad7d 100644 CAPI_SU, CAPI_MU, diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index e41c7ad..38d39c8 100644 +index 55af5c8c..731f5f3e 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -753,6 +753,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, +@@ -770,6 +770,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, struct cfg80211_chan_def *chandef); int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid); @@ -212,7 +212,7 @@ index e41c7ad..38d39c8 100644 int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index ead8970..a80ddeb 100644 +index d6e92b12..d64a3aec 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -4027,6 +4027,66 @@ mt7915_sr_scene_cond_show(struct seq_file *file, void *data) diff --git a/feeds/mediatek-sdk/mt76/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch b/feeds/mediatek-sdk/mt76/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch index 39b47043a..8052770a8 100644 --- a/feeds/mediatek-sdk/mt76/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch +++ b/feeds/mediatek-sdk/mt76/patches/2007-wifi-mt76-mt7915-add-ctxd-support-for-mt7916.patch @@ -1,7 +1,7 @@ -From 1509b89e35f93f8e8bf7b1343cee162377b18305 Mon Sep 17 00:00:00 2001 +From fac0ee814e10b01fc8536f4da0e2e7cec474b5d7 Mon Sep 17 00:00:00 2001 From: "sujuan.chen" Date: Thu, 6 Apr 2023 17:50:52 +0800 -Subject: [PATCH 2007/2014] wifi: mt76: mt7915: add ctxd support for mt7916 +Subject: [PATCH 2007/2015] wifi: mt76: mt7915: add ctxd support for mt7916 Signed-off-by: sujuan.chen --- @@ -10,7 +10,7 @@ Signed-off-by: sujuan.chen 2 files changed, 35 insertions(+) diff --git a/mt7915/dma.c b/mt7915/dma.c -index 552410a..4f9f5a3 100644 +index 552410aa..4f9f5a38 100644 --- a/mt7915/dma.c +++ b/mt7915/dma.c @@ -435,6 +435,26 @@ int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2) @@ -41,7 +41,7 @@ index 552410a..4f9f5a3 100644 } else { mt76_clear(dev, MT_WFDMA_HOST_CONFIG, MT_WFDMA_HOST_CONFIG_WED); diff --git a/mt7915/regs.h b/mt7915/regs.h -index ca355d1..d4acefc 100644 +index ca355d14..d4acefca 100644 --- a/mt7915/regs.h +++ b/mt7915/regs.h @@ -607,6 +607,7 @@ enum offs_rev { diff --git a/feeds/mediatek-sdk/mt76/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch b/feeds/mediatek-sdk/mt76/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch index 133e01b34..6705920f7 100644 --- a/feeds/mediatek-sdk/mt76/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch +++ b/feeds/mediatek-sdk/mt76/patches/2008-wifi-mt76-connac-wed-add-wed-rx-copy-skb.patch @@ -1,7 +1,7 @@ -From 6f0a79be1206d1d8b656e7388d47ecebfa5c786f Mon Sep 17 00:00:00 2001 +From cfad406a8e50de85347861782835596f599bfe59 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Sun, 4 Feb 2024 17:52:44 +0800 -Subject: [PATCH 2008/2014] wifi: mt76: connac: wed: add wed rx copy skb +Subject: [PATCH 2008/2015] wifi: mt76: connac: wed: add wed rx copy skb Signed-off-by: Sujuan Chen --- @@ -10,7 +10,7 @@ Signed-off-by: Sujuan Chen 2 files changed, 80 insertions(+), 28 deletions(-) diff --git a/dma.c b/dma.c -index 9cd97d2..d17fc88 100644 +index 9cd97d24..d17fc88c 100644 --- a/dma.c +++ b/dma.c @@ -225,10 +225,10 @@ void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q) @@ -138,7 +138,7 @@ index 9cd97d2..d17fc88 100644 static void diff --git a/wed.c b/wed.c -index c03b52f..70e4057 100644 +index c03b52f9..70e40575 100644 --- a/wed.c +++ b/wed.c @@ -9,12 +9,9 @@ diff --git a/feeds/mediatek-sdk/mt76/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch b/feeds/mediatek-sdk/mt76/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch index 23447e30a..730a4937d 100644 --- a/feeds/mediatek-sdk/mt76/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch +++ b/feeds/mediatek-sdk/mt76/patches/2009-wifi-mt76-mt7915-enable-wa-log-to-uart.patch @@ -1,7 +1,7 @@ -From 0d4fe8030a80350c0b5b66a45467f4f53a49b526 Mon Sep 17 00:00:00 2001 +From 3be6f92d47cdfd1ab676c9728cc84560fd2cee91 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Fri, 8 Sep 2023 18:26:21 +0800 -Subject: [PATCH 2009/2014] wifi: mt76: mt7915: enable wa log to uart +Subject: [PATCH 2009/2015] wifi: mt76: mt7915: enable wa log to uart Signed-off-by: Peter Chiu --- @@ -9,7 +9,7 @@ Signed-off-by: Peter Chiu 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 3ae4aca..76d1951 100644 +index 576ec1a5..03ccb51b 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c @@ -951,7 +951,11 @@ mt7915_fw_debug_wa_set(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch b/feeds/mediatek-sdk/mt76/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch index 7a3eaaaf5..8bccb66ed 100644 --- a/feeds/mediatek-sdk/mt76/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch +++ b/feeds/mediatek-sdk/mt76/patches/2010-wifi-mt76-mt7915-add-error-message-when-driver-recei.patch @@ -1,7 +1,7 @@ -From bc7b628c2a3ec331489bff0a1c940743db7b5f1e Mon Sep 17 00:00:00 2001 +From 24b3e43ac4d858dd17013087e4ea0b4b86002079 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Fri, 8 Sep 2023 18:29:32 +0800 -Subject: [PATCH 2010/2014] wifi: mt76: mt7915: add error message when driver +Subject: [PATCH 2010/2015] wifi: mt76: mt7915: add error message when driver receive invalid token id Signed-off-by: Peter Chiu @@ -10,7 +10,7 @@ Signed-off-by: Peter Chiu 1 file changed, 6 insertions(+) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 1c8b873..3f907e6 100644 +index 1c8b8732..3f907e61 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -1007,6 +1007,12 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) diff --git a/feeds/mediatek-sdk/mt76/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch b/feeds/mediatek-sdk/mt76/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch index 6ac0b971c..21e664713 100644 --- a/feeds/mediatek-sdk/mt76/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch +++ b/feeds/mediatek-sdk/mt76/patches/2011-wifi-mt76-mt7915-wed-change-wed-token-init-size-to-a.patch @@ -1,7 +1,7 @@ -From 27111a53eab45e86c00c1f5cf8e2d8fd76b65424 Mon Sep 17 00:00:00 2001 +From a1da16a0e8de7d47d6dbd43e2e677edd6285387a Mon Sep 17 00:00:00 2001 From: "sujuan.chen" Date: Mon, 11 Sep 2023 17:57:32 +0800 -Subject: [PATCH 2011/2014] wifi: mt76: mt7915: wed: change wed token init size +Subject: [PATCH 2011/2015] wifi: mt76: mt7915: wed: change wed token init size to adapt wed version Signed-off-by: sujuan.chen @@ -16,7 +16,7 @@ Signed-off-by: sujuan.chen 7 files changed, 33 insertions(+), 26 deletions(-) diff --git a/mt76.h b/mt76.h -index 29e0b19..b6292e3 100644 +index 7100934a..07dc6b34 100644 --- a/mt76.h +++ b/mt76.h @@ -29,6 +29,8 @@ @@ -29,7 +29,7 @@ index 29e0b19..b6292e3 100644 #define MT_QFLAG_WED_TYPE GENMASK(4, 2) #define MT_QFLAG_WED BIT(5) diff --git a/mt7915/mac.c b/mt7915/mac.c -index 3f907e6..02f794d 100644 +index 3f907e61..02f794d4 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -940,7 +940,7 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) @@ -64,7 +64,7 @@ index 3f907e6..02f794d 100644 msdu); diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index c75db44..d9d4fea 100644 +index 8733a07d..e856f37f 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -2509,6 +2509,9 @@ mt7915_mcu_init_rx_airtime(struct mt7915_dev *dev) @@ -89,7 +89,7 @@ index c75db44..d9d4fea 100644 return mt76_mcu_send_msg(&dev->mt76, MCU_WA_PARAM_CMD(SET), &req, diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 3391a94..6309dd9 100644 +index baf35a53..6ade056a 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -695,11 +695,14 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, @@ -119,7 +119,7 @@ index 3391a94..6309dd9 100644 ret = dma_set_mask(wed->dev, DMA_BIT_MASK(32)); if (ret) diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 38d39c8..c5bacf8 100644 +index 731f5f3e..61500841 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h @@ -62,7 +62,9 @@ @@ -134,7 +134,7 @@ index 38d39c8..c5bacf8 100644 #define MT7915_RX_TOKEN_SIZE 4096 diff --git a/tx.c b/tx.c -index 92afbf5..df2bb07 100644 +index 92afbf5d..df2bb07d 100644 --- a/tx.c +++ b/tx.c @@ -828,7 +828,7 @@ int mt76_token_consume(struct mt76_dev *dev, struct mt76_txwi_cache **ptxwi, @@ -189,7 +189,7 @@ index 92afbf5..df2bb07 100644 if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR && diff --git a/wed.c b/wed.c -index 70e4057..5ed681e 100644 +index 70e40575..5ed681ed 100644 --- a/wed.c +++ b/wed.c @@ -118,7 +118,7 @@ int mt76_wed_offload_enable(struct mtk_wed_device *wed) diff --git a/feeds/mediatek-sdk/mt76/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch b/feeds/mediatek-sdk/mt76/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch index 9b8620543..7854dec07 100644 --- a/feeds/mediatek-sdk/mt76/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch +++ b/feeds/mediatek-sdk/mt76/patches/2012-wifi-mt76-mt7915-wed-add-per-bss-statistic-info.patch @@ -1,7 +1,7 @@ -From 4e0a12871b8c134c99bd702f425c492ddc1f50b6 Mon Sep 17 00:00:00 2001 +From c9a8c7cdd9a5e042dc691fb70c24d4ee6832f297 Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Wed, 1 Nov 2023 07:50:08 +0800 -Subject: [PATCH 1/5] wifi: mt76: mt7915: wed: add per bss statistic info +Subject: [PATCH 2012/2015] wifi: mt76: mt7915: wed: add per bss statistic info --- mt7915/init.c | 1 + @@ -14,10 +14,10 @@ Subject: [PATCH 1/5] wifi: mt76: mt7915: wed: add per bss statistic info 7 files changed, 81 insertions(+), 7 deletions(-) diff --git a/mt7915/init.c b/mt7915/init.c -index f38c8a1..7bc8039 100644 +index 7f210669..26dc1a7a 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -400,6 +400,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) +@@ -401,6 +401,7 @@ mt7915_init_wiphy(struct mt7915_phy *phy) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); @@ -26,7 +26,7 @@ index f38c8a1..7bc8039 100644 if (!is_mt7915(&dev->mt76)) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR); diff --git a/mt7915/mac.c b/mt7915/mac.c -index 02f794d..0c12170 100644 +index 02f794d4..0c121700 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -1071,6 +1071,7 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) @@ -79,10 +79,10 @@ index 02f794d..0c12170 100644 spin_lock_bh(&phy->stats_lock); } diff --git a/mt7915/main.c b/mt7915/main.c -index feb2c89..722635e 100644 +index ecfd9307..802d9e6f 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -1219,6 +1219,9 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, +@@ -1231,6 +1231,9 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, struct rate_info *txrate = &msta->wcid.rate; struct rate_info rxrate = {}; @@ -92,7 +92,7 @@ index feb2c89..722635e 100644 if (is_connac_v2(&phy->dev->mt76) && !mt7915_mcu_get_rx_rate(phy, vif, sta, &rxrate)) { sinfo->rxrate = rxrate; -@@ -1247,7 +1250,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, +@@ -1259,7 +1262,7 @@ static void mt7915_sta_statistics(struct ieee80211_hw *hw, sinfo->tx_bytes = msta->wcid.stats.tx_bytes; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); @@ -102,7 +102,7 @@ index feb2c89..722635e 100644 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); } diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index 708e7cd..342fe42 100644 +index e856f37f..a1b4afee 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -4750,7 +4750,8 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev, @@ -153,7 +153,7 @@ index 708e7cd..342fe42 100644 out: dev_kfree_skb(skb); diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 6309dd9..142f308 100644 +index 6ade056a..ab807369 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c @@ -592,7 +592,7 @@ static void mt7915_mmio_wed_update_rx_stats(struct mtk_wed_device *wed, @@ -199,10 +199,10 @@ index 6309dd9..142f308 100644 } diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h -index 945c82e..6e7ed9e 100644 +index 61500841..5e7b7ebe 100644 --- a/mt7915/mt7915.h +++ b/mt7915/mt7915.h -@@ -756,7 +756,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, +@@ -771,7 +771,8 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct rate_info *rate); int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, struct cfg80211_chan_def *chandef); @@ -213,7 +213,7 @@ index 945c82e..6e7ed9e 100644 int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set); int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index c63bf90..2c9f198 100644 +index d64a3aec..c4eb7368 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -4034,7 +4034,7 @@ static int mt7915_reset_counter(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/2013-wifi-mt76-add-debugfs-for-tx-drop-counters.patch b/feeds/mediatek-sdk/mt76/patches/2013-wifi-mt76-add-debugfs-for-tx-drop-counters.patch index c958da626..19fb831c8 100644 --- a/feeds/mediatek-sdk/mt76/patches/2013-wifi-mt76-add-debugfs-for-tx-drop-counters.patch +++ b/feeds/mediatek-sdk/mt76/patches/2013-wifi-mt76-add-debugfs-for-tx-drop-counters.patch @@ -1,7 +1,7 @@ -From 2472b924a409ae452065cd5726c5020cfa442698 Mon Sep 17 00:00:00 2001 +From 86545609cc73f064e34e6783175b502623e08217 Mon Sep 17 00:00:00 2001 From: Peter Chiu Date: Mon, 18 Mar 2024 14:16:34 +0800 -Subject: [PATCH 2013/2014] wifi: mt76: add debugfs for tx drop counters +Subject: [PATCH 2013/2015] wifi: mt76: add debugfs for tx drop counters Signed-off-by: Peter Chiu --- @@ -13,7 +13,7 @@ Signed-off-by: Peter Chiu 5 files changed, 99 insertions(+), 8 deletions(-) diff --git a/dma.c b/dma.c -index d17fc88..da3e8bc 100644 +index d17fc88c..da3e8bc3 100644 --- a/dma.c +++ b/dma.c @@ -612,13 +612,18 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q, @@ -96,7 +96,7 @@ index d17fc88..da3e8bc 100644 } diff --git a/mt76.h b/mt76.h -index b6292e3..c1128d1 100644 +index 07dc6b34..08f1a7ce 100644 --- a/mt76.h +++ b/mt76.h @@ -849,6 +849,27 @@ struct mt76_vif { @@ -136,7 +136,7 @@ index b6292e3..c1128d1 100644 struct mt76_dev { diff --git a/mt7915/mac.c b/mt7915/mac.c -index 0c12170..1e2ef8c 100644 +index 0c121700..1e2ef8c0 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -782,9 +782,15 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, @@ -176,7 +176,7 @@ index 0c12170..1e2ef8c 100644 t->jiffies = jiffies; diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 129a4dd..568ecff 100644 +index c4eb7368..abb09b76 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -4033,6 +4033,12 @@ static int mt7915_reset_counter(void *data, u64 val) @@ -239,7 +239,7 @@ index 129a4dd..568ecff 100644 + #endif diff --git a/tx.c b/tx.c -index df2bb07..e4eb74b 100644 +index df2bb07d..e4eb74b7 100644 --- a/tx.c +++ b/tx.c @@ -330,8 +330,10 @@ mt76_tx(struct mt76_phy *phy, struct ieee80211_sta *sta, diff --git a/feeds/mediatek-sdk/mt76/patches/2014-wifi-mt76-add-debugfs-for-rx-drop-counters.patch b/feeds/mediatek-sdk/mt76/patches/2014-wifi-mt76-add-debugfs-for-rx-drop-counters.patch index 276e8890a..248ddd3c3 100644 --- a/feeds/mediatek-sdk/mt76/patches/2014-wifi-mt76-add-debugfs-for-rx-drop-counters.patch +++ b/feeds/mediatek-sdk/mt76/patches/2014-wifi-mt76-add-debugfs-for-rx-drop-counters.patch @@ -1,7 +1,7 @@ -From 26fb1344b791a77c86f15a3f2f96aa07d68efea3 Mon Sep 17 00:00:00 2001 +From 8c618a9481eb07cd9699cb6266d34b6fd485f44a Mon Sep 17 00:00:00 2001 From: Peter Chiu -Date: Wed, 20 Mar 2024 15:14:20 +0800 -Subject: [PATCH 2014/2014] wifi: mt76: add debugfs for rx drop counters +Date: Thu, 23 May 2024 02:33:47 +0800 +Subject: [PATCH 2014/2015] wifi: mt76: add debugfs for rx drop counters Signed-off-by: Peter Chiu --- @@ -15,7 +15,7 @@ Signed-off-by: Peter Chiu 7 files changed, 140 insertions(+), 13 deletions(-) diff --git a/agg-rx.c b/agg-rx.c -index 07c386c..97a963a 100644 +index 07c386c7..97a963ad 100644 --- a/agg-rx.c +++ b/agg-rx.c @@ -151,6 +151,7 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames) @@ -52,7 +52,7 @@ index 07c386c..97a963a 100644 } diff --git a/dma.c b/dma.c -index da3e8bc..782463f 100644 +index da3e8bc3..782463f6 100644 --- a/dma.c +++ b/dma.c @@ -251,13 +251,16 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, @@ -158,7 +158,7 @@ index da3e8bc..782463f 100644 skb_reserve(skb, q->buf_offset); diff --git a/dma.h b/dma.h -index 619dc0f..6b2ee7e 100644 +index 619dc0fe..6b2ee7ec 100644 --- a/dma.h +++ b/dma.h @@ -92,27 +92,29 @@ mt76_dma_reset_tx_queue(struct mt76_dev *dev, struct mt76_queue *q) @@ -198,10 +198,10 @@ index 619dc0f..6b2ee7e 100644 #endif diff --git a/mac80211.c b/mac80211.c -index 225b290..0360172 100644 +index e50c68f8..e01ce59a 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -774,6 +774,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q) +@@ -775,6 +775,7 @@ static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q) } if (ether_addr_equal(skb->data + offset, rfc1042_header)) { @@ -209,7 +209,7 @@ index 225b290..0360172 100644 dev_kfree_skb(skb); return; } -@@ -811,6 +812,7 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) +@@ -812,6 +813,7 @@ void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb) if (!test_bit(MT76_STATE_RUNNING, &phy->state)) { dev_kfree_skb(skb); @@ -217,7 +217,7 @@ index 225b290..0360172 100644 return; } -@@ -1048,6 +1050,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, +@@ -1049,6 +1051,7 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr = mt76_skb_get_hdr(skb); @@ -225,7 +225,7 @@ index 225b290..0360172 100644 struct mt76_rx_status mstat; mstat = *((struct mt76_rx_status *)skb->cb); -@@ -1090,6 +1093,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, +@@ -1091,6 +1094,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, *sta = wcid_to_sta(mstat.wcid); *hw = mt76_phy_hw(dev, mstat.phy_idx); @@ -236,7 +236,7 @@ index 225b290..0360172 100644 static void diff --git a/mt76.h b/mt76.h -index c1128d1..9be17b7 100644 +index 08f1a7ce..32327d3b 100644 --- a/mt76.h +++ b/mt76.h @@ -175,6 +175,33 @@ enum mt76_dfs_state { @@ -272,7 +272,7 @@ index c1128d1..9be17b7 100644 + struct mt76_queue_buf { dma_addr_t addr; - u16 len; + u16 len:15, @@ -243,6 +270,8 @@ struct mt76_queue { dma_addr_t desc_dma; struct sk_buff *rx_head; @@ -305,7 +305,7 @@ index c1128d1..9be17b7 100644 struct mt76_dev { diff --git a/mt7915/mac.c b/mt7915/mac.c -index 1e2ef8c..195b5f6 100644 +index 1e2ef8c0..195b5f62 100644 --- a/mt7915/mac.c +++ b/mt7915/mac.c @@ -1175,9 +1175,11 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q, @@ -342,7 +342,7 @@ index 1e2ef8c..195b5f6 100644 break; } diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c -index 568ecff..c9b58a2 100644 +index abb09b76..5413291a 100644 --- a/mt7915/mtk_debugfs.c +++ b/mt7915/mtk_debugfs.c @@ -4032,9 +4032,12 @@ static int mt7915_reset_counter(void *data, u64 val) diff --git a/feeds/mediatek-sdk/mt76/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch b/feeds/mediatek-sdk/mt76/patches/2015-wifi-mt76-mt7915-support-backaward-compatiable.patch similarity index 58% rename from feeds/mediatek-sdk/mt76/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch rename to feeds/mediatek-sdk/mt76/patches/2015-wifi-mt76-mt7915-support-backaward-compatiable.patch index 0f02b1c9f..38f87932d 100644 --- a/feeds/mediatek-sdk/mt76/patches/2999-wifi-mt76-mt7915-support-backaward-compatiable.patch +++ b/feeds/mediatek-sdk/mt76/patches/2015-wifi-mt76-mt7915-support-backaward-compatiable.patch @@ -1,18 +1,25 @@ -From e07f14144b386dcaece92fac81054e90e0e4d2a7 Mon Sep 17 00:00:00 2001 +From 7ffe99cbb4f483798a59bb617caa972046d8eb23 Mon Sep 17 00:00:00 2001 From: Rex Lu Date: Mon, 11 Dec 2023 19:21:16 +0800 Subject: [PATCH] wifi: mt76: mt7915: support backaward compatiable --- - mt7915/mmio.c | 4 ++-- + mt7915/mmio.c | 8 ++++---- wed.c | 2 +- - 2 files changed, 3 insertions(+), 3 deletions(-) + 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mt7915/mmio.c b/mt7915/mmio.c -index 142f308..11db3ed 100644 +index ab80736..83257e4 100644 --- a/mt7915/mmio.c +++ b/mt7915/mmio.c -@@ -697,7 +697,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, +@@ -691,13 +691,13 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, + MT_INT_WED_MASK_CSR; + wed->wlan.wpdma_phys = pci_resource_start(pci_dev, 0) + + MT_WFDMA_EXT_CSR_BASE; +- wed->wlan.wpdma_tx = pci_resource_start(pci_dev, 0) + ++ wed->wlan.wpdma_tx[0] = pci_resource_start(pci_dev, 0) + + MT_TXQ_WED_RING_BASE; + wed->wlan.wpdma_txfree = pci_resource_start(pci_dev, 0) + MT_RXQ_WED_RING_BASE; wed->wlan.wpdma_rx_glo = pci_resource_start(pci_dev, 0) + MT_WPDMA_GLO_CFG; @@ -21,8 +28,12 @@ index 142f308..11db3ed 100644 MT_RXQ_WED_DATA_RING_BASE; } else { struct platform_device *plat_dev = pdev_ptr; -@@ -717,7 +717,7 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, - wed->wlan.wpdma_tx = res->start + MT_TXQ_WED_RING_BASE; +@@ -714,10 +714,10 @@ int mt7915_mmio_wed_init(struct mt7915_dev *dev, void *pdev_ptr, + wed->wlan.phy_base = res->start; + wed->wlan.wpdma_int = res->start + MT_INT_SOURCE_CSR; + wed->wlan.wpdma_mask = res->start + MT_INT_MASK_CSR; +- wed->wlan.wpdma_tx = res->start + MT_TXQ_WED_RING_BASE; ++ wed->wlan.wpdma_tx[0] = res->start + MT_TXQ_WED_RING_BASE; wed->wlan.wpdma_txfree = res->start + MT_RXQ_WED_RING_BASE; wed->wlan.wpdma_rx_glo = res->start + MT_WPDMA_GLO_CFG; - wed->wlan.wpdma_rx = res->start + MT_RXQ_WED_DATA_RING_BASE; @@ -44,5 +55,5 @@ index 5ed681e..652f59e 100644 q->head = q->ndesc - 1; q->queued = q->head; -- -2.18.0 +2.45.2 diff --git a/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-fix-key-used-after-free-issue.patch b/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-fix-key-used-after-free-issue.patch new file mode 100644 index 000000000..b9ac67994 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-fix-key-used-after-free-issue.patch @@ -0,0 +1,30 @@ +From 4753d2a36d752d0499b26814c133717442b99384 Mon Sep 17 00:00:00 2001 +From: Michael-CY Lee +Date: Wed, 30 Oct 2024 17:44:53 +0800 +Subject: [PATCH] mtk: mt76: mt7915: fix key used-after-free issue + +Fix the issue that the key might be used in TX path after being freed. + +CR-Id: WCNCR00289305 +Signed-off-by: Michael-CY Lee +--- + mt76_connac_mac.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c +index b80872e..a1a9e5d 100644 +--- a/mt76_connac_mac.c ++++ b/mt76_connac_mac.c +@@ -433,8 +433,7 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, + FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) | + FIELD_PREP(MT_TXD2_MULTICAST, multicast); + +- if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) && +- key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { ++ if (key && multicast && ieee80211_is_robust_mgmt_frame(skb)) { + val |= MT_TXD2_BIP; + txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); + } +-- +2.25.1 + diff --git a/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-refine-twt-mcu-update-flow.patch b/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-refine-twt-mcu-update-flow.patch new file mode 100644 index 000000000..fb8587e14 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/2016-wifi-mt76-mt7915-refine-twt-mcu-update-flow.patch @@ -0,0 +1,94 @@ +From 174faa97cf0fdc8f26e4b8c13fd3c4b8d19ced15 Mon Sep 17 00:00:00 2001 +From: Yi-Chia Hsieh +Date: Wed, 9 Oct 2024 23:13:29 +0000 +Subject: [PATCH] wifi: mt76: mt7915: refine twt mcu update flow + +Fix potential issue that if the twt mcu update command fail, the twt_list entry +is not undo and will remain in the list. Also, remove unecessary parameter for +twt delete flow. + +Signed-off-by: Yi-Chia Hsieh +--- + mt7915/debugfs.c | 4 ++-- + mt7915/mac.c | 4 +++- + mt7915/mcu.c | 22 ++++++++++++---------- + 3 files changed, 17 insertions(+), 13 deletions(-) + +diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c +index 72867ff..462e167 100644 +--- a/mt7915/debugfs.c ++++ b/mt7915/debugfs.c +@@ -1758,7 +1758,7 @@ mt7915_twt_stats(struct seq_file *s, void *data) + struct mt7915_dev *dev = dev_get_drvdata(s->private); + struct mt7915_twt_flow *iter; + +- rcu_read_lock(); ++ mutex_lock(&dev->mt76.mutex); + + seq_puts(s, " wcid | id | flags | exp | mantissa"); + seq_puts(s, " | duration | tsf |\n"); +@@ -1773,7 +1773,7 @@ mt7915_twt_stats(struct seq_file *s, void *data) + iter->exp, iter->mantissa, + iter->duration, iter->tsf); + +- rcu_read_unlock(); ++ mutex_unlock(&dev->mt76.mutex); + + return 0; + } +diff --git a/mt7915/mac.c b/mt7915/mac.c +index 4e7dae7..321a57d 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -2555,8 +2555,10 @@ void mt7915_mac_add_twt_setup(struct ieee80211_hw *hw, + } + flow->tsf = le64_to_cpu(twt_agrt->twt); + +- if (mt7915_mcu_twt_agrt_update(dev, msta->vif, flow, MCU_TWT_AGRT_ADD)) ++ if (mt7915_mcu_twt_agrt_update(dev, msta->vif, flow, MCU_TWT_AGRT_ADD)) { ++ list_del(&flow->list); + goto unlock; ++ } + + setup_cmd = TWT_SETUP_CMD_ACCEPT; + dev->twt.table_mask |= BIT(table_id); +diff --git a/mt7915/mcu.c b/mt7915/mcu.c +index 2c5943b..25ac312 100644 +--- a/mt7915/mcu.c ++++ b/mt7915/mcu.c +@@ -4811,20 +4811,22 @@ int mt7915_mcu_twt_agrt_update(struct mt7915_dev *dev, + .own_mac_idx = mvif->mt76.omac_idx, + .flowid = flow->id, + .peer_id = cpu_to_le16(flow->wcid), +- .duration = flow->duration, + .bss_idx = mvif->mt76.idx, +- .start_tsf = cpu_to_le64(flow->tsf), +- .mantissa = flow->mantissa, +- .exponent = flow->exp, + .is_ap = true, + }; + +- if (flow->protection) +- req.agrt_params |= TWT_AGRT_PROTECT; +- if (!flow->flowtype) +- req.agrt_params |= TWT_AGRT_ANNOUNCE; +- if (flow->trigger) +- req.agrt_params |= TWT_AGRT_TRIGGER; ++ if (cmd == MCU_TWT_AGRT_ADD) { ++ req.start_tsf = cpu_to_le64(flow->tsf); ++ req.mantissa = flow->mantissa; ++ req.exponent = flow->exp; ++ req.duration = flow->duration; ++ if (flow->protection) ++ req.agrt_params |= TWT_AGRT_PROTECT; ++ if (!flow->flowtype) ++ req.agrt_params |= TWT_AGRT_ANNOUNCE; ++ if (flow->trigger) ++ req.agrt_params |= TWT_AGRT_TRIGGER; ++ } + + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TWT_AGRT_UPDATE), + &req, sizeof(req), true); +-- +2.18.0 + diff --git a/feeds/mediatek-sdk/mt76/patches/2017-wifi-mt76-mt7915-add-sanity-check-to-prevent-invalid.patch b/feeds/mediatek-sdk/mt76/patches/2017-wifi-mt76-mt7915-add-sanity-check-to-prevent-invalid.patch new file mode 100644 index 000000000..85ad8584c --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/2017-wifi-mt76-mt7915-add-sanity-check-to-prevent-invalid.patch @@ -0,0 +1,31 @@ +From c317d43586c49cf0ff9fcf8f3ad2235b616468e7 Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Thu, 9 Jan 2025 09:29:54 +0800 +Subject: [PATCH] wifi: mt76: mt7915: add sanity check to prevent invalid wlan + id in txfree + +Invalid wlan id would lead to kernel crash. +To prevent this issue, stop parsing txfree if wlan id is out of range. + +Signed-off-by: Peter Chiu +--- + mt7915/mac.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/mt7915/mac.c b/mt7915/mac.c +index 0d77d7f..5b6649f 100644 +--- a/mt7915/mac.c ++++ b/mt7915/mac.c +@@ -943,6 +943,9 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) + u16 idx; + + idx = FIELD_GET(MT_TX_FREE_WLAN_ID, info); ++ if (idx >= mt7915_wtbl_size(dev)) ++ return; ++ + wcid = rcu_dereference(dev->mt76.wcid[idx]); + sta = wcid_to_sta(wcid); + if (!sta) +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/2018-wifi-mt76-mt7915-add-debugfs-knob-to-control-ps-ther.patch b/feeds/mediatek-sdk/mt76/patches/2018-wifi-mt76-mt7915-add-debugfs-knob-to-control-ps-ther.patch new file mode 100644 index 000000000..ce7a90d83 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/2018-wifi-mt76-mt7915-add-debugfs-knob-to-control-ps-ther.patch @@ -0,0 +1,118 @@ +From ddf61fb2c9dcc5c4187b03c29f4ff128d6440d96 Mon Sep 17 00:00:00 2001 +From: Peter Chiu +Date: Tue, 21 Jan 2025 16:37:58 +0800 +Subject: [PATCH] wifi: mt76: mt7915: add debugfs knob to control ps thershold + +--- + mt76_connac_mcu.c | 4 +++- + mt76_connac_mcu.h | 1 + + mt7915/mcu.c | 22 ++++++++++++++++++++++ + mt7915/mt7915.h | 1 + + mt7915/mtk_debugfs.c | 15 +++++++++++++++ + 5 files changed, 42 insertions(+), 1 deletion(-) + +diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c +index aee9b5bf..5971f646 100644 +--- a/mt76_connac_mcu.c ++++ b/mt76_connac_mcu.c +@@ -3115,7 +3115,9 @@ int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb, + mcu_txd->set_query = MCU_Q_NA; + } + +- if (cmd & __MCU_CMD_FIELD_WA) ++ if (cmd == MCU_EXT_CMD(PS_CTRL)) ++ mcu_txd->s2d_index = MCU_S2D_H2CN; ++ else if (cmd & __MCU_CMD_FIELD_WA) + mcu_txd->s2d_index = MCU_S2D_H2C; + else + mcu_txd->s2d_index = MCU_S2D_H2N; +diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h +index 3d00961c..44a56b42 100644 +--- a/mt76_connac_mcu.h ++++ b/mt76_connac_mcu.h +@@ -1198,6 +1198,7 @@ enum { + MCU_EXT_CMD_ID_RADIO_ON_OFF_CTRL = 0x05, + MCU_EXT_CMD_PM_STATE_CTRL = 0x07, + MCU_EXT_CMD_CHANNEL_SWITCH = 0x08, ++ MCU_EXT_CMD_PS_CTRL = 0x0f, + MCU_EXT_CMD_SET_TX_POWER_CTRL = 0x11, + MCU_EXT_CMD_FW_LOG_2_HOST = 0x13, + MCU_EXT_CMD_TXBF_ACTION = 0x1e, +diff --git a/mt7915/mcu.c b/mt7915/mcu.c +index 90983870..61fa4d76 100644 +--- a/mt7915/mcu.c ++++ b/mt7915/mcu.c +@@ -5964,3 +5964,25 @@ int mt7915_mcu_thermal_debug(struct mt7915_dev *dev, u8 mode, u8 action) + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_DEBUG), &req, + sizeof(req), true); + } ++ ++int mt7915_mcu_set_ps_ctrl(struct mt7915_dev *dev, u16 threshold) ++{ ++ struct { ++ __le16 per_sta_threshold; ++ __le16 flush_threshold; ++ u8 enable; ++ u8 rsv[3]; ++ } req = { ++ .enable = true, ++ .per_sta_threshold = cpu_to_le16(threshold), ++ }; ++ u16 thresh = dev->mt76.token_size; ++ ++ if (mtk_wed_device_active(&dev->mt76.mmio.wed)) ++ thresh += dev->mt76.mmio.wed.wlan.nbuf; ++ ++ req.flush_threshold = cpu_to_le16(thresh * 4 / 5); ++ ++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(PS_CTRL), &req, ++ sizeof(req), true); ++} +diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h +index f23498e0..65dd347f 100644 +--- a/mt7915/mt7915.h ++++ b/mt7915/mt7915.h +@@ -917,6 +917,7 @@ int mt7915_mcu_enable_obss_spr(struct mt7915_phy *phy, u8 action, u8 val); + int mt7915_mcu_set_scs_en(struct mt7915_phy *phy, u8 enable); + void mt7915_mcu_scs_sta_poll(struct work_struct *work); + int mt7915_mcu_thermal_debug(struct mt7915_dev *dev, u8 mode, u8 action); ++int mt7915_mcu_set_ps_ctrl(struct mt7915_dev *dev, u16 threshold); + + #ifdef MTK_DEBUG + int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir); +diff --git a/mt7915/mtk_debugfs.c b/mt7915/mtk_debugfs.c +index b0860ffb..5a28d103 100644 +--- a/mt7915/mtk_debugfs.c ++++ b/mt7915/mtk_debugfs.c +@@ -4007,6 +4007,20 @@ mt7915_thermal_recal_set(void *data, u64 val) + DEFINE_DEBUGFS_ATTRIBUTE(fops_thermal_recal, NULL, + mt7915_thermal_recal_set, "%llu\n"); + ++static int ++mt7915_ps_ctrl_set(void *data, u64 val) ++{ ++ struct mt7915_dev *dev = data; ++ ++ if (val > 0xffff) ++ return -EINVAL; ++ ++ return mt7915_mcu_set_ps_ctrl(dev, val); ++} ++ ++DEFINE_DEBUGFS_ATTRIBUTE(fops_ps_ctrl, NULL, ++ mt7915_ps_ctrl_set, "%llu\n"); ++ + static int + mt7915_sr_stats_show(struct seq_file *file, void *data) + { +@@ -4271,6 +4285,7 @@ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir) + debugfs_create_devm_seqfile(dev->mt76.dev, "per", dir, mt7915_per_read); + debugfs_create_file("tx_drop_stats", 0400, dir, phy, &mt7915_tx_drop_fops); + debugfs_create_file("rx_drop_stats", 0400, dir, phy, &mt7915_rx_drop_fops); ++ debugfs_create_file("ps_ctrl", 0200, dir, dev, &fops_ps_ctrl); + + return 0; + } +-- +2.45.2 + diff --git a/feeds/mediatek-sdk/mt76/patches/2019-wifi-mt76-mt7915-do-not-set-key-for-cipher-CMAC-128.patch b/feeds/mediatek-sdk/mt76/patches/2019-wifi-mt76-mt7915-do-not-set-key-for-cipher-CMAC-128.patch new file mode 100644 index 000000000..0d1fa9235 --- /dev/null +++ b/feeds/mediatek-sdk/mt76/patches/2019-wifi-mt76-mt7915-do-not-set-key-for-cipher-CMAC-128.patch @@ -0,0 +1,33 @@ +From a3e76cf4df52c3ad728b85acd0fbd0436c226dea Mon Sep 17 00:00:00 2001 +From: Michael-CY Lee +Date: Wed, 4 Jun 2025 16:33:38 +0800 +Subject: [PATCH 1/2] mtk: mt76: mt7915: do not set key for cipher CMAC-128 + +Although FW does support setting IGTK for cipher CMAC, it does not +support setting IGTK for GMAC, which requires MAC80211 to perform +the MIC calculation for BMC management frames. + +As discussed, we decided not to set IGTK to FW for consistency +between each cipher. +--- + mt7915/main.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/mt7915/main.c b/mt7915/main.c +index de65994..5fe4872 100644 +--- a/mt7915/main.c ++++ b/mt7915/main.c +@@ -431,10 +431,6 @@ static int mt7915_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + + /* fall back to sw encryption for unsupported ciphers */ + switch (key->cipher) { +- case WLAN_CIPHER_SUITE_AES_CMAC: +- wcid_keyidx = &wcid->hw_key_idx2; +- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIE; +- break; + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_CCMP_256: +-- +2.25.1 + diff --git a/feeds/mediatek-sdk/mt76/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch b/feeds/mediatek-sdk/mt76/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch index 6b5c0ff1a..45384b665 100644 --- a/feeds/mediatek-sdk/mt76/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch +++ b/feeds/mediatek-sdk/mt76/patches/9999-mt76-revert-for-backports-5.15-wireless-stack.patch @@ -1,28 +1,47 @@ -From 1d5c74a1bf5717880ae08ba8232756a86bd28b5e Mon Sep 17 00:00:00 2001 +From 11e3e70081093c00c8ba414f4b92207b9a4d880a Mon Sep 17 00:00:00 2001 From: Evelyn Tsai Date: Wed, 5 Apr 2023 08:29:19 +0800 -Subject: [PATCH] mt76: revert for backports-5.15 wireless stack +Subject: [PATCH 2/2] mt76: revert for backports-5.15 wireless stack wifi: mt76: mt7915: add support for he ldpc control from hostapd +wifi: mt76: only include mt76_connac3_mac for WiFi7 chipsets --- + Makefile | 6 +- dma.c | 2 +- - mac80211.c | 15 +-- + mac80211.c | 19 ++-- mt7615/dma.c | 4 +- mt7615/main.c | 6 +- - mt7615/mcu.c | 8 +- + mt7615/mcu.c | 6 +- mt76_connac_mac.c | 2 +- mt76_connac_mcu.c | 119 ++++++++++------------ mt76x02_mac.c | 6 +- mt7915/debugfs.c | 4 +- mt7915/dma.c | 4 +- - mt7915/init.c | 3 +- - mt7915/main.c | 36 ++----- - mt7915/mcu.c | 246 ++++++++++++++++++++++++++++++---------------- + mt7915/init.c | 12 ++- + mt7915/main.c | 40 ++------ + mt7915/mcu.c | 252 ++++++++++++++++++++++++++++++---------------- mt7915/testmode.c | 8 +- - tx.c | 22 ++--- + tx.c | 22 ++-- wed.c | 1 + - 16 files changed, 260 insertions(+), 226 deletions(-) + 17 files changed, 275 insertions(+), 238 deletions(-) +diff --git a/Makefile b/Makefile +index 5352d00..073e37d 100644 +--- a/Makefile ++++ b/Makefile +@@ -31,7 +31,11 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ + + mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o + +-mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o ++mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o ++ ++ifeq ($(or $(CONFIG_MT7996E),$(CONFIG_MT7925_COMMON)),y) ++mt76-connac-lib-y += mt76_connac3_mac.o ++endif + + mt792x-lib-y := mt792x_core.o mt792x_mac.o mt792x_trace.o \ + mt792x_debugfs.o mt792x_dma.o diff --git a/dma.c b/dma.c index 782463f..39fafce 100644 --- a/dma.c @@ -37,10 +56,10 @@ index 782463f..39fafce 100644 napi_enable(&dev->napi[i]); } diff --git a/mac80211.c b/mac80211.c -index 0360172..2d0e9a8 100644 +index 018416d..571a1f5 100644 --- a/mac80211.c +++ b/mac80211.c -@@ -1061,14 +1061,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, +@@ -1062,14 +1062,9 @@ mt76_rx_convert(struct mt76_dev *dev, struct sk_buff *skb, status->enc_flags = mstat.enc_flags; status->encoding = mstat.encoding; status->bw = mstat.bw; @@ -58,16 +77,18 @@ index 0360172..2d0e9a8 100644 status->rate_idx = mstat.rate_idx; status->nss = mstat.nss; status->band = mstat.band; -@@ -1591,7 +1586,7 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power); +@@ -1592,8 +1587,8 @@ EXPORT_SYMBOL_GPL(mt76_get_sar_power); static void __mt76_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { -- if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) +- if (vif->bss_conf.csa_active && ieee80211_beacon_cntdwn_is_complete(vif, 0)) +- ieee80211_csa_finish(vif, 0); + if (vif->csa_active && ieee80211_beacon_cntdwn_is_complete(vif)) - ieee80211_csa_finish(vif); ++ ieee80211_csa_finish(vif); } -@@ -1613,7 +1608,7 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif) + void mt76_csa_finish(struct mt76_dev *dev) +@@ -1614,10 +1609,10 @@ __mt76_csa_check(void *priv, u8 *mac, struct ieee80211_vif *vif) { struct mt76_dev *dev = priv; @@ -75,7 +96,11 @@ index 0360172..2d0e9a8 100644 + if (!vif->csa_active) return; - dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif); +- dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif, 0); ++ dev->csa_complete |= ieee80211_beacon_cntdwn_is_complete(vif); + } + + void mt76_csa_check(struct mt76_dev *dev) diff --git a/mt7615/dma.c b/mt7615/dma.c index e7135b2..6767c39 100644 --- a/mt7615/dma.c @@ -92,7 +117,7 @@ index e7135b2..6767c39 100644 mt76_poll(dev, MT_WPDMA_GLO_CFG, diff --git a/mt7615/main.c b/mt7615/main.c -index dab16b5..d32a752 100644 +index c27acaf..1bdd703 100644 --- a/mt7615/main.c +++ b/mt7615/main.c @@ -473,7 +473,7 @@ static int mt7615_config(struct ieee80211_hw *hw, u32 changed) @@ -123,18 +148,9 @@ index dab16b5..d32a752 100644 if (changed & BSS_CHANGED_MU_GROUPS) mt7615_update_mu_group(hw, vif, info); diff --git a/mt7615/mcu.c b/mt7615/mcu.c -index c9444c6..466f38e 100644 +index a931066..c76594d 100644 --- a/mt7615/mcu.c +++ b/mt7615/mcu.c -@@ -353,7 +353,7 @@ out: - static void - mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) - { -- if (vif->bss_conf.csa_active) -+ if (vif->csa_active) - ieee80211_csa_finish(vif); - } - @@ -699,7 +699,7 @@ mt7615_mcu_add_beacon_offload(struct mt7615_dev *dev, if (!enable) goto out; @@ -163,10 +179,10 @@ index c9444c6..466f38e 100644 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int), }; diff --git a/mt76_connac_mac.c b/mt76_connac_mac.c -index 0510296..edeb618 100644 +index a89cb30..b6fd6e4 100644 --- a/mt76_connac_mac.c +++ b/mt76_connac_mac.c -@@ -1124,7 +1124,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) +@@ -1155,7 +1155,7 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi) u32 val; if (!sta || @@ -176,7 +192,7 @@ index 0510296..edeb618 100644 tid = le32_get_bits(txwi[1], MT_TXD1_TID); diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c -index 15e61c9..dd23643 100644 +index fcab950..025197c 100644 --- a/mt76_connac_mcu.c +++ b/mt76_connac_mcu.c @@ -199,7 +199,7 @@ int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif) @@ -584,10 +600,10 @@ index d5db6ff..fec3d10 100644 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ba_size = 0; diff --git a/mt7915/debugfs.c b/mt7915/debugfs.c -index 76d1951..e22e777 100644 +index 453c391..4fbd029 100644 --- a/mt7915/debugfs.c +++ b/mt7915/debugfs.c -@@ -2052,8 +2052,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file, +@@ -2110,8 +2110,8 @@ static ssize_t mt7915_sta_fixed_rate_set(struct file *file, phy.ldpc = (phy.bw || phy.ldpc) * GENMASK(2, 0); for (i = 0; i <= phy.bw; i++) { @@ -614,10 +630,10 @@ index 4f9f5a3..fde6a38 100644 mt7915_dma_enable(dev, false); diff --git a/mt7915/init.c b/mt7915/init.c -index e5327be..93f706f 100644 +index 2f6ed58..fd1ecab 100644 --- a/mt7915/init.c +++ b/mt7915/init.c -@@ -1154,8 +1154,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, +@@ -1162,8 +1162,7 @@ mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band, mt76_connac_gen_ppe_thresh(he_cap->ppe_thres, nss); } else { he_cap_elem->phy_cap_info[9] |= @@ -627,11 +643,41 @@ index e5327be..93f706f 100644 } if (band == NL80211_BAND_6GHZ) { +@@ -1197,7 +1196,8 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) + n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data); + + band = &phy->mt76->sband_2g.sband; +- _ieee80211_set_sband_iftype_data(band, data, n); ++ band->iftype_data = data; ++ band->n_iftype_data = n; + } + + if (phy->mt76->cap.has_5ghz) { +@@ -1205,7 +1205,8 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) + n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data); + + band = &phy->mt76->sband_5g.sband; +- _ieee80211_set_sband_iftype_data(band, data, n); ++ band->iftype_data = data; ++ band->n_iftype_data = n; + } + + if (phy->mt76->cap.has_6ghz) { +@@ -1213,7 +1214,8 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) + n = mt7915_init_he_caps(phy, NL80211_BAND_6GHZ, data); + + band = &phy->mt76->sband_6g.sband; +- _ieee80211_set_sband_iftype_data(band, data, n); ++ band->iftype_data = data; ++ band->n_iftype_data = n; + } + } + diff --git a/mt7915/main.c b/mt7915/main.c -index 17a380b..cc4fb49 100644 +index 5fe4872..fa76cde 100644 --- a/mt7915/main.c +++ b/mt7915/main.c -@@ -547,7 +547,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) +@@ -553,7 +553,7 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed) static int mt7915_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -640,7 +686,7 @@ index 17a380b..cc4fb49 100644 const struct ieee80211_tx_queue_params *params) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; -@@ -648,7 +648,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw, +@@ -655,7 +655,7 @@ mt7915_update_bss_color(struct ieee80211_hw *hw, static void mt7915_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -649,7 +695,7 @@ index 17a380b..cc4fb49 100644 { struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw); -@@ -664,7 +664,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, +@@ -671,7 +671,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, vif->type == NL80211_IFTYPE_STATION) set_bss_info = set_sta = !is_zero_ether_addr(info->bssid); if (changed & BSS_CHANGED_ASSOC) @@ -658,7 +704,7 @@ index 17a380b..cc4fb49 100644 if (changed & BSS_CHANGED_BEACON_ENABLED && vif->type != NL80211_IFTYPE_AP) set_bss_info = set_sta = info->enable_beacon; -@@ -712,27 +712,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, +@@ -716,27 +716,8 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, mutex_unlock(&dev->mt76.mutex); } @@ -687,7 +733,7 @@ index 17a380b..cc4fb49 100644 { struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw); -@@ -740,8 +721,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, +@@ -744,8 +725,6 @@ mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); @@ -696,7 +742,7 @@ index 17a380b..cc4fb49 100644 err = mt7915_mcu_add_bss_info(phy, vif, true); if (err) goto out; -@@ -753,8 +732,7 @@ out: +@@ -757,8 +736,7 @@ out: } static void @@ -706,7 +752,7 @@ index 17a380b..cc4fb49 100644 { struct mt7915_dev *dev = mt7915_hw_dev(hw); -@@ -1374,10 +1352,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw, +@@ -1392,10 +1370,10 @@ static int mt7915_sta_set_txpwr(struct ieee80211_hw *hw, { struct mt7915_phy *phy = mt7915_hw_phy(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw); @@ -719,8 +765,19 @@ index 17a380b..cc4fb49 100644 txpower = 0; mutex_lock(&dev->mt76.mutex); +@@ -1897,10 +1875,6 @@ mt7915_net_fill_receive_path(struct ieee80211_hw *hw, + #endif + + const struct ieee80211_ops mt7915_ops = { +- .add_chanctx = ieee80211_emulate_add_chanctx, +- .remove_chanctx = ieee80211_emulate_remove_chanctx, +- .change_chanctx = ieee80211_emulate_change_chanctx, +- .switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx, + .tx = mt7915_tx, + .start = mt7915_start, + .stop = mt7915_stop, diff --git a/mt7915/mcu.c b/mt7915/mcu.c -index f0273fe..5c14114 100644 +index fcc24fd..0d476a8 100644 --- a/mt7915/mcu.c +++ b/mt7915/mcu.c @@ -67,7 +67,7 @@ mt7915_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, @@ -774,7 +831,7 @@ index f0273fe..5c14114 100644 } static int -@@ -243,7 +243,7 @@ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) +@@ -251,10 +251,10 @@ int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3) static void mt7915_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { @@ -782,8 +839,12 @@ index f0273fe..5c14114 100644 + if (!vif->csa_active || vif->type == NL80211_IFTYPE_STATION) return; - ieee80211_csa_finish(vif); -@@ -349,7 +349,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb) +- ieee80211_csa_finish(vif, 0); ++ ieee80211_csa_finish(vif); + } + + static void +@@ -372,7 +372,7 @@ mt7915_mcu_rx_log_message(struct mt7915_dev *dev, struct sk_buff *skb) static void mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif) { @@ -792,7 +853,20 @@ index f0273fe..5c14114 100644 return; ieee80211_color_change_finish(vif); -@@ -945,13 +945,13 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, +@@ -704,10 +704,10 @@ static bool mt7915_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw, + .tolerated = true, + }; + +- if (!(vif->bss_conf.chanreq.oper.chan->flags & IEEE80211_CHAN_RADAR)) ++ if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) + return false; + +- cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chanreq.oper, ++ cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef, + mt7915_check_he_obss_narrow_bw_ru_iter, + &iter_data); + +@@ -968,13 +968,13 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; @@ -808,7 +882,7 @@ index f0273fe..5c14114 100644 return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he)); -@@ -1037,8 +1037,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, +@@ -1060,8 +1060,8 @@ mt7915_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta, he->he_cap = cpu_to_le32(cap); @@ -819,7 +893,7 @@ index f0273fe..5c14114 100644 case IEEE80211_STA_RX_BW_160: if (elem->phy_cap_info[0] & IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G) -@@ -1088,7 +1088,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1111,7 +1111,7 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; @@ -828,7 +902,7 @@ index f0273fe..5c14114 100644 struct mt7915_phy *phy = mvif->phy; struct sta_rec_muru *muru; struct tlv *tlv; -@@ -1113,11 +1113,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1136,11 +1136,11 @@ mt7915_mcu_sta_muru_tlv(struct mt7915_dev *dev, struct sk_buff *skb, muru->cfg.ofdma_dl_en = !!(phy->muru_onoff & OFDMA_DL); muru->cfg.ofdma_ul_en = !!(phy->muru_onoff & OFDMA_UL); @@ -843,7 +917,7 @@ index f0273fe..5c14114 100644 return; muru->mimo_dl.partial_bw_dl_mimo = -@@ -1153,13 +1153,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +@@ -1176,13 +1176,13 @@ mt7915_mcu_sta_ht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) struct sta_rec_ht *ht; struct tlv *tlv; @@ -859,7 +933,7 @@ index f0273fe..5c14114 100644 } static void -@@ -1168,15 +1168,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) +@@ -1191,15 +1191,15 @@ mt7915_mcu_sta_vht_tlv(struct sk_buff *skb, struct ieee80211_sta *sta) struct sta_rec_vht *vht; struct tlv *tlv; @@ -879,7 +953,7 @@ index f0273fe..5c14114 100644 } static void -@@ -1191,7 +1191,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1214,7 +1214,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb, vif->type != NL80211_IFTYPE_AP) return; @@ -888,7 +962,7 @@ index f0273fe..5c14114 100644 return; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu)); -@@ -1200,7 +1200,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1223,7 +1223,7 @@ mt7915_mcu_sta_amsdu_tlv(struct mt7915_dev *dev, struct sk_buff *skb, amsdu->amsdu_en = true; msta->wcid.amsdu = true; @@ -897,7 +971,7 @@ index f0273fe..5c14114 100644 case IEEE80211_MAX_MPDU_LEN_VHT_11454: if (!is_mt7915(&dev->mt76)) { amsdu->max_mpdu_size = -@@ -1263,8 +1263,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, +@@ -1286,8 +1286,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, if (!bfee && sts < 2) return false; @@ -908,7 +982,7 @@ index f0273fe..5c14114 100644 if (bfee) return mvif->cap.he_su_ebfee && -@@ -1274,8 +1274,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, +@@ -1297,8 +1297,8 @@ mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif, HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]); } @@ -919,7 +993,7 @@ index f0273fe..5c14114 100644 if (bfee) return mvif->cap.vht_su_ebfee && -@@ -1301,7 +1301,7 @@ static void +@@ -1324,7 +1324,7 @@ static void mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7915_phy *phy, struct sta_rec_bf *bf) { @@ -928,7 +1002,7 @@ index f0273fe..5c14114 100644 u8 n = 0; bf->tx_mode = MT_PHY_TYPE_HT; -@@ -1326,7 +1326,7 @@ static void +@@ -1349,7 +1349,7 @@ static void mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy, struct sta_rec_bf *bf, bool explicit) { @@ -937,7 +1011,7 @@ index f0273fe..5c14114 100644 struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap; u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map); u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map); -@@ -1347,14 +1347,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy, +@@ -1370,14 +1370,14 @@ mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy, bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = bf->ncol; @@ -954,7 +1028,7 @@ index f0273fe..5c14114 100644 bf->ibf_nrow = 1; } } -@@ -1363,7 +1363,7 @@ static void +@@ -1386,7 +1386,7 @@ static void mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, struct mt7915_phy *phy, struct sta_rec_bf *bf) { @@ -963,7 +1037,7 @@ index f0273fe..5c14114 100644 struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem; const struct ieee80211_sta_he_cap *vc = mt76_connac_get_he_phy_cap(phy->mt76, vif); -@@ -1388,7 +1388,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, +@@ -1411,7 +1411,7 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif, bf->ncol = min_t(u8, nss_mcs, bf->nrow); bf->ibf_ncol = bf->ncol; @@ -972,7 +1046,7 @@ index f0273fe..5c14114 100644 return; /* go over for 160MHz and 80p80 */ -@@ -1436,7 +1436,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1459,7 +1459,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, }; bool ebf; @@ -981,7 +1055,7 @@ index f0273fe..5c14114 100644 return; ebf = mt7915_is_ebf_supported(phy, vif, sta, false); -@@ -1450,21 +1450,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1473,21 +1473,21 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, * vht: support eBF and iBF * ht: iBF only, since mac80211 lacks of eBF support */ @@ -1009,7 +1083,7 @@ index f0273fe..5c14114 100644 bf->ibf_timeout = 0x48; else bf->ibf_timeout = 0x18; -@@ -1474,7 +1474,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1497,7 +1497,7 @@ mt7915_mcu_sta_bfer_tlv(struct mt7915_dev *dev, struct sk_buff *skb, else bf->mem_20m = matrix[bf->nrow][bf->ncol]; @@ -1018,7 +1092,7 @@ index f0273fe..5c14114 100644 case IEEE80211_STA_RX_BW_160: case IEEE80211_STA_RX_BW_80: bf->mem_total = bf->mem_20m * 2; -@@ -1499,7 +1499,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1522,7 +1522,7 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, struct tlv *tlv; u8 nrow = 0; @@ -1027,7 +1101,7 @@ index f0273fe..5c14114 100644 return; if (!mt7915_is_ebf_supported(phy, vif, sta, true)) -@@ -1508,13 +1508,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, +@@ -1531,13 +1531,13 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb, tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee)); bfee = (struct sta_rec_bfee *)tlv; @@ -1045,7 +1119,7 @@ index f0273fe..5c14114 100644 nrow = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK, pc->cap); -@@ -1570,7 +1570,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, +@@ -1593,7 +1593,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev, ra->phy = *phy; break; case RATE_PARAM_MMPS_UPDATE: @@ -1054,7 +1128,7 @@ index f0273fe..5c14114 100644 break; case RATE_PARAM_SPE_UPDATE: ra->spe_idx = *(u8 *)data; -@@ -1646,7 +1646,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, +@@ -1669,7 +1669,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, do { \ u8 i, gi = mask->control[band]._gi; \ gi = (_he) ? gi : gi == NL80211_TXRATE_FORCE_SGI; \ @@ -1063,7 +1137,7 @@ index f0273fe..5c14114 100644 phy.sgi |= gi << (i << (_he)); \ phy.he_ltf |= mask->control[band].he_ltf << (i << (_he));\ } \ -@@ -1660,11 +1660,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, +@@ -1683,11 +1683,11 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, } \ } while (0) @@ -1078,7 +1152,7 @@ index f0273fe..5c14114 100644 __sta_phy_bitrate_mask_check(ht_mcs, gi, 1, 0); } else { nrates = hweight32(mask->control[band].legacy); -@@ -1698,7 +1698,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, +@@ -1721,7 +1721,7 @@ mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev, * actual txrate hardware sends out. */ addr = mt7915_mac_wtbl_lmac_addr(dev, msta->wcid.idx, 7); @@ -1087,7 +1161,7 @@ index f0273fe..5c14114 100644 mt76_rmw_field(dev, addr, GENMASK(31, 24), phy.sgi); else mt76_rmw_field(dev, addr, GENMASK(15, 12), phy.sgi); -@@ -1731,7 +1731,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, +@@ -1754,7 +1754,7 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, enum nl80211_band band = chandef->chan->band; struct sta_rec_ra *ra; struct tlv *tlv; @@ -1096,7 +1170,7 @@ index f0273fe..5c14114 100644 u32 cap = sta->wme ? STA_CAP_WMM : 0; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra)); -@@ -1741,9 +1741,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, +@@ -1764,9 +1764,9 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->auto_rate = true; ra->phy_mode = mt76_connac_get_phy_mode(mphy, vif, band, sta); ra->channel = chandef->chan->hw_value; @@ -1109,7 +1183,7 @@ index f0273fe..5c14114 100644 if (supp_rate) { supp_rate &= mask->control[band].legacy; -@@ -1763,22 +1763,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, +@@ -1786,22 +1786,22 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, } } @@ -1140,7 +1214,7 @@ index f0273fe..5c14114 100644 cap |= STA_CAP_LDPC; mt7915_mcu_set_sta_ht_mcs(sta, ra->ht_mcs, -@@ -1786,37 +1786,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, +@@ -1809,37 +1809,37 @@ mt7915_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7915_dev *dev, ra->supp_ht_mcs = *(__le32 *)ra->ht_mcs; } @@ -1188,7 +1262,7 @@ index f0273fe..5c14114 100644 IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP); } -@@ -2025,7 +2025,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, +@@ -2048,7 +2048,7 @@ mt7915_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, if (!offs->cntdwn_counter_offs[0]) return; @@ -1197,7 +1271,7 @@ index f0273fe..5c14114 100644 tlv = mt7915_mcu_add_nested_subtlv(rskb, sub_tag, sizeof(*info), &bcn->sub_ntlv, &bcn->len); info = (struct bss_info_bcn_cntdwn *)tlv; -@@ -2110,9 +2110,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, +@@ -2133,9 +2133,9 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, if (offs->cntdwn_counter_offs[0]) { u16 offset = offs->cntdwn_counter_offs[0]; @@ -1209,7 +1283,7 @@ index f0273fe..5c14114 100644 cont->bcc_ofs = cpu_to_le16(offset - 3); } -@@ -2122,6 +2122,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, +@@ -2145,6 +2145,85 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); } @@ -1295,7 +1369,7 @@ index f0273fe..5c14114 100644 int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif, u32 changed) -@@ -2234,7 +2313,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in +@@ -2257,7 +2336,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in if (!en) goto out; @@ -1304,7 +1378,7 @@ index f0273fe..5c14114 100644 if (!skb) { dev_kfree_skb(rskb); return -EINVAL; -@@ -2250,6 +2329,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in +@@ -2273,6 +2352,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in info = IEEE80211_SKB_CB(skb); info->hw_queue = FIELD_PREP(MT_TX_HW_QUEUE_PHY, ext_phy); @@ -1312,7 +1386,7 @@ index f0273fe..5c14114 100644 mt7915_mcu_beacon_cntdwn(vif, rskb, skb, bcn, &offs); mt7915_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs); mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs); -@@ -3547,17 +3627,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy, +@@ -3572,17 +3652,17 @@ int mt7915_mcu_set_txpower_frame(struct mt7915_phy *phy, if (txpower) { u32 offs, len, i; @@ -1334,7 +1408,7 @@ index f0273fe..5c14114 100644 len = sku_len[SKU_HE_RU242] * 4; } diff --git a/mt7915/testmode.c b/mt7915/testmode.c -index ecd6271..b2c442b 100644 +index 72cee21..a8519de 100644 --- a/mt7915/testmode.c +++ b/mt7915/testmode.c @@ -418,12 +418,12 @@ mt7915_tm_entry_add(struct mt7915_phy *phy, u8 aid) @@ -1355,7 +1429,7 @@ index ecd6271..b2c442b 100644 sta->wme = 1; diff --git a/tx.c b/tx.c -index e4eb74b..a3654a9 100644 +index 9df70fe..2182e2d 100644 --- a/tx.c +++ b/tx.c @@ -60,20 +60,15 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) @@ -1423,5 +1497,5 @@ index 652f59e..1c2ad30 100644 skb_free_frag(ptr); mt76_put_rxwi(dev, r); -- -2.18.0 +2.25.1 diff --git a/feeds/mediatek-sdk/mt76/src/firmware/mt7915_rom_patch.bin b/feeds/mediatek-sdk/mt76/src/firmware/mt7915_rom_patch.bin index 10d3d8f44aa91c0fbfad145955119366a4dbca8f..f3aa076e66d05f1cf125be8466ce2207f692800e 100644 GIT binary patch delta 31 mcmZ4Rl4HS34n89TBNGD?BTFL#19L;OM!r@)#;trzlS}}cp9rP^ delta 31 mcmZ4Rl4HS34n89TBNGD?LqkJT0}DfoM!r@)#;trzlS}}cV+f=G diff --git a/feeds/mediatek-sdk/mt76/src/firmware/mt7915_wa.bin b/feeds/mediatek-sdk/mt76/src/firmware/mt7915_wa.bin index 83b635becb44067c5881cbf7413cb2a90f9b45ce..bd46eef00c258e5a2db7ad19a0c86f24795439f0 100644 GIT binary patch delta 53371 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 W5S!IMabjXZLejWI?(&w$&Ho?fk`X8X delta 53627 zcmcG%4O~=J{y%>1oy#!5Fbps}Xb8iDh=z!0hBgiZA~J^KsHDV_qLPxCqLP_w&IKE(y?_7i^yEt1~Wx7bIWO4*LKPE>zbO4h);yf|9$QZW)I)r!}tIH=W96k zJfHJ9pYu7Nr*mq#CFgI;>+ZJ{6h|{$v6j{7W5=x0tCCBNr>3-pxt(JPC3%=yvsB(7eRihh>B=5NEhk8<+!tURZizfZh z-M{L|-cH`%NcM!KG0)kG71AJ%yR}FOZ;8WSxezbNjN~PSE~fOLF155>r!3uPWnQhG z9Zy(OB9o8wk919?tp>hMVQ97!?s3B8B(4fFh+~3k9M8EWtT1&2>&=9u@b;-0eYZ_) z-_7-g>bG5C>P7s3@PT}gdNm)tqiTo25U*AA&1xSoW$0hd^M0o3eg77R$%b2w6Muf8 zNv7mZxcNihJ>*?clgw|1pe2L(pvDGMLSG#n zsV)s=UjW(=qQ&~Efij-Htr+nt%>ENwyfn{GjAZvaNPh+x!J~c5&eFFm?!(m&^X&|4s#H)we9aXeFG(vjSTG-QZRuZwY?${ugCvT?N+;px9mpkrbXI6yj{`+R)aI2W0|QDY%_P*+6&|SH`Z&oYq#~z|Um-Y6 z+e5y?A*JArwss?#_JQp}!Q+UVyX_QP$v;qT}T-ITT}fVPH-NTV^V}4Vp`sNM@&)1jC$vWQuu%-n_wrikn(AGChVIkk> z{;+lXrg&W(V)ewIE99Ai8KEE76Cm1dBguY88ecZpgk+LP#$XO|l3>`TRg_%i(+zJD z&NQM+Dc3LYA;4UIg*lR>s7I0Ts(91(-lQ6W5f@NM^~Ul;P4&I^iA~CMOD~HSBZ<~5 zCtAwnmkI{(ymI;t^j62v;iQ0$ZFCh}ue-_*Q^z zOz=T;snn~6rRZnvX-0Ra=;VK#Pf>19SwbXHn`A+zJQZQW)PDI=-XlO5Wxzo8aU!M! zBw8-yXl*O_gdGReTHe+eX<~mIw&O$epQ{hq)tkd`6gbJbT9Rud4ztw2ef31zVL^Yt zEXBjUalJe-SBeKwEP7&r^zBE#7fq+%Js$d9Udhw%+tTW2^|5pq4T=Oy&$m_vr}zl; zmW196=q*U9^%aGIKD1^i-HEw`Azs)k-{0~3ym%QPXFX{OQ+y{dfZH&s#)sZ@63AIb ze{-o={onyQIL;sq^aXPGV-2*oPz=$-<4F}jegZyffs zk1XI+J1J^CP-Y}qpkKFR^7;r_d(sl|E?n9W5@N0y*2rnZvpyLC2Rk|`QGO-l#Ox^IKCrydL z7ArpfijOr2zd%@l@Jobc2u~p_Lg+$Rfbc6*qVg?-e?zzx;n%+S-w|#?{4~m?Bm4)# zB!p)WV&Lfo=yWdl^*+62NTuL(`P4UX8Lzs-x|sGqB%{3syR;@mc-rV6G`0#ern14-PH=jX&nEn{rH{d+b;M@*x9_Z$f^7F1%r&F0noq@h<(+ z#7g~rmLx+B;Zu;g3W*oeq6RDQ-GHrFA=ZUOTE>6Hh7$#wNW$1rB!-bIkdug<;m8q? zv#m9mOC)|+`#^323E^fCjozXf?nG9DUX`Y{FSEBHGYFY#WJVy}3dAYH@lsaIQ$nr? z(yK<;(;`=6g~qSOcWYYYTsOWe@qGvjUxjb*I5%tnZWBT)F!+Mtr06>0l&yXH2goPI z<=kzg-=gW*&m-L43|%+P0HN4#BxQS0c@f1fFR^Ie;=`&BC1N3+XX^+k9xL6<>s3RdbJdFbjbtMaG4UhFIc*KB6@=)i@GJGjX&U`$@rxd)Rd2yBbpQk~{1o_gN28%A)WLTVe!2K%;&%?eHvDM4 z-}))h4u^W@9*^`Ea3XBNZ!v!55x-sO-i8D;(2O5{pH@8@gVn1>k+i5icHQtxJ0NZ@ z5ju62OFQ&Sj;Qr7zI#giOT>L4+V@{a&P)cp;*M)g_8~krP9kjO3v{pqin0 z70}Fct4wT)9AKH%Nc3q()D3bg+n5h;2P=boB^IJAK~BP; zP>IQl1xrI}@{vxtkpLaI5ukaG_d68w{*7+>4X$K+m;90Hdn&OX?xV@?{5Czc%)yL}YYZ!>)r_5sjl>x$F1L0=T#o)$JsNCpiG=MUf z^(lLjD1)SrOEO?-4x+}N1uYhIv_52r0Y`~JiWMMMiP%^vmVy{4({{S4o6Q!i5vL{$ z$YzI^uL-D@cuLQWMv!(Eqo0R@b>5k*R^YqVyRNzE9?xbY(gO>o9cczeEq(Wbe#@;V9X?Sge*|U)%^37spJpq#$?I`*O`XizjRy z;qYT^-`c(|UZwq8zUTViBrY>R=ser0cfSI;>iP+KJQ~Ssa^7iT13ttTG<~^h|C5fD zLOdqpc05C|q)1(LrcJI1Cjpuj5KxzHd2ZKr-9|^LdId=Z2d)uWw zyUVUw$1}V3x65>c9MAJZj3fg~aD7XjLR*KWB51h4NHPy2Z4*T%#4~kq*6)#a0BHi^ zCD=0{)|st{uc6S=1%-Zr@0Il1t8P@xHp#9pF_MMVNMB?m^ULxrp6d&K+OutpPwT~A z|6OY~8s*X8MHDWi>9pfU6~;Zq)#U^F7B-ng^QD58Wb={P>Ac#M!|$zWkH9PqOC&$c;{m*(ndAL8Au8zrVom&4G{>HK#}^#dcyki;Y9>{5@EjQYKM^9{!Z$`3=tH#7_6i`X9m_`hUd%(%{-BrCHqOofbDBUs`Nn3Qakr!~7qT zKJ5gUtn;2O)As8ti60@wgp$+i6{0$JZhTy513duk*+)U-{NLiWKor6Ub@XcNd=N^F z5KqKE6BQEL@N$Bc_hV6Ymc_#cSrh#@KM*JJKSkep$!~Mf;PoB z=4%uLj6sT^N1Bm5_!eDOvp>PfWC3&V;6*aY0^;czCvEI>K2S522XpcICW@CidXkid zP7Plx$@*-5NRPoRuhxVnS98}kM}+W^D3{kAp&RZfy(<2g@PJ|Lr0xh4%asG(g%sZA z!SuX;uqbUvXoD@gu@2)nWsU{^$Kj2tz^ZcjYJ0MmQ;GuU!%wW1k7fEF0>rhHcaQCK17Y{}h9KoT!bP=pPE++MkUU z7sm~X3nfwbzOO)S`5YsPffyH!@1rD?3_$uI(GfSrLLtxiAkXp=s_q6^aDL z`GeE{{tU(=_s2p<0ej9pb0X=_GJB6@2Fw4|U z3`U>o+QCEY8&UzjeKVC;-N_iu4&YHUYWR~49hdO8)^(wt7^>8Y4V*zxODdfWX!jcD z6XhpMH3MqE_ubsk{4ATu2U*xrd;~jzk7H->L&5igN$caRb7CFO^<3LVv z^Y4)pjGQRs#3Sc^u&f+%rZlfXjtV)^$Vos>Dss%oG1!04CGrYx6d%k@;KR5Xd=yx4 zCvryF*Knf}`2b|8kQI)sXv%scD;Xo)3Q#h|Y7aK;wZ5&{jrq3t^^faAk__+KlD0A# zl^sY2D?O6a$3Ae&NJblsWRwH(PO#yKk2Omyqwd{1w7jkYWq9Ua&Y-AzhA&q^ok}p`8&umWcYGbs8(3?n-g=goabOkGz}UM|#!gf!(EWEZSJaqv|O|RuolF zjndFreg6g(e_vgU87ccux$n2|gVC8CWmu`qOZ7xEi_}70S=@gHsV5O2Xhs+IOklC% zRXV|rV)7bi!3V_OnWv?BhR_2iJrz4S0EKbrT!TO)#bNTxSc&*-UtEqjq`GU7r@_wk&JvyB8Xb7Er9?d}U6$ zb%iN|Ehf|W6w?gG4K|PAhf*aY45FNgz49?Pk`KgIJU+p|uP|iSQQoCah$q9y(8hml zh9!~?{z?lvqtFX7l98SHp02Nbaqxd5zefDHFOJ!dJc)Px#YrHJ)P4iF@5eKr`&r)u-835~`-y#XQ==lu?wM}m=a>uxLxu}=Y| zQIG(t&dxJkyORE@!YZS30BRMw|Dcb}$L36F5$lGfvm@=|!C?NQoF6(IwFH^ zGK_=fi1&9a4-={KXvEo3RM5VyE0=JNFd0!$CWLcPv-T?^#AEko1-Fj~vGKn7z4a(A%Pjig~FB`{Z}(DfVA zfl0;GXsJC3h!md5n$OJ;s-o$(8XSkv%2eh1`5hY)CU%sun{E zl3mQ?K{JK~QrdfQ6p%V(%X3g&+jG^-Ix6!R$)Furz?rT7HOPau(x0MHZ9j-cVVI1Ukc<>ki^k?f_WdkUcB@+x@+R=&=JcVK$A?3% z)Cw#tAW7z&mkDBt^-u!x710b~&h%2`tdg5#7v^~tP07vqo(m-yi&h%T5NRy+_l!l9 z#$xeKU&>ua$0AGVAB!wS8cUco7V(J@hWirqX^(T}aFQbM0s|H*U9B{Xw6nIVkDJ9q zBNDKxo_efm+T$@&p=~_x8b}Qy=}Du_YF=HeNXJ@umKid5Z$0MIeQr4-o*#T6s7r<1P_ja=8n4MDa<-MYUlvH0+HG~e zfL&9l4|uNbd7f$w+#9OaK#471t#JD5f{)2&yO~sYw>;c}!~bQcWC1%q+ z=B#_zx)+f1p};%}X~-=|<#y9@={^sZvp^79d3Pbia1+aL2xSnJrspZ@>|7m*lyn3g zuat|2MvfiZq)VMsuT#!>&6-fFJ(mFHp_Y?-ZkuFe0W`OfCGPbB-zi`}8wwtqJxlX# zyb4FeUU5uDlEu_n1kpO%$qxjl;6SH(--w6$24SFs=osqeoC$7~Z-90*ei-@6Vgj+B zkP~ThPe1RgA6o*{L4KFO7)Z1-FS@QyL-=?%ozOsc(B*Sp{~om0;|??Wk^3`TH^kE! zLoKgrR(fu?eb1}Zl~m}?FqmW>9O|A;LV|$!Gv{?NbAC40*=n9Og?SdC%o-v7{VAGA z&ut1)HAk(Uo=Sn9oDw7(jw8NGAQu9p#g%&(RfR>prpA$5s2}iLoh2vKx`Na4foIuT zR>(Fmy89qPr|aVeE4@;wE#8rhL#vHaL~D6J)OA2#a~T1sI*GY}9B~g(mkS!`r|TfI5}e z-fbikjZEgDnDRB6j(Cn+S*(!#OQLm?U8jMRb5GZJm!%D6lA{Bp!7J zyOkYgl&iD&3Z_Zx$9lp*D(+oDEeeOA;09m0fwY|S?>}o0W%}-T@q$g4aKq!-A`Qog z+M+a|T5o-^N2>pUtJ8-^79f(c79DK#6}adfNZ$$90p5TuC-cs<0m_-a6H=r3X!Hq+ zSmHn30a)}vcf)m!JEFksSL6$yz`me3^BQoc-pbUnvteN}U6UD*?ne3#NI&mQw-7&M z)KHtBe(h?liIva9o(A}-f{VKW_5RCH;$90FtNU!LU^?gzp_PS^*Zl&obt`O)+X|yx)G?~CI4oclQiTh2q}WD(p{S; zzVg6h3qC%VtL`LyDood7=;T4rSU*B}xC#(Dl9ME?Fc6|?WU98iYfK45bjwQIT4L%V zyl&9Z!<3S7g9%fA(iUGhfyla=8@X;l7kBh9_G4|KjOQ8|d~FqHkBLuwrKForH+3<~ zd|aiBS?vaINj`PU&>wihDThV-m@aB3cb+w1pA5XJILjE` zJHQqC@gP@sSnmSXcTh^Q?ga_QJ$G=Z)1|6ELboM^fk8Ob1|6M1VF<@I6_I0{6QCbz zz_!nFeX3VIxQdJ8Wfmj3-;5!AVq=Ql<2iu!6W7}$Qv3jFAUP|*dn8OiUrT%+W^ z?Am%G8MYni4g8QU@Ug>A;oHeZKtC~<3_<)je)V2ZT$7tv&jNm!K!gcGsgbNaR20E8 zh87+wW6xTo=Ln@>s*$m;+rK}nOU@5(Ib#O4&CDTSe4i>7Pd+##Y9>oaP(z+xb)>_} zH0QuF2;SB6u&Bz6k8f;AHb;}FIO~jUE7=xu*T)1@y}czLP3Wv7aU@v zps*l37K>fw#Z_kryO0FYLu|o&Jg<)(4?$%d>5}n~ABI|5&@mA0;jesiP`AYJ!+DcX z%1xy_hGh&J!cR2G*zNs@FN>1q9f~@jEq88VzA%twX7ZDB(+P#ZQ2tnr^X5jEin4*3 zW<@w*pmW3G4~;3V2vHSxHiQ*ELqb09;?wjhOD5KNsM>Xz7M`xdcVO{_21uUMb)1C{ zMx2#^$a?fQa1hb1biI5Yy289ux_`T)lndUD^6%-0_LFkvr+!ktD!!241sSftqm&cC z8m0I2Tmc)S@AQlTr@+=Svk536+uKT^K#!uvSZA1Y!s_O{Ch)b1*6g-9des;kz}woT zx~3GiW9Txvd9fRhO9TO@YR@(jLFN~$<@5k#*})`DbUzepk#<3K^8{Nqc0%>;2>@%h z5DyFh&{m}Rh%Y_RfA9^(4?|hi$N3$3c=EX$y!#N0<{*A z_em5tu8L4fyLm!^dHp5q-Xa(zveti7Fm3(mn$F@BdTPtt>q*OSTZWLU@$lhBQWx4X ztjgIPo+h7r3;3T0{dR$uUy^Iwa_3MXPtdju>=scny=CB4d9GGY6%jAq5G%%yN%G$$ zw3{Z}na!)rk#wu2Y&WqAHGwfvIA{vH1MSzx=fq>lqPgpptl(EptQHq znX$x64}NTHr2a|o{gSckx#A8ru|2yehiK~RdGogf054au`Za-B_X0h{ZoS>W{iJfc zy3r)-drELZ9XE;fC*d(L?8rzDI9(3v?hw9`3?T_{U|~ znuQyYFSiEqjfS@#0eMcdu+ zIixHI%!prcIWM5t(`pU-(99_eMfz$dH2|wx3~Y;dZ@#DYz^KGEV$oDCVc@yrV=k?zi4dH z$IjfBtCd~2USlMKXI=MmeMLd|&?+fD^*X@oSqwWPFehdYyi%ONg$Ph#n_G3>&(!77 zyOrnV2*-)7Iojx&aPC{eG!z*A!%NBnt48j;##2^%KLC;EkcDUyr+^pLYCubDlahi zIPtv#-%k`+%su-NsYGNEGFtKdG`^q2cL~A*uVtghf$u54@9p?D`M#U*J=OQ!h;Os+ zyAI#eeBYTEa0dpPigh&Lcz0Y)>`FpBiQ<5TYH#lpA^9X3!CTolej>7>`nR`dt#8Y- zcOFKW?yHH|VYD(dPIq!}p3E;Mp+Lnul{k@>2steS0l@?KuD~~iX4}1xVMp+z>5fG& zg@$;dF{pX*$%)~n+nvSf6VS@-GsW6m8h-6_W1=m@dfk}V@?W|!agwr3x6eot_o2@5 z{+`6+6aQ!_qbH=7>rdDN_Np*fz5W{mJwLO<5GyeEwwwLPa%@qXk;H=%m}I?Z#j`vO zuBKiaaBq44hU=YAVWZcNZ)%C5=K|$sVSZ`_hcHuuPb{VJIv7_$<3Vc@2U#Q<57ug8 z4t(j>g6!nbf?lo$7M)LhtilP2RRCAi{YUI0rI%DC^kF(-bie-FZo1YBJNlim&_8-7 zRBj{*d6>}XyOSARFr#W04j_rV^)1&9CUdlw2!d0~lhc!$!*fa23$|`}Wq&|dq!!#A zwnmCwWrKSo+05}gvx#v8nyPzuaU5*n6>Hvv!y)eo&>TXWlCq*!!&MU5kr4apmSK{^ z;URifZtyhgp*z&mT~jN&8E`Gq{%4Nknap+-E3TOw%hs+JnZT7QUiOT zCY*mw(ve+6azq ziYf870imf_JDXM=m#f8DHSO6k!~jKb^?4{xZl?=;ampxgY0PyjCM0Q^2F@-G3tJ*B zCV0}@a7#jbk&xSht~aE%45LGc2lsZn2+Gwzdgp1~50tQjEUsrLi^xD2?EoJJAq8+BXUvlzO*@wvKKM+Ige2EnvfslSr2q&Lmo} zl%C!X&_4A<_w=@cjx?imgZ| zWaMf0h`dk&4TSSC(^*nTj})*Ok&Wez{Mm#H6Tq4{H}0%bcC5rh_3-~3UwCm6j=`(dq9;(g0yBJBfp>IdR9@g3}QJKn6(W`X|;`B%NMVL{Uk;GjF0*=6i z63ExxCP1lsoM0k#W@32-I}FQl=hi*e3G9va9X^Y|uzu^r`uBX+37Y%Cw*5VkUVA{# zOe(2AKUthTb#hL{6}T@MyoQEI8@Ap!NE<=tSyR`|XIh3)X2mO|Jg*%70cV2P9PeLp$Pg;i2Ly6k^aMp}-ofSJx8k5v`iR+j^T&?$xX??5d%bTD*cgh6d z^-WmkA%X_ezo0KYUJb|ZcHGr)$Zi6SZk!e!=6^GFqHWqg1G7{0v4*m&P1)UI<@C9J z_AJ%<3i0&xg?{cV)#^GiZ$<*US}QJ^VW)&&SvW83xr37Y=IL9K3z^PHp4%_-g^yUC zv7E~~Vc_&vvRd{3e6&EnL|16uEIHMC{74zmmRJCxIs zAcQ;ZHLW#;8sb@yLp*&u+a}uAqiuj-;bl0ta&`>_lb1L@-mf*GP0NAU+Y1qLydM{e z`r2*J*&{5ig9~%ffSUL8g|zuWR%Pss@UntBVBs<9OxKO>O=0W;Grai6s$gz0w3#z! z$yp3!VrKGsP;L^GIYZ9AU)?&OtsY3r}#bm$LQPl}=N90odqxZ!@qPM2%)AVo(s#--A_V+eG zJ`u+~I_S|q!TNKLp}~!LR#E4n@VrnK_171oemc?$Q2+U#)qnms2e8sNfF)wfqxU_C z7KAluAs;Ph(L&u%Ep!-vUcZI*TtI7gj1t-62^I-az=eO^3h$pg`zi8K)VuR1iaJQy z__L8~T_?adF(maa>{DI)eqI7t((ubNNc;V-NscLqICbAU zN_B(Yh&DuVa#J|r4gN85-4Aa>W2XdO{xb|V7=wiop~LKE z$AA7t^!dOGe>2E=Wucl?V*)oI79N3kc&E{l=KK^ROYP{ON6hLX*CEFS4V;u)vo~e8 zWy32jpf&!R1bdcO8^(m)h0smAY}?1&NkaZ`z&_Icj=j=RjlUxuq4uM^f5BYOzg%Zv z=VUbNc&>FWuiP}ZZ7#gbX={nVF@JA+*D-~cE zwU4ne8hlaLR&=tSmR8sCvu)fqW?POuch|ga?6&M(bGI1{4~)JKi}E}iz3y3-4i&Az zfpF`lIOYlQ2B>cg>}V3E3vtXV&XN#AX`M$4ot@`shh6&1@xhMSy2l*r%_&5&ZK$oe zc&da<&x+?Ciyh;5>};v2tM6-Fmg6yOi&NKRjvJ;7a>KgD(5I9;uI_66?svM9xwTEB z%{jaR9Z)=cK-AA3WI3RVnOm!io%=#wsBDZ*g>L`{M|daN+1;N<(-HsFuD1poB6)dx zreo}`Ub#x1k2+||0J!;nU^j%8x2GiMo~%+~(SfwTTz zO~Rc6+itjJ)=v0Zz;EQ|0KNJA4Ieno5==tQnq+riJ)(nP`!I+$46A7yy9?W`Z*}yx zRQoo3oHX}^li6#%coh@yA|#bmOY z$7Q0{(z6pT^lIdwGbahFiR4+$Nqpyl=5RI((?(eq>L_^cHsD+{`6~O|*6g$MF7#rP z2cjz|0}TI(VGRDDn5l1hC(aUU1n+&x+1<2?62I*%nvs1G7g1y8Z;QFthI+Q_4 z>T%o?KZcsU<3g6U9LU>OSI51{8}u*kafoH}9%fF8E%P3p=IiqR$eDYj1F2~97z{nx`qQN($o}8VJt7!P0!q1JL zz{B%G)<%B-+gEP6oz@E{_!W6N8VlZ z_*m&XQry2_bNnOIp2YUd1~f8?)lUE!`qBWYq^7@SMk^Gcn~#Xg7mm9B5k(j-0^kx! zAM|K;jZnMgV5UK#Xqrx27pCla#R!>RfLj^LpIjIf{0J3b`#zM8nn%R$h4U1)qR+eWKQd z>}@wKCpU1N8aC`%7k=4~-1?>NDaU#-;fdk0v~4zV`V;9EiAR`8c|pg_g1KY^4uM&? zP5BtTgYTFHE_0msY8)NJ(N-UGU6Qy9_-iRGU@yGf1z@++QH8$^xGJnX6oV$7w=w4FmRqRu zy!|`<(67o}ET7$)U=KJe`>t0LX6b9&t{Y^%VjpUytn3wdos2u&=BqcsSMS?j)eA?x zYN=klm9h9L;x+-D4V+6}!w~)m=Jl@#pThnbe(5xb&p&M0_Jg_+mrgq_A{>6{lw+tZ zd)K48a`Yi@mm~d@1I7bS6(v-T=W$L{EHm4R+RCKml!-#MkO*sM6}X*1*MW)-|GjUjq=4`G8v-o zsX;?3GfSar!Dd-`Mv~n?Wbc(Hy{)eNTI8R~jyk7Ln-C+Ao7G_!YI|I{umz&_%I)IU zPbGw{E7HYXddtlU;E*pJKytmPT#{i~xkU3cpNn4(TB4;Z(wNhgC2FEQTEIo{!woBV zrRQ_x4^LZmy3)+iExEF=M8<17$}p0O7_SRm1&ODU?MghpmA9&{&b^L%m!HT7P;Deq zbsEH^{A>Z7H2RbAIVX~IZ(m|gh<{n~s(RgMj9g4W0#r6cb<385bhsAnDZ3VwPER)Ib`@wAc5-Xh*wnl1a>ku9EF86i%qSR0f~ zb9=@kZ-{uh!m6q~<13Eke(a1`u`Jn=a}up=&5Ob{dcs#VGPqScCr?4Nb_U-eZwy2# zFMSQ@-}bpIzT-BnrCUVDu-G zjb!ODiObNTMwS~@{EA4B1Ln;nii)B}Kl^p4yA_?Nz&MBXck87G0^R9W!KqtH9iO#s zv2b~ESmj%~rPeQ@)0^kQnM|1h(YAbme;uW}m6@AcWXwQS}{$Vk#x zn@@5~0z08ZbgzgSxk*2Jo2?@Zx9Wm=xISej%d;Ip*s}AWj${m>oYJ7?!f>R{gG*kx zZoFfjs9vc}b<8u8B`>?chfD42(7pybGrG91j$67LZG2`PDghI=NlBGx;J6;IMh1pYJ$anaM6Y~n>}=#wYFT~79m(Q|tq`l~d*M>sP; z0WY@g|C7lm>13YT<(-VETRFggBOUniQt!Z*m-q&*2K2Ea6#C0Y(t+3AGw|gZ-hnT- z{3i5oz3GE~Lf_A)a0|NHd#A9t?SC=_X+0Kyc<*}L(*0^ZHqdD;tMpE5S;almO7Tu> z*+e=m^F7mAmgk+;GVwR3b@PM%X@&iKS~qKdKCLH@{ZFQ4p)2#`U+f!F^;iq$!$lZ&Sb4voeHwKB#=o@Tl&o}>nuI> z>pDwM(K<{2x_LkP!R5%!eSu6gWoyBc=W4@C^{Ty?YDFH6h46aS_Ef~O5Q~pjgLXv} zkq}VRiZL{QB00r@GoQmsYGAVDkSqrD`2M^O%J zHOi9;#MHuE%5rbOuU5Zg?{59tPn7yi+mmoXB$ukHDoBg$a2N(%1o^raQuT(mJm`Iv zIySgvP+&2jG_}Z`VLMeY-}4{6Dp&g+FBtT*vwK?WAdF_fj<87Vfh)-BRQ;0esWnzo0-;0B4Cs|7Qw z;AY_xPwe(2@xprvmZdW_D=dBCA6q=u%cd_pE?`tRRlY9S!A0^+>lD1qg)UI?%JschOX5O8GV_ zQ(3>HPoROF#+QJHJ&3$4%&S=y7r!6PE_nn5Buf0l`@xoSXr9q0wq2{d;~MrvG*y-r zEa!c^G(D}l*Kjf(78zUunZXBf;e7Ze%6n-3$~s4Hgm#jsFopm@>saQ5auKW^FfsNN zc-1fNh1+%6!r@8E59Ti*%Mqs~88N|K%^L47@+zUNyf8vsqYK#lt=B z*<3=fBNsj;sy>KepV}jq9{9lz8<#P>tKA>MWcwIptkx_^Vwr`n_0AIfwK~W9anM>0 za?I@Eaum2XuHR;}#lsgPG&>Xu&J>L6F^sF?&l(&bnkNXet3D!}aGCKui(NR=97>qX zP(Bc*omQ%m6PWe@gzLqYKS$;{*3-7BR`lQecOU6qbgXwB09L~0UKZZZ;kRIgseR}1 zGeR8ZhZrqKM+)H&TvAM$s63FCOo72ZYV>rCGu1PzUhWZCei9hE$21KPSOWmzH(?yt z{4{S-yT8wJ7ccK>?SBpdV9tCB1IQf<5w7P7y`w#A$1Q_JJxO}iHd_uWtf0{G!o*%h zB{2IJjxJ#?>}#xHWCK>uv6rr$rkn!DF}l@20n;?C&7!5K?=;fCl#l@J@zvqikMgu@ zXMohP#@8|P9d07`pEq69?h|x@-BoU;n3Vc90ELG8AdIlz-2*VrNCwu?X#ice zXWonDyu#(81(5-ljecx*Z>LW&`Z_YB!B-&^O|M_0VIlHFt|?{~iBnc+#h2C$^|Ffh zY(95}czjJJH}HAqr{c*K(W3S_`CXRF4Fj-e^-nBU8EEtWJ^!eo2YcBhm*c0s@WWxT z`MLKJt$b${1HYMYXQ)@kD&HX;WHv{JcCp}%uA8tFsFL3Q_mDA&0%&{c1cn+rEhXLX`%l+(;OtHn1VcC1o znM9r1o$*wcR!GPlXhCAroj;p%q`jS%Wz3ucdho8DnTW~~qIG`|`+~GUn%rgQL90>u;`Q zBJZysk>D_r>1%P+XC*j56%=V92@XN)RO&+#c8N2q;^PpNr_eNRv3d`cYXHUcJ~;oy0my#Z%Q4ksUjoaT)``yOIfZ-Bh#$6;^^>EM7-j>i9R3 zc8Jz>duZ`YAt7?Xbm@+5nfHz@uDnXGsE8FpM)HC*n&rFFDT0+9G=lCuY!)DV+Tk~N!o)6_Dyra3>ENlJ-$KgdYVS_L&1=M*LmDo2!7L<4yPr! zdQhKdF{LKU?-a1YATF*+UX%-;ndUp4i`F6gO-cosd6E2a)2)XoP>*Iw@I>fZ}zRu&OcYAAE8F_9U>bAVw_Ix43 zVlc`LA{5K^4TA__`F^7jqR&I(xeZfi9nXYc1E|Qsd{UecQP2%=SxxZ}Y|eon4#6+eypG2Mb2tm;*|D2nhW%9w56uQj zI=8+o*4Ap1=dJhcXIiM16L}VN(ctx?!6~4nFL2I}7Ejg=8#WK`CD02~9QO6Yvx$t{ zf8OuAAW(~RR5knZz*;?Q7L#5mq4#;JU${D`AnVbZRNa!f1&)ysGYDyOLXMyEUJMRR z)!Zp!o$WXZzB_xPoWac>t%l?_a)!fjP?zB)4&~ee-KMz(8hAQJfGWICtua%)742hf z?Qoq^IL2bN;KYWzU?1Zl7u7@u?ty&_33UWk7I30(!3&*kOs-UbZRUb^w565a(aK=6 zF;-H;Q`KCT`0q{6he?l+!@9!01s4#!g)vwuu6gmHsHV)uRKji|B;8UoczE*m zm7`R-Xs^qeJZF&)=u=?#UPN7l?nwT86U(8to)QrUy}9QWhbExPzw-{N#o$yYY$DwH zMv?oG&lo*7yQ$NcnEKNFV;cm*f7`}T9Uh$RUgV?cWc4TDrYBFu6OVMtW72T2uK}8S zez>3Z*L#wVK&*QylAY8iI$laxFwvk*B)Pt}n`qnUA8qztLI3yWZTczij_MbAkRk8Z zyZDQ|<j$c4#YPKIQiz{7m6?#{_odWaw2kbopub++KPtMXGQH%V`^(n_>I$6U&Tl~KX|Mgg`04~7Dz(nmz^B=4* z2nq#O;zRw^luU74V+@P;_=*}I4&GlVNEnx9BvHj;OJiK{>kypipk6nUl2ziF#(9@$NGggB^OYF}ujpZP#>gwf^>miL?d5$h%!A9RQXEv7 zz8~iKecF&D{jofqtUeaAm7dM;l<7yLWLopJ*?{LH&v&3L;)k1+iCKx2)D+6EAO$9e7VmIto##KiuLx#)?T>(v)~I5M6pZ z6K8KJO*&Gi|2(8Fw}o^-s^fo5tML~)u>rO8?L{vwD+v+LZYi_uDc3)^2OP`qzNT9O zSv>Ausu4e#o316ghvvU7*ztF3u7Q;4emDOQ`n)5Vh<}9NUl9MW|FJd7lE?^hS5Zzo zpZu<+kw0&~Ajd;|BlZ+#h7yIB9#eZ=+QQx1!^8DUcP9zrC$D5OZn5u`L6%O4Bdd5h zl}(#KtbiLKyS21gb~KuUNthDzD>lL4uE!0nSNM5Yp$hYys)})1WzyGu-q&%N|H}G2 ze4qZsxPAN?q0{Au`KA|?ktiawbb{&cfiXKDrWD1d_=bmD<PU>Q>|!|0WT zN1yzeisn9~%=?9kMoM$jvU6M^{m-^w7Ck~H@c4bY|ME%^@A|&ddqfZ%F*WvSz->|W zhk#MhQqLF%9wZ3`EyM9Kp$T+Mc|Eivpg+&(`3~;veP{4Lz)nHuoYwU?WG@4a^}&Sa@|Ot2KBrk0Y|Gku`R- z`57G{WkB*{uG?yOjI{2@*6T{-w76gDpHGAZkEOhbH&R~iZa@jkdTr*l&~DB32tOqH zArr;FlSmCv>}o~-RP8c1Jn#E*d?28P!f|5ER*MV|y@^}5eijdX8ZXC=z^Puen{sHB zX_L4#d}CT~iMH2MQovF^q#?ZYiW=VE#!HQMg(>^ZEmc zZ(|3_c)HDKqeZ?(i(I?w30!Ju-5ug+`($=k@4LKxB@?)7pMH+RkTqi0t@`chDo3Ux ztgFiL60g?J*|ks9Z`TFxy4B5`Z`a@4bxRbsXR-+Xvb|v3uG<1b_t6#(hknXgE%I** z#J2%;X;HgwwP)`Tc1+m$i8aAG1g{dt38{UB`l*ggG53uf%9PB^2$toYl=w+sKwLgPQldEq{Gcgv7l>es0DDv(W{`L%QmSAY$U9gKc;qeSy^$4@#4+|_R>yK<(SFtDHj(w^i)vX;aHssJ9%dZ zClD&z|TsDMh;$9|uo5z~)HC(H3rY^L^Y~;7?6}lZXDQ`R9dlZlju~KHPIru^N13CjLqokJ zF8vk1FCaCdQ@`nO|G;!9C;!b>djOoKJuX}ya6D?K%|8ltSUGe@zbjzK@3zT=QkUF5 zL6go$6c|1_<1JCZz}P&;@hI=-x~3ZiV=+y>^bh@rw<~myUHS$UC;g)0hu#w2ikJQ& zp82da%<-tJdD|1ajIN7t9`Mu6L9*#Ybf#lgTO1}bt4Gs^!4^!cf{~gjYt4c-`FWv} zswm+_2sIOZN|(UCwOv{BpDYt#vGv4A=27wFiQH(%`o4{Zq3}?8gVXZL9k>GbCOu{b ziK(CKq1^kG_Ma0DS=&v`pE(YH z41}f$EA3o?xJBuXL0W|i+QMzt%2urqZSDo%Bgq1o;ahXlIb}1ls5;V9kRHCX0O^mE#NqV9!e{=w|yBLXt@G2yQ$#F7~EoWi=X}OrQn#f z;^}&omsTeTq5%uL7oM);1JXf5Sq`=HfKY}5@%{FNCqs4eYyN^2f78Z|U{*JPK^v+v z2%*SShfG`SRVN21@Xiw_W5X;jAjcWxNJ5SzVkh78LTERw4uiMPBE z9}A*(Yq6LJk;R6srTmJmRs6GC_w#LAPb6;HdO2~!);ozSw)yWd@soF!@`*czs-nd3 zomq*{m;f6s*Pgq5W!TR0J;{l)ciQ$$Nu0bhCoys7qC`x$J(fKajFYQomAsdssG4oh zd~dX(YK?vMd*N1abvNkuM0oXr0M}p+77exLBqowlpUmIg8n|5{7JBJ9g~^=a?;2KB zh+^hweK}SY*qZ~pmx+pEhF?Em)jN>TuJ)jPG zy`kzU()X}#pM-Idg|)MxYGFfT)!K%wRZ|*v)6PMh-EMzPcQpi|aYzwnjnms*Ag!U` zFYTwoAv!*e;^gJW)RQAc?FgiQiTrcSFp)3grsi_tkWG(7a~3Bk1%DDF$8PVYPV(ynDeVuJ%!%uB5XP>uB3wOsStRfr;j%@VqKZi@Gq(q zR>pn!!u?PL$}K)X()r{4kv>bs!Ma+>)lrxh0Puci;SEq>s>+j>**v-v3Kbb8SCP`g z<-*M;ko3eQ=hbILE-?%%4quJ#nqx1n*3o50bxKnPM2`N)f!x20)8P6Vew@_}1#&1Nr>lEqDjFkI`nn=NI z`AwGl8e-wdt1UGnEn|;E0Z_p$TWwmMNBhqNNcU-AU2i}t8NQyi-+q4@HAcpckOdfs zegX_hduuQd)fyUzYK@=#`7m)&Y0yaQ>dx_r*TG-E-cYxrggXc(sH|i)+^tk$eCGN; z5BrPXfL*s~!vUufaQLS(=ek;r&!GXjUq4kBBsy^{Uv59KBgl^iq}qg!GuxYY1ZnPT z5R_vN+PPc-0Y~Z1Y`Qe>!$^NL zUH3y_szU`ab4G9bh7bC%N9~m#=&ZDeKKv6%6b@IdY9tp51rouvK|2o%dX#(Bo~~Ci zEy7}?m}E?}HSm8phYjH2^B8CK=e8B;p;@KnNV5vZtVwq>UV>)TTv@XUWYZ)WHp`^l zM4DAv4w_ZaCt2zysU}^>=>xSZjJI-;kvf$&9|}xV$T@q?E}gu%7xVFf39mNUL<5wxQxT0=P+b``((aIl}if@lbl3CV-ooXMu zJJkKvv2JynNz+tbTp_U`w7BMjS&0XrWB4#kU0nek6~pcea3(N=Q=oX(R*luw{~)Z> z+l?J8pp&*H@qNz})aGsNd#R{NB}6v-3JZjI?Dq_t&rJsejGq0zpX=@wcz{{g<#8n* zXY{zedABzBzTB?6b$H`K<9Kj-EvFt~`*&|SHHxwQ_S2_FM|^hKY&LZ}7Iz>z_VJy6 zi=DW0|6>ZlnxxjLlhhhj;;^0j?J*5_#=fj!4slSwZV0w6(^(e3>OvpHfX!Ft!PoPS zWy0y^mCo_R&Psc|hJJ0Hd(^iSUuW!oPhsDlOpRIIu=jNvzKr@Ov(G%IgliII7u z`Umcnbl#IoE@-xPWTu5GeQCPu8xDxx+qlfKocig{BTAE=LTQ7%dY)u@K{q;0vDvn;u2jZjxd(1 z;^`ef`azSb&-mlHLrT@^42#96qen|6Sp2n?b_#l#u~EI6Pej9+SiV{x#STs;-Z#0jl@X;S^K>YM=S@WaM59$odCobc$+=!oi057r!@FKnE5WYy; zk4`VD7j(+wepI8CeKRavO^XlO(}1bO9&-9AO5(CKpSnnK8Lc0UFC7AIq{jBRF*bJy z;kdV*BIRTu^oLdHu1)8fVTuEoxk8jM!oKlrM8HJeq)Ol%sQ}yv*QGl?9fGA)Evc(t`u%L7tnA`t^9$MQFx7XA`d*lH}PFmdqPBBYn;VpA(oaAfVUsw5c0@7x1C?Y3s(%eJ+xD$Z^qJNh>GkHAARhr8`o4LUk? zWd{e@)z;rr&dL@=D>DwGDfI@-?$~RdgUa}=q9_qZw4!s zfCI09?fN|dZe{|w9@A>YGTV_rQWHtdB&jR5?0b;Yc)X9eI8dfhEiBe& z=RRaxVtnNK4aabLQ?VKVD1Hw&Y8ZI;UOy|1O9pX%9F0v%pmt4_FT4{#fT_ zQ4(L_ObDzDKuXo8w$8OR0_J?;ZDrdroZ_tYsh9Hk*-`$+Vf7Qi$%E=Zz4dzwR$Q>K zzsEy!#05s>SEt*KT>=;)_cU(*Lc44IFUFxaZkbxt-bj6UT?(4!7EZX`zB)|^tT!}n z3K6}9lScFjw1B%MJSbk7-mYimG>V%x1B^F)Bi5=pkhXnm>~8(+a#jdj1 zh48jz96Mxa3MpO5CxWM*Txmb377elS}2NCt#W39?->YEf?3>O1C_rsbb&BUe9m%`;& z&t2F@ZefnXp{B9Nja&6~Fk5!DJ=Jh1cJvW{@Wd3;^_&1Mn1Ua(6U@K#+hQ^wHfa+- z;D|rk1zJiNtRInU$IdDdTida}kX710zZk&E?dL8oBILh}`hIlw0b7&<8~ciI1rxEq zoZi3bpVZRXK+^?SH10QiMf4K^D>$3@fJs_KpwJCS*QnWr+YoSZIbdnkoo~2^d%5zx z5j5y8TB$j)xC;cseqk#B6b$9wnlpZo41Y@pOlis}t?w z+Q!p5O+W*jT;WP#!5iMz;7Yit^x`m@X|ao)|7?F+u4sVsE0k?Q*%b{a{l46;)10+E zGs%{}zay^+y$Ve=%(9WjT=Lh(p(1~WjJ8+fYuNfiqM?5l}8+ygr4Ms5M zz?0;7T-&Qe?Rjc>sy_z^kM=Yg2AeQ>&O;#ka5ev26b8(B*n&NL2-j^m@4txfS%k|G zUWD)+gv$^nM~NAsh-^dz&>I;e5nhMzO9qj-E5nGUrzy3^1^aVuY6>{5--{ z2)}?ZV6iifA-oXbXAy2jcs|0<@BxodWpWXI4&i8ovl0FS!YK$_vk-X!5sa1dnF#+8 z;iU+tA-oLXO$eJ2UWo8MgpCNJ(vO@)cr?N*5T=*KAuRF%ne;J(9jIES5uqpt%Fd(@ z(cxMEBhyC^4nY`))T7w?tmn0Oa1|1&aU%d>jDyS*2&)l>CT3<6!U}}JGMS7A&fP^= zKv;+HPY6RFZZckVuG#ScVyN2WTw4U+s4fyp?roV$Q@fap%f2b?>@ z_X?QYj07qeye3$>xz3f^ZJ+9hXnpTfoz*={a32SwCfZ7J9yUxzPpBOb8JL5F$EsOB>)5J4GcoV|M8_p1YVvaVBiOJngM5#bT zX>tcqdRpFLfD4Izn1FkUD8(MeNioEa3N;J%W6s~9LMz==sPSg*Ut}uOQ7TiRYYGc@5EWVoknfd8WhykO zoTyN*RJ`Lw`@#buW0O`Wyk)>M{L+^t3D{IN7722AStr2>dxS=2_7I$Z0qwHg?mWsfSfqZm(oKH4t@2D~?{5IpIcj^5p6J$u6CI?d zx8No{w+U(xq#n{UX_j5{84we2GVoJ$o(!~jl)4&q-rj}u{0m6W?XqQuj+xQQvt-h< zvJ2^%D3hL%AU&~>{KJ6njByh)kxM;<%N4?emhqqgUr@(WKfs+=+iWzH>n=fTXSxTu zDIeip7H`_EPRvIb(zq!k9z*=>9mGd@$kSJ4^7N!ko;G?WPPnHb6FN!KdoCIfriWUw zV%4XC6m3C8Wc*WTWLp~7CDX({dkim&P>|L1RQvAarcI_mX9mTnP;V2i38)k5{vCGWDY+1T(s#tByS}tOMC9}>{5EEq938WaEHFn_c3*wW- z-)ju8?0l5WRs%=EqSF9Z#EGu&M04O0D9w6nz>h&1Ho-wBmBW%tu8{6E&isMNq2aJOiG7$@!7g7)Q=>&a8pnA zB}WGO-d(H55(?K!_KG8wQxiwigBw`!S$ZrZ-}+v0bH)Mv z4f-9Yvp6+qhH9PD3xLPi5zoBtR?s6`5m6`jV2Xsoq;w@TWI$9_>o$O9uhwD0;1ES| zZa1gDqP^OKrV5qi{08-M@?leLt=P2BJd2$F;H^EX4evUEBo=zaXFbanv?tzm7KeWE z>#rH+3ivjCyIN;bRdEo$Mu@361oXuVgD3?DEclb4LoH8Q@P1CUsM~U&4Z_#Ddr}=L zFh>5MQW&4&SOv=TERPhbhN#yp5rQ?ff|o`ssO*c5dQX~ihiYXp(3C$DfqJdyU_OY~ z>7WWKLw1z~)G0}NO%xJZ!-RYR?US$)&QtR5x@FsT+tEQ*a`g_T{UHr9Z%(9 zLVL=~6Sp>;?a0^X==rYs@(*EQ@noDMZfiJn-wVFJFLs?M|CC(%@Y8LnHr>Vs6=3V; zaQ?MT1$xU<=V>|N5>M6aD0h}DXD_P)g5Hu30*B{ zdv-DLj3NTq_+H6327md9r^p1$XtT$C6A@qpjX1Rq+#?utM!jUu{ib)Ho_|^nPRM1L zNm^1Dslu^nfZ{gh+l#*$V3wbcz$1-r6!Y<+&~$krbq(OuZbmNTcSKgCe9Cc!HfY`a zi&JO(HtLyp=`|WQAds8vS8+OB`0RzUhV*An*AIOPRUWHt(cL{g& z4vF8!K}W8=VuqXcMVItcu>(^96=JCkr_zz#x$rL7WFZ2=P`?c4=p$ zjH|IXUJ6l+t0qZZFiGmX+>*K|}=@TL`5( z&2Pu$W{3jJZ#j?o?YK;P#kVWvFB;cmkGUM<4t`;ubvYspZ;KcGwIhhHJ5E-$c@%2N z<95*sxDV4<-UXV7D{l;a@eMau9&NwCxbVfz{6njAFtZpLO55u$54YNG;v|kEG%TuJ z-z~~~fm_tUsE6J^sNymz0LCzZ+{Bi{ z5@}NV1K83RCM{|bJ5~8>ltPSbSsH*LW`o<$l|QZ0zAC6>?2|ETpkM1cX1WpVK2`Bg ztzI~PF6U!>_QlO9+~hmPuovHi8tW#iH}GMks(6Um0$zN>Ui065S%LlNe}`JX!(t)# zDQJD?CD8{C6I6pDOatc`%>VaLz-#y`=KHSBfW3ZLUWqX_&yLmJf^aFgcVT(2 z^S-MS@WS=DvjNvv@wf37Luv{_uizSo>$>bXi`s2f!>m>m|1MY?tmrsDqv))0R^A-Z z3z?qhw-?!3;Se|Pg^nhL?1R_`wp09|)zL*dykxF%OWq>!Z9J9FClwt-dN5Mw@qLRN zi2of`dQ!9^&wL}FSAf`4yl+u0t_x7^LZm&DkHE9|dk&eNhDX0*v~?!`TG46aj=VAy zli&FVOyXR#&2jO>`(}3UU&T#x@J45iBd8H`MN>=RPb=LRHbP>$>+?9AN4+Bph!N#J(YN(EMwAU&_E^PSA@LSUgscmL*TQH4`y5PYWmDVoRA%)y zSh((|%$)EP6<}Jl$@lOmcZHxHVH5L(#68xZ@%TX%sY_t6x{fwcPFc(WyxgkX!_)}) z06Bl&Z{$DGt|Zu{;@dEEb|6064W8oqbhBHa=mAr4eOf}WA^38rmC)qdx4*E{xD0d1 zJ%6}-Zi2Kc^GR+cRwiG|Auwt0I-f|oyu6TST1;zXEk$>Ky^lb7*rh!gQ=pMI4OflRsro8%e5 z8(f3Hw83!@_&$S3nr*MS+OLw2rFQQ>PoAaewJ9KcN7ut3eA1!_2) zk+drd{re|EW(YiE*Cbpg;F^K_3ICo8CFEj=ujVwutoni3FT2c$?< zUh=s*Tx`U{A#P4@+njXQHO0RdgrydcY8*T!5BC!F7)TBjy&4?OSu`7rf2+zfzJ+Z! z^hW4NcaXjy{_^h>q~r>5w*e>QZQM=5gt9NZ5$o3p{$;PY5i=60S-=FM$H=dSc#Z zI%PfwqeOf`+s|?pr+M;hK^|UCzb>awa#NEe_`>%+;fAiV7k?KU@qdS$vS0WvY${nQ zdPSzY_LJVtCI}TZ2VrFFh_^*t(p4>P(hC6ut1{Ypi*3lm78u|diF5J*aNTbZ>(ecA zBW{H}dU8?D9(%^k;fj9+*oB)RA#&+qNQDu1o5{U`dxapr(q4PB%xyT8GJyQQlZ%)@ zK$gRl6KvUh-%_8l=SqSaj*zbK_lJo1v~Tz&#yTq2!(8!+Wh*W;uR>?9BwL74F#ye1 z)r}#`kWrzYJmj&9;xN2grgr*+LP&G^fZLybK!x8)^~xVq^@EQ4wSt)ZB&^x1-MT{N zY4?ErasigZh|YAp$I6Yo)0qIazw4$zY7czCqoBtBUW^g96)Yw&VG84~o^}q#E7MU$ z;_^?zwMVL2=frTCU<@5Fvs6{0-K>V@xAL&Fp$-@fOrZgnD1k@Su#{eDxYm&tjkI*6 zU9dJ>=tvAkVj2=pHXNrG7+H-I^7}2TNpTIh zgV^#FS#0?V_~Cnh=vHVcoR?t{dmAszt|*N$oe?+{jFHy}MZ&L<{<145FD^9=Lh;E5 zRfAAKWvl5S=MFzIpGIRV?b*M^nI9Bh5<(Zf>&I>+zBGO^d*_LVTZXP{vO^XH<% z!iT{;N-E4H?2i@a?8kl$@fsOyQdZa}9|%fpTv<5zpz;&d4)9gBxwb$v07AVQ|4y`{ z5v^FfNu-BgYL5|s_I0gWBgo;O?54YYymnFx*>mppvsOT5872o%;dosKR+22FtOP6R z`4#7`T)t}l(HA4f4?;@doBcjki5J>L1@1K$ z{lI9z7VFCf{7|S`CBX24tFMK;Zy|i7!!ZmFyqB^$A6g!Ekrpv*Po|@=4?X-QhzZ+r zTm4;!_^-il+EdQ0Uy`}YwXepXT(OT>?BI)=F_!*nAA3(Xbwq*cB|&*a14e;AjK~#% zdx#M*;?WLP0ky=m-}{Od`i@G$7knoVhiSw)d-Xk8xcLBw$=!YQ$t}>U#SnvV6T=4| zE?bJ|SSFf#RBRQ=7Vv9MxH(L{TjXI0rX@P1gTn+fr4@)< z-$xT<$xXxcPsNgGaW~V!%XrD8+GtF-O(jrw`TV6?bxA*Wn=*5@+6Pp)Z0|&7*u(jN zto_JCoT(W1N-%ss%KZVvuoC!Vxxj!PTEW_~%EmywvxNbjvHpTvCTOg`VC?nPX`tv2 z-M8MZ}zpqYbOktVLO2Og3OHeoz_C;AA3RbXEeem!XvdHiYyPxY>)7>>K z{#kmfYZlXyO6fl0mmT$O_Rr$1E=V>OpaTn9{9)sDgmkkhXR-bgY=Y~LG$rz1zyxNW zE6s`$p?+2WMWN$ch=j>i{ME~%5)@yK?3ipR8QL85A}oJ=)>Fj(xN!^al2?K?I-A^(rlGS%9dS z4z|b91*oy7wkF1TJL^jW(Y7!Q`aP)`$;_zh-Ey;|liHug*VGu$e6q!K!2AO)RePtZ%ksQMeRB&0u{LgY&-XWfU{T7p#!F#=`?mL8Y<%%lt z8cASm03-lX6=P=Wd6P3$hylQ|>sRaV^j-kc|F`{e$ z4Bt?Z}RUTHZwj~(%hvcDs2-SO>c)@pVREBr}p3)S*CSnQj@OmFz z=w|iSgK_)oLnGvo{uuqbtc44pn;`Rg?}FiccNT%J{~A%aAiIwEzi^F##a_1PgY3va!mD2lNM+%}AD zs>4Ys!);W$cYxcZ6w3(=N^6e*zU15D8yPQJFDkTLH_WGFe2?8tX3n;lkA+3S!rR$I zNY&lW4(w#5@>Up6eG$ITKJrIv{ECd1taV_lUf=^BBT4d;ihTGea{bpy5DHH^Q(}F# z!@~pjCStwI2J*vTJaYNR0c3*W|5J3@_Fu}<6M8b=&%EG!0E_q;y`UyNC8`HRqpJf^ zRy)&FrF8w`f%{tkKn%cgxlMlXu4VS+KZTO1btITP;B3OwnvAyHrq(-tiixOu7jvYM z%(ff8-m~Ud%l3yFnrSFg2@{)8!dUy=pOSsMes^d>rn$`yn`!iX+qrbtp#pqhEw1Ib zHc}-KF2i3=dj(}j#;!xx?Bzel>83^F))#I9nhe#pe0gQg)gV4#+H@fTcMjTb{A^Od zdqnJ=etk}ABDn}~)<+e`fD#8tAP0GPOol!8PV`u`o`QQGgFy>}v|ey5+uO!$3bbTm zRe~5JB%5`r#bDE@v0=OhB+ubhyZ1ymR+90K{otJxMNEuc{mVpX3|M{{9b0aMR;2|_ zONltBKwFMP+5Y^n$R!>Hk##uItBBaAG)bjpBZFW2C=i+frg+;+)nD9q7jCeEGGF`1 z6&g4k_syYY?+iWm#V){v2gjV zqB*YAV2;x)1~Bp5*Y-)ZTK1xnULDh$8S*_3gwg|eNxudM>}<_K;Gq-u6&UEb-?L#O zPVO)r0RKueU9S#KbCoVYJkk@7MtqK_=!nC%tu))-{LbP>F$mngpRnT{CeQ)$`-HHw zy=RH1Oq_fH)`rmu@ZI5sV;v9EAZiQ~|8x|5zF#UFpqUP?Us8 z*+FbY*lYU|gWp&*{^{2~!niR91`AwkEPh#Qyxh<~1+jyQ0W+nK`>@!Qqe}OJam9R9 z=4Ts6l!jc2Y#Is~!G7Kvo$&g)H&(nmsPrpo44Fl@{cFe7`ebVGRcS0^1nz|X2OTrGRHxy#Yd>Hjz5zIzB2IDCq z-&QaM018TsEJc#w`>ohCOA!yVr#$1M=$IU1GK`)yrK8suHWv0mo~t9SsG8!T^r4yl zbFnU=55QYloWEXEj=y63W%*0qec2?~pcW^=AZr~Nyh=HJ86WuCKHExLVWV)hx8O%B z`rTtvbze4a2nt#s`cR+u6qB%_jttOi8oTQ?OYs+jKg^N*w`Q1!+YH8DuYDv1hOifg zXY4B*(gDNbKDiOXCefV;+{sUl@?UJytETZV#FZxXV=)8J1l36Q>P)vSDlTkPyx+eG zI#F#G?0Hby@|Mc`vB8R8KauMCu}RSxA2$+PrzYdC*kQ)O>NXqKF_=_FV`NEK>=*+t zI(V45?;RV;Y|I_Dr96FqgmXm%WC;ta38LNvj3ti??m;C}I7k@C|1!ibk=s0C zm%;xoc8T1ALe_Z->G?n*R0jEgrZNO+e>WE59l0F&*Gd<~TjPE)_u_B7c%!Eb+4*$c%==4lkBG=1l(A8U@=Wep zg7mRJ3jloH5_dh`SXq9EP%5hrQ8vlhiEo1_k4!>#i;e#wELyIK86mPoPLvBvKN`;{ByZu8FN3qg1zy{1FhVnTwmnq zb@oT1Ml$Dcz|;D8KX%V2oi|`tR?u)2aro+_jr`-O@Zv^w_G~51reeKis*nM(!6O;NT`j<*!2CWO5IZe$u5s4v4@HNV$4|>^ z=0``S;V)ej@H@$vIeQLi81p@LWbvuXz?h8aBMy+iLc`?=UYLIRr|tYwU4TBjQ>x~d zEon6@st1YHG$ie#X{t|=(lo5UlKpA9RG?vFWpSDwMAQef(p_%`N;Mi58cHHI{V7oe ztJ8q#npOFH>@*N`x*a5RlbSRvLZLe=`S+yj2`R28)5+Eh`qyNcg9WG1DfpWz<@aQx zVb0+C8U~~S7{r3uI6Z!)(k(92&vBEA?d`AEb!mMowZ0ypf7mJfsSgm-@Ppj#Y+RA| zh`WWUts9j8sg2J+-XhKwGhlt(V`sH7@w3bLj2j*WS+^psY%Ksq+8*~S(vlEiCzMBi zilj=gLwt`akPf=ze7J0{oggg=WI@5(@9<-`|H4~$H;GQcN3Je4)NW}@AnRl80TXgg zSAlT>dvUV+CW~=k8*Soehi?*14c+!^C72@PY*4%U;%Xk@Q)*b?^#@APEu>a9`~cz> zngNG$V^c9cGBG{`J~gkoh`|^z4S(rkE`BGG<)e|OF@pBOc*ZChy^O;GqMJ|M(?^=z z3tV~XRb6rFKxZzD!;E~uY(BGcr>mBQdKV&8{h$9T}Kk<@P%&B&+vjSpr0Nj+3@kAK~{CwU?j)_=WyN)`WgPp zZ-Rcl^MRD9X7SALe#p;vR$|xf0>;|+;Qt00Ohz*8Ti+G(^PM!+gUGT)^ig4gJ?Ev6 zfUxDBZ}Ok6dBtHDUm6`0X2C`y+dpVKJ}S%tXyG_T*jxCfA@-p!_xLx2+=|canJ*7h zy1odt3ol1>Af8o};=5kxL_7;V{lEDx8SyOmeAn-)$hPa2hAR5MDlZTHp@`WoboX9i zU%2#v)uBJIc9st9=X$?9-6dH>h>mHI6vFwQ*jSzET>r6l)6%ej{yKQAm+&Bbo!`t@Ub=^si`LpQtOR(#gM27I$)Y=R>~kx&!i2j1{LbSldOSFk(c}Hv-2U%oWF%<(6d2x3cJYq`6pwGRSO0Oe z;_)eiF7CH+Rd#nnl(35ir12bPxjsu%32%DhqpM(Ubm#^|OL9GI| z6rj9nn>m4wRth`9xQcZ3AKOyXxpYqQP>K4mKs%sUid z`lv{oUb+^^LPL(KnpBm^#rhq|kachtfn!;~&EZ!s<0PGd@i9MCpkzNP*#t`;XB_`_ zbV3r!HKjPYN796S1z?-r^QQ9SioU!&D>)J`qRl; zI74wo(LrqbLQ4?Uez&Tl)GQ|*!?cx8C75D6YxKr2n( zgpGKELMs4(@m^aIl)dhOYNECi!xL1y)QCgqr|2Vii6-gVK(^5uMbJoBFwyd1t_-z4 zv$wbyEr@)aABs4*9CQ-k8DJs-9zw!F{*z^v%w5d?gH@!+A3V#A zoyL6*=Mx_6G#E;G?Za`Ta0E>ND5m@b>~>}5uDjK6h#k#(&JX4lUb5yceyL@HO*9`U zbNiggTzt1o)I;RvI@t!Z`+(^Q>8_eDIx8VR6-8X@s==}I@hm!06dVT+!(_c3C`wv1 zh^_A>6qyvVNzZ|1KWNX$<6JYC1zAt7rt!T#$pk4+-M^@)cRwPM43$7S*nYP#5%Ymk zYET=@1K`cI2S7#?Wbjgzgz?mW4Q))Qe4jGm?)c-g=OAqyS`z$iVv?e|F$$#>2o*%s z%_gKN>fyJMe+6>pD5Q4=vr&^eR{fLVG#kF_J7|jIBS$Y6ykjo^z=B~~cD5`aY99L;nlnA-sOG8u{N-9QvHt|vvB@@H}9R7z@B7^8A;Odhj5CUks@7t zh?xfjjcd&YLo7s`gx`MRBf#}D@O{NN#6n54h&0^Z7%xp7%cfg<7k5rc?lt$3q<3-Z zMCU+NAoEs5FdvnId8H<7bYyWoTtEs?*mUb6uEaO>Qt5^6#mTU~?J0C$7m?Z9b+79a zl)K?7?cTj-!g>z2T!4nlLBo>`R=YO5Vpb0*bYSx2qP4#>R?og9nZ~gZ?6S0E9DB%0 z*}lUgSGpjdeea=Q4%ddG>mhOL4Wxl~Wmh^0YuiZW^&N12+EY==t=e#KXToNKqSfB) zyi-H@!FKhalez9)z}vn<{>!C6Ckw^!+3r5TX^(ac4cEP+R4pmZ$oSAz&Vlq1QBzl(rd}(JBTfOx%DR8g9uLy+(mt|C7I#1idEoH}d{g+ESEz z8u{tkUiLY}DXi<>rI4j#_AVIDE~`}g_J7|by)=YHF}+kigpDvL3sWqgals%l)$cFL ze3a?1PIaq}BUU_=3Y9oxL~+usA>+rA%Mvf9LKqBExaSpNaE%H}02aBP)zZ=!HXgpHdt?WjQGjBP z$bp61y~u&nX7Cj?WPUFTF|>vpd&2RuNtdr~d%Wsp9OCswxuqpG1s|IooB*XLjgpHe z;hHR2BqYUHoMeMVA2SsBa4(qaCB&H;h3>#cWR;6E1KBx{*lM%pj{1sP+sg{~>n&_A zGR=pN$?}9Gjyn(!ukc6F1cBxG5V?0R%MjpjQT2pnrPW2-cIHa@(J(NXQo!C$w<+`Upbr%-N zRVkcp!-<~wJpv*3bzEz4{TJ?%oina$yJuLE`c;mSnfV-d(X0n=hU1#%>y@rHAmUv2 zp{^u-(6&o_zzh(Q+tuhoZxh_A2S#$;Ii-*A{cVuh&KiW8ZuSgX5tuKI9ZTmU}Gm!8uph2l&vC3;TC2S?nSQwacW zRB9AnoU}KV#r0MH3cZ1xmZFQ9x7yz8>?iDmcTkl1tI79b4qcu(W+a zgFtZ@+8H%&Py^*NZZ^B(wtHZFuEW6KFfb-kkyS63sfu!8!L3wgP+8c{|6%gdVT4$J z&DLOy0#Oj*yV)8Ld#<)w2;a->)t1d!HP$u+rg4z|LeXz(f|rgJ7MM8MA3R26!ww+r z-jWMkD>u5YsK8fydAciF7wKx^R)LX25MZkKb^CXKpZ z)r*3Un0MkpDOVl5CiKE4ksc#*^kNjEgU5zU9<}iGoMxi-i~vRvOr1p_$Wm z6O)QC92xoek>|Ohr)&#}rV|A;&;rjqA>VS**_vdUZov) zoAt}pRUbA;w0x8TSK&yVTXU$|3=N6DRDe{iPA1QR7&?8j)jes_8$1H36-bN7(r`b+ zkKR(Q7v}}7bo7$zp#}^bjNwKVMl{F?Xw=_3j=Wr%6)ThL(aJISwZyU_H|_=W4;(M^ ze0Ff@{(w{Zz(jx*^!D@iXwuSw>DODEZYiX+JD2wpfCt?K2j zRNJrAvsDn;B5e#>R~_54Xt0@O_?mR8ekMc)QCC-u!j$<1A>XP|XsX-t*Kt&Pm}k;g zari1l+hx@J4&s_@j>g};H0i={)^Fa{3`^lP8uA&Id*kuQvmT#Q(Lxkr-X`AV9RtZz4Y zF@^NJXVDNz7{Nl4Iu}r6?3N9dH%PR*j!|ZADZWYptUyx@r!{>j^vd~AD8Rj&SJXug zyxit_xpaO63k{}M^}rs8;m0YlDj`~8I+ zC8$vk*u>xca|zd86U55ht%@<@YKw!9`UufXCx`BL5H{4P2%D;V3y=*}@Q4mo9@JVR zXvuWY~H@Gi!I zN*G!;0NN`9p{k$+F7Ln+vjw^Y>8=l9(Bujg3f((VnW`=weMVcNRhz)+XmDXYy1TKX zfSD*j!HqRoXL1}j%v0Vq z&(u}i`;le|jFNl7C^>>E^iCBGmYg`+;6~iLf&$=VV^XeAKv`}VBEu%iaGT}Caq7>Z z(R0^av~{f?T4oP7QV6p2bTyaRu$8N?Sg?(&QE@GG{O52J$vs**k-Cbe z0?KK|bUlRf3uvu?n#$cz+WQOWmY}%0>!{Drf1n7uhoHYy=r=5kg4Tq7D_a|glrpA5 z-fUgU*lb;L3Jx3H0qDayKFr{pGifB?b7)$6y5sI_E{Y52+8wn`s7RJzOLJLWU=4IG zAn%0HS3?zHZ6QX5YpCesY05JB+t))gRGoaZaun6w@u7PixO)VJ)nOccLKgMe8hJc5 zq6!(M@QhxXBAd0~^ypfKuJI#J@2)@Aq|l0tvcuzXV~OCvD?cDfNexV`-A6b@6rHl9 zS!OnNK$L%}LNimcDGsXWAx2jkg>mUjOJk0i-S+~> z%YQso%Y-)|hr2->CLb~XRO&PKz zAugJk;xGGTj^MC*q2iP$v{ag(3ZbMQ6qp4}p3Q{q6VqAuu4m9~?@9Yo z+3?YHc<=>z)qZ$rxrAzTJyuqCo*7yWQOjd)ZI(hOvZz6cFz87C3rvSp9G!c<$1IiELosM>gcaw&4+g>MAWtPAx_a?I2gkzwp zo1xmx$ta=rB~W_v;lsw4f2&K#t>&6cM<&pm&uK0s(QY>QR0#=zm1^kKt8LpVwE5V%joU&=}b6x%1S8%+8bRolD8c>sjgLEx?0u^qVp@&HcO)8J%14Fg_4K-j*! zWR1Am&Ey3pn2$=s8L)3d$er%03?lvGT4HX11w~@%t$APkjb08milS28a6t4ICYqyQ zC=ZKVER@lJHSB?0q^VeL>Q#j!lTd|liJK*})l46O_%=~zy9Rcz0e?d@y@V>MJe{c( zpUspi(^*DnaazK}%?dhjl|BMVH~up4my>}5(j!v9Bpk_#9SH;1A%~i4%+zbv;qL$B zuXeItv;Q~p{#M#$lv{@UbZsxY9B~ReyLTz%a^~JMlUS6>dMew;1&u87>A{^ycNK4F z*Lf#ran4Za+rw$L#RAkwIL_WWh<`|S2sx)V*)ipk0S+N`K#}^hj3VW62$|+03Xp~q z@b2)mF$T6zP-duFbF>c(eiqKx2tKeT+ME&xtD@LUm=*DPn;=1xU~-eQC#k9)9tgu; zgj;l{$$||ciwQn;>04&N21tgBFx6mSwQt~IpLXpo#B}Y3OW<<5ig7S$ z*ZZ0uFZdJ}G<-2Rij1eGIwSF$ z<&41ZG^ZZF)15l}X3IuZIkF+uEN6eDz?{mJDW;e90=u2;sicEbS&X%6Kct_x`GB11 z>8^5U^krLcHSjCubuZF2_`<{1VqsDCrZ{pg4Kj;Ux_);4gxn&nE#(?ZFV`)^Hr496 zNY~Fu@p=1ih&wA+fMtO7=uKBGgcCW92({J@IN-wvJi#e|JBWA-!l9hC7hE8@-n@ax zNUj$^Q(bRf0UmQV#M6)wyTY4aBM!KhCvrXUGYI3bg1y)E<_Uy1BJ7LsQRM4^cm*tx z=(&T4_d?w1iGPfEAH*+s;=2&<2SAJ`?syX3BW+sn#h~t%lVK?Z)#Q59A%FkII3ins z-$AYOW*M0Yrn%mP#5nJWAy3|8x`CWKQF#vyPv=6wA`giUmXU6LPwgD5=|wgzL6J`!P6D)r4c1T4t3 z4T+F$&0d7?pAj}73ytzGl7SMdZJO^h!P;my>E9V?o}Vn~aatzbhSk42P54Xxu-8KNphl*Lv)V;c>e1dU5J&@Wfa8%2Iwq-i2niCrP_eU|K;?5EvwE ze_xa=Guip>OA<7}oVc*<7(e4&g_MxP9_n9Vj#Mpnd}-ugDklW7vN+?4m&)Buv$n6a zAqP%P1GWWA&K#E12Z35$?`DA$Wmm%x*{ZDO5F8}h< z9Fq@d%fz)M#vW_!W^TFf#VsK9@$dBko7+;ZLj30P9J@}^CS4ZUqP?1VEK4m3&oD#xnQ=>_mOe2yDlTEEAGdewGi;1fk#$o#w}?%X zmab;eQrz>*>801}r!JNLDl(n4;&~RLLfmif_s_GwKGLG~%(7Sg2bQ9gN|&=xsdf>5 z3YN1N$sw{7sb)F2^iJfFVpajcuyI}2j@2wqYF-Johf}NBpS;ua z7tV|IlN77i;JubLEL0JKH|gd+lRx35dCx9MeL3T~Cx@p!w|L2;^PbJ8>I~R>VI#{` znQbaPl#A~FcehQaG2o9<^Y7_27W^6UcYiJpstS|4bE)(2XkwMz@o2ex{r_Oy0w zqSgmmp!I>eV_$e15$_H*GH{gTj04`BetYtiBKL)&Q&i? zggXXliGz)X2Zg=W4wlETp#*G$Yua?n(HjYdKn8F=i+d<q5TKqgvMkG6S zu;uRmaw+%E3_dCHrG0;9sjwX>t6=@1nHyHY7Q)_PZ*c`PGcC^iFr{ug$p;M1K(T7P z&>~%W2jc1`DWH<+*-0s`lFdb|w2~PV7JupEO12HpOS9gEsMwMrEqj+uMd{M4g`UF595`xDi)ftV+n4-Y#)kyC8?(h@I3AL?!cJ659; z;<w!B2JhjdJOffy<&6B1`K^2Iz9mUY}dxz^O_+|#)TP*sw`9p$HAeC3K z!GTaN1`jw>aqlsZ?FK%4chlapRajybM>JCIdyqsP(d-r9V=Gtyd?Q89ecRXv{*ip< zZjm(AtdCbP@3X@p#Z3Do z1z)Bd=d1>ku5F13;Q-f{4?rU|SF^;PH$+pJi66N8Jj5LadO$M0&%(Pc5+XWUe8KxH z49qz&=r(FU1&x36$YrVQeM|^sKK?$dR!pjumhXVr1icfulRf2ow&PK8C!5G7OUHJy zVR{=`zzN~*@lkx|;xJhsU1NN|T_0Tvtzn_M_5K%!-H35}vaa+JsC!&QetL)c{eK=Z_qd>S{ne7D(C;SVmys>5Ic~ zLYpJ_p+Y`nL?FHJ0egLrErnw`6Su$L;h;jUhW&@y#_eLE5pr!kJRsE8LABL3a9p$J zN!0h*U94X})VJNmr@P4Y{vCC#*u|oHoxM0rb68*#G@J-^X1KRSeJ|`{$*8YxH%n`; zZ$X#(F5As^v$IlcEer3{L`xRgV^xg>i{Lardv_C`fOg2QWdjV*jKcn zl(nOI+ZzQ%CjM>c#_yDvC*Tx5J;z6JJtP_8%)x|58=%l*WwS^7%M8U-ar)~-D&r0)|YzXivX!D zS8+YCK0P5hFV1mEB3A{?mB&0eHdyExqz~wt5BF=^OYoH0cz>B=sRi5>z{5c6uGxQo z0okXWgbQ1#{yaXyMOu<wU?4H9e*F``;L>9Su1-zr+vLGU>sA#B!T6oD@YF^7*a==wl@w&#C znPDN4nNg6dWwn|anVFSaR#IqYXkPG=8m;ns&Dq1n?EU@x{$S6{GtWFT^UO2PJo7wr z4#oeZ7ypx9u5u^(3blJ@LQYy@Jrel5tCraw6UZ^kX%7=h+Iaet+|=qAgXTz1>O*c+ z);-C$I>zj2?%>SjIm>3I>iDEA-TLwtIQmph9pbCwUQ6Xv?R;}oUCbTKp3SvV^{RF^ zi8@r(1+*76*F&m(*1dv>)iFp#WZhetX({*8lAe|iyh1#>qir7W*;)72oUvT;dWLkj zr0e#Oi)zT8pkhP%g{*t4_aa?`bY#}O{8QC2#~F>OS@+E2EX!L3k>@Sj zTZQ>OUmeqMJUfS|%}4CNDKs8hzHQZq?6bJ~bPYCxb{n%$-yLNbRo?09m~z%`CeocO znLgdfPnK0aVPuYFuTSTo!s?j%M6=M0EB70H$^Xex=aXcLtBy(0aq%rN>N#ht>!wu4 z)G^BQvhHmJ9pEJxCXD-{C9XVTC$%NM)59*vSjjChob{y>;5RXlaa9)4Z#a55+OIQy z^Zf<||AZb2=1|~4CS)nl`X6-WBwx!VzplaiAQJ<#bQ?4&dZ7v>;aT@qt*VZ(c^b6i z_E}PX1C)Ks#Y-B8*iY735 zXt2{`13D>10!0z}6rIY&plw~?gsjj*K=oWO1ejw`OSymh*7;XKRWL^ZMVVvt{0mF1 ze{8_oTXIq7<|3J~Usz%T!bq7VGa#OLR%{CBPWW{fD~<)eK*$M8LeSU#TOl_Br;@yN zD$cL8H>zhq@_0-8wkwF8odH?*Hk3Y& zhaqshDT`B&bIw&E?ZU{n z6?fYul91G<5ifI&c- zC--YG$B_(Md&vz|Mu17FmhF*2K{;|+|18eET!@+)C7YR(&ZFK+F#0e=F{jE^mVY^4kstMu2o-CL4uMeRL=PYfDoUbF z1exnGFMCLsdl7Y^BMWC(w#NPtgEkGCUmf6KGS-$}8iG3a8Qo3QfKK zuw{FynxDLDz$94qZY`6$^bp|X2dFa;so|dcKBfR8xY62Rm zSLl2Aksv3qi?ea_VJ?i*G$L3sdcIFmEn=?_ZztBwW|mlb_j(g$HNE_aZ^ivyerjYq z`-LDA-ESrD0|i}Aq)0AYiUqYr*aFO!;|bjZ*48p^Ns;x06-g_U!di>2zsX}pb&TT( zAdEATWlH~9@qpM}pp6t*bxh$ATAn_s;hLFq*c{|$o=qb$y(9CI;mW$&S>MwzHc;;N zd3S}gnbIKO%AB?28wRnVOX<=SgXVmABSusCMMDoKYtE-PmhlmqGmYgH-4ov+B(vgs z<0Rtb>v?lynI$c`G}nOX^ zZ6Jvq&{!DM{KpCHhJT5CfRZmj{&VCtP%&XyoM(E1=kQNaJ1|jiYIxYy=2aiktgs+X zV>Q*&8v6r|6Cmn<82A{Xrn;%$z~h0(0Z;f3ypl$G6;%WLRE#-T5;}vn*EaNVP?k<= zB2;ld^*Q3tc;8%@-c);eT2o=AQuB0Ep?dIYS+AhxX{GQWM6w;%gJbgVoV&e4!sNNp z_ExvRVVc=lUOOb%MQ*)!7mIuPn5oX5RNB3=HGFqYEpb);(D3n2eCKZ4J5!;=b~I(} zrMh#vLO+KsSykm$<@Z>Png6a)aUy*bArmX~!{(}-qwj52a3(iWttcCDng3TITOo3j z6=j(X&IPIMU98m9l^&|kX+k(U`W~+gt+>MWWH2A>9Op@3r)KFk)=5LSo)WX^oCNE~ z-jip_;3UXU&X!izKi7odo^y{VtAw@4^v~87tEBD3D7mwm^ERbaYOHF>o;V$A{@BDQ zXzHsI`+IM*MKB&Ui=n08q|g}bo0%e~x2epWotJgwDp;FP=b5`XBDp1p?Q@el%6Rb?)OTYOmL0Q0(8a^Ee+}U=IjtVUZBiPR z51xww=9TBh$IJY`u_=w?-Yr&Dxj$Ct3`$Bkj*F8zLOnm5F)F}4-~FGMC+1B8X7v0({HDzhf&Dmb{#XBJt;_}0|0hny!ax5{ob2a+ z{{Mj!W_jU-5B^WQj76V17xP~UX)xEneuTG{E{i`RT`X4?Z|#&?d$Yhyj;fYqjG zo0??ZX{}M0Z@yW;WD4^1vpEc<-l7 z%CKx*8WS|Lj<=~=NgQX4*oOVTXmh;^b#N@(m}&WCY3C?q?(OcoKK2^R-I9jI{l&l_C>+OUj%j(un;ULzta5v#-1uUj zj!F+2TdIx$r+ly{sD`cJ9_3f@i$jz?G-+r{{fnk3ap?Bc4v7bUU?I& zICp7Zx%Im>jWC!j!R5TE;oJ{WjXBhYwdO2wIs)$AZ&n+Y*{j-F=1E~r4*r#3kIhT^ z;xP{1(=}4I9G3e2*I0RXbvedb@vpJA%X{Xrv2Mv5!&YpbVmLM{7E8PQ7oFJmnl?7e z-uym~aiK0>k&=5`oBCC@!lKkY)&v`DwkohYO)%X`gV7mSthS-DKiuPpE9$5ZC@wl7IS@fEz_f|*R50f);zBAbx)$iweWHIFcdCT zdfhy_s=~)d7ry=-1+RG|7uG8+-D{SQWgDJFOSK#3D%j0ZGHv4<3alBs&89}YW`1wq zr10!sb6vyc70$Z%Pd3fV>CKINtZgAp^_xx3!+^YN&A_hps9t$$OBni>zlE7D2eyRb z_w1I=VY2M}U0`=@se{-K`uD!3_989u&Q<#N>5@f_P^Oc(XR!me{#QF|EfJtyZW)B% z`#BaI>i;(bV8LBA@eS!9%#*l3A>%|N7=>Jz6}J7%aM75xsh%@yE=P z`j$#{Y=*DoE@|UhuVS_^Xs*9hF=JO}<)~KgXzZt@6o}i8Qs!|obU{|MjHAoK!833!^3CFBX&GAPrX`=b(!!N6|;CHaA zrr;Nw=^g`MsEyyE@G!W7{qG33YMmkVS%z|^-jkGGj|}QF3;4^@B{w- zu(H2Ikgzx@h6umM!)k4Puf~;z5A6%IO84TTS8#Gm*wPpE78cvip0*&kxs)3x>(0- zS-3wKpKcMG?hpR*qdWZJiqIy`v}?hcx{A+1?O>%Mge}+W`#qeJ^3RUOaayLmza@7y z9FhmivcB zg~6q`5x!T+Xm6iMB#q7EQrhJZbBg35t3`9OuUOkk4{xZAAv4qSOi1S#FLc?UU*LMkldH z9mk@vqUw{Ss{d7J$^P^!QdrU9*eqw)HOeh z#EQdTUgQ5)p~ZG;JRC;tzQ&@^S<+5-#P7V*5%}FE|9*TriRiX`!@!-s31%qYgre0M z-*j_Ml~!!pH7fRgYb9i|W#XAZe(>?bf9xf>mk($>)~)Yt`S?tTTtXfzxpijHW2{fJ z+sXgxc16!0dORj870;htp-wD;j`Mox1tBf54^40%-LWXdo_tIw2>@ibJtdm`_S?F} zpv@{NXkVZ|rY;HC?`n@Lb+yAWlvQGhtL{unDkfL|-8jI*O#(9W*M*AEG{GwBejTGY zmBe#6ucsh9(JW<8onMH#IdeWSco`O=OR}$K{s=Cw+-SoBbSWPS!h>ZOaO{QMq|oyH zg=f7WR5#m8>~tXuRYk^cL2PK9vU$M0V@VlUP41Q0_kh`@5kxsbGAX_gpoR2Rvi24eHjJv`htF8>f@2M+M zp*nO~SMT@8F6oPL^Jd-9IEWltlarCjL}bdR}KHi0_< zrEJ?`ImEZ>^30+2ED(U1aC+}tPM0pa#r(kX+^`kl*j42V4f=09rDwe4Ybm?)+!JiC z_^)nArN&Z54u0!3*)loF=3Z(%;>t(@jx%sUf)noSc=b-3SjyD(ddrNzp2psB;;+~? zE>~}9?U6;B%2Q1ZzkkqjA}qdldySafvcK1=WEb$i`l~tD5{F?_`TVajVMyEW#y`gG zi+6`RVVaALv@FT@KEr%z?iXmXutgfa$c7HOA5XSaoVourq7)T9>wQS5ypR4iuCWpe zYLX`nn&0A_kQI8%w14`upxHmU_>FXQW$~vv{-(;2@8AqG`gE{NbVO@1E;8dMuK|0V_7cyUFqvp3`jh&+JxsdTd(P>Cmpcpj7 zAGy&Q(raJ`6X!P9td|CxC!`wr*sNrgue8hH+K0jC*!}9&Eth(~uPgQ7YpoPn{9eBS zzD@R-^)yJaUW=||79I;+$uoHT?()FO+|d=i^?P@+0-i&f z?TOCo=>|`^@U-*M%FD?EFY-Ie`srj=EYUGO(Y-oWpPto`XYok!CIg(_--}%o59{fs z!SD1Yp}?_ulg;ED9odRJ5rJTh?BG>`F>z5vqKzXJ$&HZ|OPAlY!f@~hEJaBZf!yETgWoNQGNhBK;m%g6rb>`pO`PhC zLTaEwUhC6ZOE(W@BTKBxeij~QH_+2kW89f z78`_tcAy)ANQiT4es7W&w(rR}$AX9nIG$}u5FVYJkJPp#B)7v&)q~cihP!5aJg?#m z@L~t)K9N|!79QXARfr6GNkLUwRwhd*gTlZ-z`Sdbr>(Wb!i!lj!3HC`_lOJ|G`}}( zRzqqMU8WE$+?0gbI>aoJ4#nZj2lv z`zh?udqI=grV8u~b{PUkF}-X`vYgI(p%W=0yi{*p(uD*Ne$6j*Ygclr&HB5rF5*&j z?Vm$LauCAlIgNdx%c4ogz>_HUNAU~)F1CIgO%^ll6c>wS;cJ~3OP=I0z{A~{xLVJ4 zC;bVty_9+^vW2MBhRIT@vjNGMcJE2xd7_0qQNx#(A=d*HfFSq8g9QaqWn>rK8Uyw$Z2Q4@akU8;+NDvY%*izDw6!qez}WC;WB z?T5`GmR{^f2J`t28XHe$g<)Eyw#_$0)*k~0*iDia(JE?-CxPhlPx0jAHu+dtc6Z3D z+Xucny_A25V1TeiLGQf;GD+SUwJmo>8rh$G)Hr?j`$O@yrLeVsB??9K8?<*tH|3aML9E%_IPbM=+Pnw@h z-a<9pmtZ_f8$g2PAhUB)%aslkqmRyAK^j0_1o}f6-5QWWUL#=0!GYNGQt8!!BpAZw zno5G4p=z0mry?2~nvPP`Xd-sz18{cGvuz`JYlp$4H{n;-(VQV9fIXKCA@k9|^&w=y ze^sC<=_Kht3$~@pc7nX>T!)g`GO?lL4xZLI!yrhE(@Og}$}lq;`vDorEbRjiPXI)z z#ib;AZn!M{_lJ{v7;jw$G?cH^cLdobN06Q5JQ}%H&`6G+9*Lbkwde`PV{4lyNR>Rs zi(-o6#MgIaU3JV~+PVUB`x17+Dit^W>gcvnjIY*{qsS{Nv^VWZ(g%;?CmEaR z$4`=8q3O7Va%r>P*M-G(Q4gw4a>bf(MY=zv>I3SVO$L(pXm&Pv8+A2fNd)Rfk0mit zTU+4msE#R4DC%t+163w);ase2R4}>hPR*>&d)B>Ui5KzFK#!gWamB-9t8<*Eo==iU zdTSh+s;m?1?D1r(s#%|Sl_?AkXpVBzTRCJp@W)MnTG>huOduArj}D%QUhbp!Cz7$v zv+C7s08N=hJ|l6o%VaPFDQSWW8rC zd7d06eEwDI%tcIfLZi-GOkTolYnDJHl|ARAFRFY%XfMujD@M~!A7oo%4 z>C6{l?M|aVy-3!ROzX7eL?@Rn$pyMQEzZT%_N2J=)0NDz_Li^)$P79%k4z%R=z%=4 zoAk4e%LmsRo2*$ujosI99tCSih##gljZ@YAYrP&` z10nFG*VkZL+gNpL!CghYVH#A5e%-*-wsW2?u7iQ!#yX`Cb}pV**OOP+vtT2k*gdWK z&16Cg0^Bm^RB!ZcBCul%>Bsh}vs=KNSZjiX4VS0yZACv)>BX%~VNlIW7|{AZ7u-5p7k_~GM!-EM2R0ETWIMv z@+r2`87~v~%~I*|9oR`V^vVtr$!5FNtK?Nbr`}`Zzt|kLqQ_n(OVLr|PRLIx{eCAC zc=~WBF|*N_U&DbT*4nz5=+qE5+M$HZRx<}Ly}H9C)_S6Z98!_P)Le$+&3kmlo8*wZ zk-E3sNUc5hk`IV${QcBu?o3vwXM*+qTSTo^FHS1>-1@G-S9+|j{D|O>$Dhht`H_0p z7Hyn~Y)LnfqNl7+WeDR{#G4*|LU^BiNatk={b8q-X9}BI=iirzlp0SatK+%J;g#(V z=na7@GOVLV2}AkZB6G+AH(yaQREoB+gto&P61og~7^iaOA9~t?aIHHO_qwv;;Q2hD zPv|n7JL&?Qheet=ACa$a&(d*WBA?(stiedQR&grPwKDREuR(J(p~z(7dwhhHv1Be% z2kV2)p(e8F6+ludBTZ!E1GK1fPto!D08KNI%}Z%?mN3vOT8gYA#_%0n;Sm!*t2@ol z5}x*7CJk#GfTXYF4`4tB?FvkKmN1tj(iu+*Z;+kTGh1lgVZ-0+HQ5Ea<12IG{G<6J z9-zLDb*B4kERS6ImRRJr(e!K~kUVXjk}b?5o*!M$)AK$OZcLiUN450QSRo$5)P9`M zha}PLal&}0%7f#CUfzK?h)gXct?-Ko5qaYjeK=0&OfJ(-Hb<%IZ`qSR- z^T5LU85T}c)K}_=2)U<;&pKQ6c5x4QL9SRB)5z=s-#A$FZPXb)l19=NnWQ1eb*b_}UN7edBfr2lSkfZq zVw6}e*fv0N!*c~2TQD8|jL@l9Eod`+$p#jVE)S9i#(8we=J){Tu-1J4uVM9~`=1ep zl6KVbj1Wa!Y4{Z39T!rVln_0f(4VFV8@)-ke}h;Un$T`I!hZ?-0bVjy7)U;&wyA=@ z09h|+N6$?aI``U@F^MZd7Y^fo(;$Gk^k*6_JMV<%U#uh5p^ozoPO=qhOnks}=hOr| zV@;SQz=$Ap_HQdDjT)tw^e8$?`L%*Me1tk{E7D7V*tGW(n)*uCW9yQJuf`eSD zLlv5?tOa%*meIwZNEgi(LUYAbuWMgsaIV`%4z{(pm^*LcuR~JJ^v>8;~tunGqdq9tfu2|L$JrFkFHH_gx zD%YxK1}97{>z*)fxQc%NoY0r7rMfwSUmq94VrX}sD@4hEjNA<6jgeypS6l=yA1KXE zrsL)a-9|hGEv@%b3*_|+8mI2)hJVRku{ zPqkjM$zA(pju7Fd*{&I;=F|{s4fUKWv<@&g{EOT`nbR7YFjwd^=1+s>xTZ1@Js65E zj&%0G{MDmX$VgQA&mpdWQ$rbISJcPNY$jXgx9N$wLdc|Y5XW*|;lpOOipkRw1!2>_ z8d!n`mSO4+Vd@r2Jw8{Z&o@RlO3;cz(8;JwyoDv1f9-2V=Ou;COqxCqYhf&%Jx}Q2 zoe8`-@X8*j%)P^KE9iUkgsDlwqmA*4|L15_jibqb2J^AO*~p6DY4&`fThOn{goUyR z%TENtE(PHeS~_2d@%{kKm$hg`_@Zgmu(kB6vtRi?)7cA!&bgY@vh9acB~l}=4zM_5x5te&F6mRa&8K=c zGCA)vR4Rk3mE=W%!~uoGo=177I#Audsm4CWkmEIS9S_twtJGQlXdN2xyxkH8DFVc(`1bw>| zXOkyO^Rvr{uAmfpeXwu7#9NNAqC2o7q-2T}pj(?}5)u{N&9t z6qF`EM@KIbdWDn~=!@4L6)H)w2}6N9o#{#m68t&r)?6#yyGR&CzAaiTtR@?1!D1nX z^rZ(E3t_?*NP?EuEEc*2`zUP7 zo=!(D5hAevELtKA&CNG)+ZLO+29$_lCY9!li5qA(ah0!_xTG=@H>%LYrDmGAmtQh* zmxE2*>kbolWs2NbA{v_}r{KbEm}DZ@e{(&{E~<}{F^f#R*ZZjPidkSzWD_Tjx2e%}e(*YabeS-RUw)tVd{G!ezNONOutPqk zW$dw+o_&7!B2Nx-|=s9{|$sCO&tFQhvsuslr9#1ib#V3?@{r&@K1Q#0|>`Z_LYfWya6oX7r$nhZf4WMFLA}l z`9(M7^h!46ONjiNYgU^hK%jM|hZ1O;tHa2?&t9pq%& z($7Jn?j{6eX-9fIPv{yN#fG*lTtU+-XvGH237w3_Q{Q}`aWY!86K(n53ff|z#WJ)d zKhuf%LQL+Tiv1^~aH`tsP=sBeE<4w-BLTZk21EHnr7Fy{6B%s2m%NEXg5)64B%x~| z-lk3H%Er9B0=?pu=H6E7z|cFfKyGeh9YL4|lZJD`(;W>x|qdFqfbmx!0@ph*kv{v}^QE1AODv6g|0N zYWQo8&4)p0`3mfrFF9vu>1KIV^Gnazn04)eK1*`SJ;8l!C{7=(vN;t961=xN+yl?f zc)H^mg;@?a^LF4dI3MDK^Fe?=V^-k`VNrtT*ieV$ELV9s%T;dBGfT}}J66aV#Gkv| zg@%TYS(7$*xsQv?LSh(bHC$o5e9>k;k}!KLURg_sE)cR`?cZ(0rMJ@@0(J(i7m?S1h&UpGSCx7ni}Eesx>6%5eR|x~WM}y*FWqxcXvgm!ff0f|xbNZ1EwURq@ zc9qagh-Sm5o~vR>NHALSqYrU_6EuKyi1W&ld2wE-w;icARdCjEcPXWuOEJ8;<{Wk3AbdpLr6)EB zK_S8HEi%WE!Xw$!)PK|;S(%h+;Tr1sn?!=oDPpUPL^!J72=ito&De;+E}-)^3LSlZ zFlbK3VLA{Nlsc3iG?4|^j5gvdPHb*w4YQRNQ~)K58J`RM?5))T=aMm5>L6cD=7qKy zYN@S>SLZUVrd~!pHwmLm^HE`rLessp+(hPovALtDz443%}%tkaCP#<1DL&}H!lSYl3 zaa7EtOEwED$?l>pLSWD~;GSa#*?IMNAt6oD;&MYA^LlXJwC5J#kTx0!_ffo=-ra&) zL+LULMEW8Wbi#I7oAfgvHu8K(kC_&MWjnk?^!P zyl7u-QkZoH;7N2O6)Yr$UZO&OZ%d0(tk36eS$l315YGFMo_QJOu{ZY{N3v^47tW9C zV>U8>PTw@@x*bCj=%(#LXKzS7>*4IZl4#arz%S90+l4p0uK|2tX%&0#>~t!tB-hH8uJp-NV{)$>h| zGUQd(X|FK}A7w2r7H08?27A6CRA`@oLWC|08ct8VA$$^g16wjU+2&8YK)wvGliuOf zQfI6z5k|e6iOedcdrP1Ptn}Lw;Q=hj)4PR4HypT5oo4eot-;!+REScAf_-1R<7O<} zMN^;2R7oy2_ssdy{jat4T4sh#y+bFyDZ~%>9%$)OXMGs%w)ElzX*G&^6!)>Y+j|wB z&t9ZHr=TAN-W~e@=qxQTK7`)V17b$HEv=L51?({68dFMsYh`EYnzR2%5CJJa;JrkAv>@7^KHUxRd$us%X_ibT%$fAAS4vEaA7_@PJFD3QLz8*?y zk9Eh}f+yjp-lO~W3!{9(Q8`75T(RndfDiS1`kBaNkaF)}Iv_AtKCh;T#-SMvQRXgFb(N>tg$;JnY$y;{ zVBRlD1KugR>^)&K$)TPVLT36zaN^r8Yz0mnrHr@OxikALEL|j}vQ5_Si_*nNL16uk zl`cUFir?>(5|)AyL7JfjFS7Lh@Mje&H z3mtK){_dP}1?816@ta`6zEtd(fXxWL0Z*u)?+&6v$LNmtQOlct`@Yb*PbNE_f)>*( zzIa{LeA&l2z6mcIG-q({O7b<4oO%VeQF5t=0+|>~dma#?v@ZZ99K}D;$p?gZKgiXY zX~-T-(Rm@HAh#ArD-Q@`LJ~55lSp1-x(hcg<5$W3foLK(^V407q7;JEYTC&v3?d`x zJS)^vJUwa^%K3A(biqL(qusgMm(1HdD~;0mqaMWrj))S$s%`kOja_9Tb#KuN2ZjEj z`)oc?*`%(ZBo2!E7#tP2%7LC}(W7l9^7KqNfxYUTG>0x@}7E<lK!lu926L1ZD_@qsXm_3!Ej!miG(q*RzOE=-jy zjlkuMB$h)u1V=&xjGhoFGDWY$w^C5y;D^FX@bV5jEJTI%tnyY5ko=3vlat4}alR7I z_mDiz{4tns(L*pezUy_m?J%~~H|Xe(ge1QonL`3s?b~q!IIPMul_oO2H{JJ`<=ApxKw}a>7KA`1CAh=%i>=DF?5Hvmtm)PfY+EJlnXdlTFS~X2tX5wQVLeO|M4Irm`aY*8ON}} zR?-c}pdAY6rDITT*J=1?LX`JvWk7JvumNRXq~ksl`gl)Lz;hL_jh1{Se8D`C$1&V| zT67#dvC|XBg>Mjp+wr;Z9Z92es$i7m(p6PLV&7zg=6iK%E*A!G9~txdunSy@+MiP$ zF>>Wn9CsR9yG_!A^AO-Hd?V`nF5o;=%ouRJO6cFq1t9r&H3p6ryT=1T8Y<1io7bYb z7@T>_b~m*x-g^widUnI^rDctb9YE)N0qwNe%AbHQ$nQ$&0`6%k=o>d3t`*`{@&P8k zy^$t-i3zgO*4TF;mghwq?+QMxG{p&hS_Rp$iiub&j^Lt}2eWiC5+yGaug|5nuLOVcEIs=bmMn#E{Hk0f~SZ`4I4~9 z{u=W?fnNAph>5x7xPULl)Ks~r=+wW0%`;78R4#k6yxl`O@`W!_zbhpOjhq(xbe;$O z>W39irdsUY<~$SmZ8}JJLgKmiTuUUHs1>2?!kBQX|Fd~E9c*$gTEDC3F(er z98}c(eJ)%gCNgp(zQN_fcAe1;RQ;WhFA32$3ds1rRQ)yHgB^CF9sR;tU>dGMvCNPBw^)teB1cS5eu;kt861yy{Rp8D=f<}UzW*n2WAn0Ob2B8?{UU{RGH?%%j%2M{=TaEAUa zOP5~ile-dsmsv6#tmIE!mM;GbzP_hA6~kZB?rrS#kd><00bfsbzxQ2~^^>qUB-lxH_;4Uh zv%4S%Q)D=tS!c^kWY}Bu=ubjlk0@l%qDf5GumY<28E34yH121_AcoWJKMO&A3DKbm z3E3Tp`?$JQ##*&mZ}3h?peKG7MwraagE@N@-q^BgG*Hvu=8C35L2tD|^CP&%S?!*( zSAsbO8GI?=%&&rDTmDrO848o&oDkvBG}$1cqebVi*7nd3&Iv*O@5Za~!lo)spW&D5 zki>C1NHE{FoL)sW|F3L5?3-ku>+fujYy{0kv_my?(=|G$S_lmr0HJMYh<6-u7%xRg zM=pChdpH!E!jBSL1Vg*i%4)2)mubK+LRbXrIo=dDk@U-OTIo%sItvmI#0gwnl@`BV zCQe#GbAAy5-KGI`AG7MyPf+tOLQmZ_hpm+}>~j`_8x~Egei6Do(}5Xz;4=g?eT`z~ zNu|VwkEg)NN3Pw2lo{b~=zs{jQL3qjB{kF&3k=S_pQ|v}tllh^zZ6!BPo1&+)$c&B zb5Z&c0Tu;lWTexleigdr{#x3*bZ+T;rMLI=+_UgN2nf`ma=Z* zqPmu0?_BSj@u}Rv(UmwboJ-(Zb0|q~4?kUsbeR)5@|(Uku;g7(fI)X{Hha;YbufKz z>73GcOKzf04sx!A$39o3%njgF>qG6A%r%@Jb`{n;SH_;S5>9xVNPPrp4&4}_HV zuY=WnuEa!!Adu1U5Ty;$AZeDg7H8Z2wEYE~wN^kc$bB609G!Uqd+kxW^#Ysz1|#YW@_4`@Q-fMWg9VR`kh#6cy0Ze+nl5PaUs=V4HZ70)i=es7~ya zx_2iyz;Tsv$T9tnacJ~Sy5y=59Qcl05O|K3 zUxmk`6|G}*1nPQC=m@Vw&uai`=mPdAp_SJVg1u7OeS?U1X>pUB>uGS+Xy|=_aoeiP zb=&}or>m|DJ$&-)A4#Q>3v_>yrn>}7*O*REUKdPmwyK0WzT|ndXruZYpjt?CZov6A zoG!m1^!4|Y2kwQDIlDJ*$EzmZ^DaGgLkLM)_t>!boYM}eaX~t`*R+@NYlYHGL~J@d zj_cKtM%UqJrJ+;mgwERU?CLtKl;3T1dmUskE z^6eYVjbc-Bad2pod^d_NxCukWM8CZWPs}v>5Y@>DYrrk2CT2U|7P@+z0n^5m=i_`! zCY+)NZVN-SGoVb<4O+ut>Usxz z#J1QaOSjI9%i_sd-OK?gM$*mH@Non%4>c0wb*qf9D_rcD$j6&i-3y!=7vZMsODq)4zp;Hiok+SHN`Cut0<1 zY`wb9yfVq|YS?8sTU0N+6!mI`Af;zlsnjbZI}c@t19)UKLdLs~sJ18Jb60Ru!{ff2 z9oICD{V<~!Jjj7?_dVIU? z5d7R@WOLHRV$8qA7mbc5jE>yVA%GFLpdbeYI@ zQ-hV_HJwMHub^sjqj*`DGzeXZ{|G2W<$kK!ETyN!^4Ou`-+t+1@%2{mcTjl8N!FYJ z@Dp?%5hJ{RG-!SaP{0WQ$I&t(jxv=3JWc@@11#9v;+2V>$qRRc?_R;wOp*<%djm)E z^x2ZDkJDirzYev`jkVa}so!Oq%8Q)?XQH68v49KbIIbt#7yErq*Ye``$^Fo|U+R?d zX;PZqpEbcWnq*6UMm;|-XV1;-Iqu%hX8KjPXl5F7x%7*tudBpaey?Jig>~?2cq1tj z>03|3)nXXQqiJdkcQ#5FwJ80HE?0{|eX;=F*9gAF-&WmG{{;iFZv|W$J(J((=C4?H z$h|Q1P@&x~dlT_xP(vF{2YOm9G7Y8?#HaY459u^Pe9q&zqekLc_|)L44WJhVv5#Me zW;ebZ37BTkCdSfOQS9&4A=%qKJZ_|#`$}u*r0qbLi6Y+JqdP^hD;%aLMKK7ET2UN9 z+-N@+aS%+(d>3)-pjV-824{6!cgiMDmu4IL97Ero^Gac{ZmK!};E z%R_w6DCJ0!gk$Rr8x7ZpU4sr)x#7Jw4@N-8t-Gl_>+nIiSLsZR7$lrVatAHch=H&# zN;P6k-^*qeQRVgp%8@BT*1E@+|~zpNDLWar?9i+}p&xy#s$IsHax^J?f-Q z4qp}?v3tu0VPgLQR^dIQ)5=$vU(n@BIJ(&P&^E5(Wq1$OZepSvE(`rG-%9KK3?1es zwsq}|_~Y+5L-Za=7r2Qrstab0db)`{-FsV`P;n>74Rf@cwsRNzdLX>|`wlou^d`~^ zrn0-ZIVeN@h6E=m9OrQ+@>Qh#WSN3i)>O4gK(|AsxqdmkV zH!PmtFS6~a7X;8ljN~(F=?M?9UF2(5H-shxyml3WQk87s<|lBkT{Y`q+u}?(4L34?-d+z#Ft&(&ZpGwA}s45Soy#*)>Fp-`=&>5a$JTzmerx=#o z#+Cp}Qb5!bm!yZ^D4U1h>t*xtd#!8%ey^4-#P6SF&*S$>*$ex-$+re?Kw)0T-!=SQ z#owR!yJAm99P}^w#?zg$9!TFV>xti6Wxeowv#d9M>&p7*EF2=kc3;r@t888d9(UyC zZp+QxlAF6JH&@4+!;WYH@xPSk9p!mjdEQcNUu!XhEVX907H{w**g7~6S@?Tq zv=JYW(bj1};%|ifNYjJGUF0KrJy;yk5ohm9J)J9k<$d^qTA4@}IGf9%tiIefOvS&5 z^Z=ww>9lrOg41bHJ8^7B_=7Gf>QJubgIa5pT8XF?uGAVz+k~K&j;4i(iGJr%Ygvo7 zbf^VicZe8;+bQK?q96S+M4Z!60@}6~Xs~EIS38NHunbd?MNZ-;cF}oy@k3m$iVhXW z`qiM8qEh89d81Z;x-(SlhL`kChl)=RS`UnKE$DihNT(}Kx?dFI-tu6`K93LKKQ7cwzz-dY=EH zH;ZA*Yy2Iy#=r2e4hs_#iS{Y1C9LI+N32ERVz^Ia;;#m+Q4^OFiJKoL-eo7gyIK>+ zmAXcg#9s@EaZcOT_}J^Ow5E@EoKHMwEsGNo4$HQt^%LJ9u$ZsLi){d>ngnrtpY+cI zViClPG$##By3VspS@LpHo_M7oCyaL{<3Os=2y5T(i+g@wXre@I{3Fuik zJ(nPcT-bK_eEyisbV2Z9gb<7{W_jJ4 z49*N#a}IKxR0BnVI;eqD&mYC?EEhbHy7eyZJSHm zBx0W%Y)wcM@zTyTde$iFCnlbQO4FF}m59W1>`LaH_YnbX_-cy$Th9V(65{G;BtdB; z=|ITMJa{ASUV?2|+XJ03RB70E&W(o35L|2Fy~1U0MQs(lC=jOvnw=yjky^SV39T2? zkCU*y#?haW#F(HKmna#pRCBA_BLcO{@Fvbm;mKm>&>@nM2}RtTHvEM_msPL)U{{Zv zpU)Ls*m8m1hg6=UbCShg7)xog*dM;5a*t0A5c`Mzt8>C8xpNRIj|q7|gQ#{&5tEXh zbFw$^TXqP`;JEFM8a2LUXf{guu)_mz{+^6Uc+K3&*H6*{629KuoaifY1bMfFwj;LF zeJNs~%XW6x6`7MMVz=D!wtM&p=48waKEn|W+0N?i}7?ii)+UdZ85`z^Wt5c^$F$9NOkjo6Mef&AH4d}4Dl ztZqV=4HWxy%Vu|zObrj-t;@Sf%#frLBN&8z2<*Y010nEHa#%#1+xW^vxipzx94N+g zd#y4NJdBOgwSy9oqTrdBZsOhlz&rEuDh!0ZTC1q_RWJzxuF#ZJ$j5HFDpiaMK9a}b zgIi8axcX`pRlW*pJYWw!ktzoH?S|39?)Z;_+c@7u;-Xn|v_2JbAko-CVh;qbCJ%zF z#nDxGbdGYoE(>G^o}%M*+_`$)!7C z72 z-=NFV#LiKBAnkd7OfuUp>oAvawFIO&zgJef!?_!*!ov06O;4qX1MmiED--NSe18_* zO~d6Fn?34lcdWlST*j0IoMxNEp(KiynP7cY(i)TaR&F9@hcl7=Pu1liB_j1?k?p3c zG6WaRdBb7$63~GV1t+~Ok2zDApbfN3IWQL!5MG&JZv{iu%jQ)_Dic|70#QtR)os8$ zk9^ z<#f{!vGusVe@Qkb15Hi5>1^Wds-`ABZP7$}izY;+iR8zcaJDdzwctNsr_zAJit;&1 z0~?zfSSxeFIR+mz0Ih*fLFb!!r2#D+mo5h8Ml|!YJVhZgNuD3MYRc6XRaMTaDHp2l zfw8Vfv@(0eI+b&N;;o=Hvj!+x7DL@zZegGEN!7r*rMS*?j zxKvManMd~R&PANO*VVv?a(|4&B5w0as9WWp^)+dq?^|lRcqwb{;&xqs__+8_`+Y}jLgyOw~`u%iT+VFh%)gR zpK=pxi{uhlvrSAN_uq7!tIZ8^{?; zyOqo>c`u`f)afKllN+tswSXJFscyLVL||`TE$Q)2Vk<;%NGl)CCnJmnMXsNv%Z7`6 z-O`!Z*2lpL8Aoly#Sm?;`Z&fRT^g+&E{1wxwynKvQSvy>JAqHz*m25CIARBVe z%z?>#c^>xox9i9-7tWh0PN)P#@V!paB|!53#LU(A!fdH9y*;wJN#i65f^v%P&wx%^ zPA_GMZxej1V}uwwe6Qr9ehs0oNo+b&_tmXn9ZD^$GeceTspa^<8Oy^(0AbY?UNv-D zc=bStQCFguw8qfz;zozTo#l1BiR-$Zsz-`ZeZIZ)TWt?~F$c4_x3I{lo6m(;hM1F0 zyy^5xBd!!h;52>$kWeUa+(*oKnmLb60-ZQg9EgsUjTE2pC}zWi$&7(|X3{oKh@FXw zrapngU@XmlLLBI`tB%Llb^=ou#OWnXd5Vea*N^`61UTkZABWEHo(V;nVwBcf$%WI{ zOtB-mPqQ=O6~Rl#nPO{x;Z+Kx2)Gyy1FAh%KD;gxV&qM0fg2>`+Z|w)oW02| zQNGHJJ6-KuMXgNCK3i4-5F^TvovaRv1H7@R$~ z)3#Y+kpB%_8Dg^U-zfWL$bR34bXb-cjQ1XA0_W+^fzz`Ej=PNWJq+zPn)L4*Ov&s% z3Yg@Wuxkao2v=&TQsYl=4};bSXF)cwJRZ#7v0~LBofZzXTG4dk7--kAfy1#tauPBl>byik60& zi07`lNTX$|#&7~MUXv}xj5v==9@uasc_R4AL#RU9w%kPdMBldUU@ z@3{WueoK2hvd-=QBkjxMnz+`#XOb{8VGWCd0vbR?6ct=5D#m~aL{V{R#T}PgYpq)M z1!a&ZXsKJ32d!G%sI``2OO3YH#^tuudcA6m^|soJOQ~8^KwOG3dA}zKXz%a$zW=-* zK4fOjoPExD&a*#qM-%jmy3QyY8t@Y*uuZbxLYZT+DJ!X9tPmC%k}ES)*>ui5!=Okg zt0{P~a}qwrr`9&$`|dkVm&OWRqJA4wtW*O<=mqT0jV;z^mmxkI#Fl3b)JJyv)v~Li zLmfqr!vdWR14N12i3fbI|+Bm?b*gRqF?(G za)UstLgC#=C5TR0vcyfbYZk2B*dCyKBgJbzj1(vk6~ zK|x<%x-=diQ=oAZgvhY=poLP{*?up`$g_Lg`D5|zlJSK5VA?xDXd5|K);8foEur{@ zuHOD0$I25&%rzzEl%>p~nh8SKSi;hMgF$YnH*f`OpyCjK|7K`~>kgJE43Fa2ul-MK zQ}pPY_nrIfoAoS5d>Q73i~kgOMxdj_A^>FEmE{=}Qb(FOQHb<)XO%-N?~dy48Tjp= z(%y+c_CHCV_pUxi&rXnj`*JencJe^3pB%t6gYKPyG_D;&k@S11rWJ+lCE^$a`O^Cr^t>INVHC8{2L;?S7P;xTx$Exs_U2o{z7nFk&*By%A-HrO>7%I;MCv(Ahx|%7p z@QSEWTK}->jg^qW9fEPbkecmbXTo<7MCOvCd;e1O=YX?$jN7{eS`BUQXq=dY2Na9% zc(0>ECx-yhrYlL*7rsWDHF2#w8)`tbW91b=s@oci8Rw zTtazwzyu7^r-jvwdgzBqLUJc;r9v61Nr7?>U;-C?t%k2v0BcfehsrQmtG;2)W%QwZ z!oYtpiQ*??di&DU$->}lNcY&5cmFK?OIh0p2s{$FwldTf@493mtFw?}XVcrR@{os6 zI=zcHQ%K*`l#WmO&;#k|wSe#LtDDkWGEx)ib7a6H_oYqgV1{|#-CV1d2R{U!=01z! zrw9|XZ(%v6;G?Gi!%Q&nC);vvvU-d(q)Uz3EXYEw8qn=l&6+Vq3Rpiu!>R%LgZQww z9uL{X0n%>Uh~=O@p@7;~GE5O}*a7g>>ny0%!Hv+Y z(hpflEvE{>9y<{MO{ja<0bcb}LA&*!byIOxw4;Ml0mf(2Z!FP=qF)EkWICn3E)3x3 z(7M-!F3{#X{yNTdXh!1_I1`LA?u0wWz!c%S*7z{_z2^f8nkJZdJ)NHh`mq%SydiW| zeAqy#ZvYp&P4XMy++LyLH-MWor!#M$sjCz;UFa*8H+br{Er1R8bWqciXv1_Aub@lQ zg^9kH`6i+~)4+=}DCte%sLz2K#gTk@A}G9Y0D)-ooB=LgIi<}IT5A5V^&YyJgENIu z4H>$nsCMBDVIr@i%QJ)xinfnv`dgT|(e(LSLfg>fG=cMR(*MF2FEy14BThf6e+xt2 zNzG>pz2NL1eWnnksCrH_W(w=Ue{Glv1noGz@-`R&(0zUz2gGtJdK+V0PDkDrR{3AG zBE}4sc(yf%$s)nR$)faGLX_7RM!xtRSr6qs{>Z1adKPBKK*wi+0okkM9V1Y^F&e~t z1b}zs=u$El-WdL#*0yB6kwY#e0}_s0Atl{#!T=|SHaNtYptkuV$t4Sn3YN?DtSeb) zRKE253V`lOhZ;?r94$_LeE_2#R1nnt2^|vP|3~pOlIF}7dPSUf!h=6&GKK+?5rYh3 z6sN+9!yZCvW;#0?vLpTkRm~9$US6oh$oMe^UOCGY|Bi5!=hNx&T;V-+o;BwON#~oK zM+NhQV4w0Nt@@V1z9K?yhdF}lsd++5r+o<2v!J9W+v)>2^$hNoI4jA%Q-7-j-bqbyIJ zB(HshV}H##v)Wm)?N1cVG;p>dl(h^y$Bn*QCbac`kG+TD5obGq_b_g@d68`y_Oz1H zvcO7ON?OvfXT9lJVVZbLK6ux-OSYq`rtUtUqm%9j7&z-sV~Th`mJgHj zmb?aeVjV+gl|!K6$a8`UR|vhvkABe#3aQIj%db^DvHp?7@$87@3p*oNpEuJtfS;EI zh~DCw1?pY2s&k=@tj5Pn@Ed2~Bi8(@` zKjdr=Mmm|4uAKd7TaG}GRd-z}3=5uu_cIM#!*`906QdHAXAt*p8cjP_V&fR;{z{>T z+8_DAziGg9=Hgf@qj9-7>vq%PTpVj5FJ`FWA~F`U@i%lgmF1!WetO|5VGw+IrL7X6 zUNo4>RtwGekLkPB!X&k?PO6a%+|&6KlPBEl_5mKd8@MMnBi1dVH68-jcj1^fwa-8t zq%$b-va*09Wiut`1C=hP8Tt6in<+nEcqvbv7>nuG%3OWyE3 z@*jiLb^#=C%_}75=X-Pvsg;)gDwV9Pa4q&npR;d;oS9rP6UeVJnmztVbOxm`aF6zo zY8_@`Beh>AbP0nrzc$0b)n845J6)8)iLlB59ex$Vbg)%s(&BXxEJxAPbvTYaOx@Q5 zN_VTlLJk3Vibu&wsG**X@8KzncZ~`We0LaIAB=IpVXl6-PO1yRI~c=m5EewPv?z1* z6)IyTD8+s3^nQ9BB!>&C)C26-r6KbhG;pKPy6p}K`&{FEco(ncTV93oCdjX+OMwHs zn=cqR-&9(+QHbzbeTM}SGg_4RT}8(?3jI1k{id$S;#=}iPJ#F^DlygwQ@EqDJXm2IN6xPAnEdhKsYDKyUGfTD;>}4@hq_S z3^Fg@L8V)SR*L0|>FoPLa2JRnA4)HE$PvE=9oyHK#w>Rq!a;Z)j-cfysrhChA`r%; zaww>zR*Wf&f#%5v@bWUHZx&MAzQ=7gZQl%xu?JOd#@_i4*)|Jd{h(6*P;cOB7rz+u z^60;hd3grLeBCwX1uu_zd0RH-;2yjFw;^YJ^7kQUt$TUMS=-r=Tl0(P+!i6!3xM_^ z;8HDc_^b=`bPL84{_=R_x1Hn3`kjp@mi5iUua4aLmlh9i1#CW$^5j2^E zem%Sz*%vq7&OYc!)kir?QOi>?kW?DZ#@vW(LgTD6I{c34hEsn z9C}dTdLJf36Qf=$50+=iYvqsd29o5hK*98sv{jg*zJRxtNbOE#TZI?}_Qs8^!t1`! zajrMY9oQOSC(QjyQ^qzF^1p>>JZ9(eS`){Pt^0|z`2(SE#8IX)nWMksBew%a#@#PR z#!Ie@ZD2pl-3I~ifpCXEZ2E1x@HX!ObCqWfKvI3(^x94#mk&L{HloGd0r0$>-LD23 z_E)umtM;YG9|BRELdIgDQ;Rg6WCfV{^E1GeuhT|0!t`oAohf#3Q0^Cl^a-HwT|$TM zf7+0HT&msvdD{F&OyEyosn(fD+Yh`4_FUk4UN#Pbj~fT__vh~>d6$r*@Ewnsa9Ri| z^W<4Z?7syw$ZxOEV?b~H&NeDzn0~XY!YdIo%U&kw=gX?^T`0lb*=V2u6?1nkteK%% zWi$>s$*CPs-knjzpPi$Ey~5CDJ(11onx=7bGKdfE&St9FE6fkNQ>T-jhq&IsTVQ!M z&?W8;@Wy?@Qt#vkko6|Yl{sO$cak5Fszm7HzZ4VU=V((#(NqI>`z8%95fXZi#Ur-O z?c)t05WS)#p8r!yr&l$(!k5^kTC z2y-<{pBMKwW9cu8He#=wuArqKf&0=acl8kv^UJ~*wzX_4{!<-yMYtQp?oNO6EtKnd zU&ib_0xEu4Dz4DkSvHs*dCNwWbjRHb_maW{5X+ylR(klX7BHp|jqUDvBe-HShG zIhKBR)cq^<*Iw-Y^yXH@U5~22LI;*!V7*$_AC^U|+J5Z!^jp+@zYwNgiW%5!;QqKq z6ZT^r@1=aCdZ`0ckT$9qYv6PTI=o*v(f3wF`aqG4}0UvVJV2_^gB;gAc-1$1{d{RW1!bAWRA# z^r8`)i+!@j(MT1f#Rr5p)xJ)eV~K|Jp9s;4lXjZ*383I_wC)ojuosXiTbiqH_^eg2 z%xOg99~2A1cIATfs+g{w@-nVSynKCmEXUb%DswmD^RZIOXW^G%Dv|(r#DvFPwTd(aIzV#Wb0Mi zIb;7ujFHklMJMtTmC`)+vN0JB#!iQG$tQLWzrO)uFN8@O9P8QEZLoXWv6lCadd+eb()g*f9cDlHXay%r$NUbvY3 zk|$M{3a@(PTUz3S9M!c*381vkgn7+&S9CHeQO{9>eS#a1ymolyNtZqYKJ`A@wNDrT zqouH7WjY5Q0aX;uZPfCR5IQV`)h4{|nCupqY^bcW6z}M=*=Pa6NjI;uBOM$sG?Q@}r?-(F8?)Wgf5|zezI*f`AelE0VmguO5X*=CQJq|(Bw$=2@=R)x7 zN9D>ozTy=S?Sf8?<);mjz$*7C@5kms1!NNVy~67|SHJulJ7oJ3DS(qp-B}74+tujg zkFGQh+~9UBjmg#x_MeAR*#)Rz&i+EsK$a?h0kz!#dyTSIRp$okB~LDaDBv^eUTZi^ z$(Wxd{YSM-VQ(XvNRWj%Bf3`_MN{+{(%PybDU_5YMG#PS>ohuthOz@{a}t&L^Zu)`Fh^sH(AYoz*4X>5#+LoBjjed8vBl2DbWv#; ztiiaj5DmJ&4@>^vjBZ7EOsL(YbF}b?5Yb|^b5AgZ0E}cfxIU4r_lpM8=SM)saP;^H z9fF>Zx$upkV--D)0y!kA`oAh)%^=P-YAKxRt@M`I(0%&RCsra}MI#jMvPN?BtEpL4rs=eH+*x8`$ zuY6eE+HvB0xc1oTdfpPi-XRY#i7V^nNOnl5Ey%|(ipG3a^88j9+HpcHU#DO?q~foj zh5gG`)c~!%(ymrngY>e~KCqgJk|ahWK@30Y5%D&gvSh<@-t2<{}AWTWNK~(%Wkr)uSkb* z#l0L~fQcFA9H5bAp{VQN3TA>ZVji?`eFvY%-2xpy_z14E@odKR9bMSq{kXn`=Q3R1 zrdB6_BC1GtLTID-wU(xy5ZdbE;qT6LKY!Dn55`8aAKvno{I4B!jVR6Tu z7w(Q&+;E5Eeeixdc|vI4-1QDtd#-oz?KXIS;YqBmIO=dx809(8c#HB*V8Bw3}u+lHVrJQ$m0BUMA7$95#3_Wt^c&SZ4VFTEU?q0PYk7EuH74-~zjz?{x=p0zphNrQdF9PoEqQ|1jJym>>GQO3!@ zUAxCno_A~5Z-J3)r-bR6Vbx%CXmwG;sx84f^{{GMcv|S78FmjTVBTc)V#@2o?oruk zp}FVaD~|ZUz2J7ek}jSWe&z$|z(0g{;7ujuJHZ?>>^8azPXrbT*iMGdci0`r^PSQl zSwZH1;e7P^UKpfU+CXEz2QZjRE53(j>;~frECu%(XqjqeGwaEvi4K1ejJ|n`PJSSh zmxWjPKWOP?eBOW3&db6$mTJ8Wj=>J}0%#61c3fMNq!l+A>}dv5=FhNqU{Ah+Z5K|JZ9K5;=3?7)lk~w9WTaG@bov~8k%`sekpn?B2W5`ObB^SV*HYTc69GoXA zF4p84!`MBLfj8=vz>55l>P{mo1w#bMUJw~>W4|jp1C_YxkRsh|q=Vu0q%WB(g|P8m zF%id{6a4Ni1NY-bFqyV+O3rtPlG~ULhjtaM9fmsG+0e#ZC~*lnvx?_J9;`zCTd}DWTMlX*gpn~sw7qCn~_?=LWB-1(cpJb;Vq$4>jIq``X$^C53Di_ zY!6s7cb!V&++LGU?qaUai0RYJS+DK(i7M;EmT(HL%R&tH*{f*ApTbblhYe#f!e;yl6^OA^{U?TTo}#PKWr3zw z0|aK%+G@asV^ms=*{!Er)lm8v%Rb?v2h{!^u-*5aA7RQpAp@!v$L1&cU>xEUZ2 ztp~Ba7~t#-f?af{gZG8G*-rf8+D?u$r&;wMnM?R}e3jenfuLUE5t}0>PLw%)O+0ta zM;JJL=5UVHkT@m34Gxbp8JpMPqsFO@DsX42OQGZdVa4%T7g$I+QO;fq24#yCB3++c)t8$qOg zAxG8uI>&hIm?h2_rt#|3mFcuCX;-27>%%S;Duy154dLl$NOSZ~jYbAl2 zRX5%}`ptFAoEogRwa0d1CekOdQPR}y zuoYMeL=)|wLy9rabnv#b{+Wr5u7{&j-Wp?*t=a>cfIP5 zA$7cf?WIFZyi8guiAA10+^}Wr&(q=NMM169Vkg8kN>hukf->E$79*f<^PL)$nSqOG?b+^f9AjqaLY-;=9Vhw5?aeP`Rl9xUI?q=5{ji#Z$Gg|>k3D) zaW7|4ZQzv1v>lmR(K z(_egDv^g?vBKH9COTLTA93VbZVO1P!A-)B1UHg{eD84PpEyX-Bi$Uc{8k2Xh_$klF znvR8t&D`Mg_+pqi0QgT(xY#%BRcLBIF;*7#GT28-#VUB0gK}|Fpxyr5-?+|TA3nge zFkF1wjh{!iBE{HVcY)D*Ym{;nu0FUrG@M7@WnCJx0)0Q}nEaF01Vu5HH?+$R_p1Y- z57W_*_F}KV9&$UAfze4LUt=>ex}5!vNu{0b#UMqPnvS#=V*@vqC8n#GzR$>$tlrVg zw!=OqurNw&0hPm+QDT=KYV5wKKFYIjbCU*LN@N=D_^m=0PC2@8$~wT+g;-}7v?a76 zN{nss#98zzijH#@1!{;2zMzUI@m)k79oa#ApRc9c9mFN#P}X$DO`6_O9Pe{PW^7Em zeGO0mMb|@gsiPRyYn<7eNnll+q7!f}?2>h<1tCdV#ZZGiT-EqSZdVZET<_kgSntCO z_K3yQIa(a;yAbEtkMIR{+IfKZB$h|*Kl}Qb^S5G0&E+X++roCOTw&0u68iTH#rslC?e|{j1iN#Jo zP5H6nzhTlpxvSWXSI=S9AxQWo+SyGE3!KA7S-@*J;~eIhC3zNJPQlB|-NYW*Ju&nj z12VZs?8-9Y{xK*P&j3z->UielzW@YMGh)~0!`QSl_oFI|dtB6?wGlT-b`S959`9ds zIGp8GY2+s?M?o0CYx@9S?#URn{x%iY?c+ynElf&PGA6x8VIigiAOf{3{_7Il@&osBQ zCb%ZCGJRfl{j>J24m>5{6|s+cCTqjbSJBfn@D=f&O0epJdW(_#e$w|AAM~xb7S?%E z#t{1OoB*2DZeOLt6XG2XVLpK}hA^#l1jXv8Q>)Ih09MwVD)Dw(fcgZ)Wgba0`-oPB z>O9Se7vJN5H$9CPTPgfh^#*QdbBFbMtdc{?dQv)8_-)EEy zg5U^(S!dY?G21_TS_nN(5`V=hd2xW4$LmdFl12E0$TTfY5qt1JD#}vD-?8=z4dP8j z@W)W{0Qa?kPn)A>hzNuu2Ci_nPVEKypB8EFUT-d?U;V@^13x|qJnx(JDfD7kfYXOh) zK)=U!WlvSgJ2-&ZlLabmEZ;>pXRa5BdQ(odGbaM|I&0`guT2$4_{YR?4vz|87(z_q zri&UIV>&if9HnRx10$KiH_W$FWHC{xou@QItpRjZ>=9G+8=^1Iw=wCai??{iyFS!r z24>}nsdR=oSi!F{S!aqHSsc`LvqT%O=p@p*IpQL(kmNFD$BZwbKLe`GI`M2rvLTrWEriO*04}6@+X29axR;^qKQXH(`D1C(z zkg>Sx*6mP*hGTK*2LKTcqOOav@QY0|7K&6^3vz{8ZS~o1IRJxaDKfgLpc&LJVz|2Fsmr04^Pd6TAAHoM*6EQ|LY_ z?fW@;txVs{N#^Fxo-cC|IK_TiG+$l4N3sZ`=ys_w&I#n~~oJ9U=DH@g{2<{G$V z|8jD>vZj`p;FwzC`g3YDd%9#H-kos0do6vB3{6}Q6~RoaHOSn%vKY}e-Mt-$h|9>g zX-vMVK7Af|@Q21`mh=M%n1tQxj_YJo*Bo|0LLC?Yw}2L}5?=?^{M#y=ZDyLeS{&fR zyjpObhmDMmkR0B-Xar0TnZbgE~k&D1es0 zLopce=^JUz`{K87loPXAoCq>?!)9?o=mli%!_e_(?pPb_a5b>Qb#8l|+G{a|ZxM&_ zn@#h#i0|-V-&GZgr-GM2yVj>M-<)4D4TFF;L?eGWohC6=;Z;fAMPiJ?>nZ7r(4hA4 zR;&VeOH11(&g1W!%-h6{3O?9`ILDn7e5$GCha%(w<4k46VvYi!tLq+dJi^s%*aI5! z1FG61PVtQbBiGwtuiRkiz<8;%C()R_VlR&r^Cinrmf&ZnoqI8pgG|5eWq5>0wtZr! z;BYu&^#mxt1f#hOSxDE)i?L<8!saTPl1oJDl9!_eyYdZ#-TgtWRI>(HQ3uQdEH*F) zwi_Xq(GBho)o=me%?--n#NFii5g={~b^b`~26q=~7QQt-LJoj^z1Cot{sloi0)av; zQj?Qj+~)+t9)D74R)*^}`xPew*%K(+E9izE-O$6_Jc~*`632p=RqO{g{fJ`r1B;2G zf&0aT;M-*o*+2aqE~foZx7MY#z|wv-mFyR{NPL+o{*d^9ht6U27r@lpK;r=z!V^=g za?sK+%8FW)k?}dDsEQfT&2fH0mBwi z=dZ+0{!=Q#E!C@b0c&tjNmDb-Eh*+Ju{FK-mFUSQnYMj}qa9K6&V4Q3> zytG7N_5_v?1^#1X#*_RxObq}8oqgVHN<1#!0ksj-l0HyXaNS@# z_c42~g{q%)9iJ&BgY(%*!!L>Z_~-QWlDG=~kXKm5P+x>&D>wmtj4rakaJSgjbkKs` zuBG0W#eQvBOpj6{XN)%3&U}-j$C^O6LVU>q!02Gx6gbFWJ9``=5p=|l8ZKjDzE0^s z#4gG}+0wcyTE2eAANyq>+gF2r(W$+Q z==gQu-r_D_|ABE29hDD+FD`GH%5RF1QAL&%`P7e$-ROLE0JG{@$fD#03}`O=1OzbC;$1r}hnT5;ky&t&l5Ue3X=vc&DZNcf_HXVclIE z1|w*?ZVq^Ey)db1pr~+^{3-tG51)Tb0OOp+)1arZE7T3UKf?5ywwm+zi9M&VmS!hNhNEp@&RaNClW-bbbr zRCFIR9Zlce$5#%Z$M*pe;wk!pqlt_MpuM!F$_L1ag0>pKjZBJpC^iot^6VvtB?`=! z`Ne!CLE{4RHM~}2u5ORjqEs9!6$tygnp!a;RO_7oHTw-*e{V*)fhzynx*P6V)njWY zrVjjs0P=hywiNom?x<>io%mK$sUicHxUQ*`j8eVEUUAm{3#C33TQ}xhdjvVBHsxgQ zW8WNWCgVdK>RPfsM8C`wRF8w8u|v}hT*9NK0=vbN^-;^C_dP3W#?7Pr}T=*E1ewJQ&?8yDvV~~7W zI`A0Xn@-<7#(vIXt+Seyru?(Jyfx&VA*D_OBnMh>Me~R8|={T}`NQraM1k~r! z=27KS>_#oM{7Y=9z*k%Gm)I^`4>b*6SO4;#!iUZqO(SLBsRh0h^0C!>;4jDQ<0+7? z{Uru8&QCs+7yGq-Q3_>>$+O|bH_A5~INh_qW!OL?8?eh|THGLZahsm#n?H|MG>AcT zx&e*kQ)L52kWbB@ImSKYnYbPh;kRcFz@V@KBx>D@f@h)bcsNgx?j4cU+&+gy%TV zgGk0DBF+Ugs$s^R!gv(VuA7?xT;HE{YX3|+&GO4s#V+L}*-)GRE$U#yqeN-!qNQ2v z5>Fd!VzXeK`5Ex5&QLS*bJoR-nEH;^sRJ^}Y{QN;nre^_xYZUxisZ|-be0zI<}G`r zQboXd(@0)|*S#xLqmZH%0rk{MDMf{PvMPEnvJ5Zbs}y&dI@m|lsheqOs!|FA>AhMh zjbkNlDW$F8AgoZK+F+_zNn4toXYy(Wao}g9n)%R0x$d;nO^Rq%UbC|4)p@31gjZQ~ z*-h#R`M9?rwFLs)U68_CHLJ9=E=dIb?;~>>IKC-~EqGJOy0g|5gWi)ip9su^p%b_ zuD-QkSatJwX>qaa-TkDmd7G)mPa3V@KQ;|)COzc&&rG^N=~E`ws%{|-0+5VrDS0au zBREP8m3{(UAJR&i#53fjwKPhJHFP-~)AYT`J3@M0*)cy|Bc4y!N~!q~`TaqAO+x?? z_`87`Tck7;r|I2DiIE5$ z+DnnmQk`qGAfq6`z(wA-OlI}awD!^#gx0aPmm=UsRU0K80^90hlyu6!6$}=iT6Zxs zncJ$uD=^AxM*BNR-CCTEgL4dh%`t8u7tg8E#>|Ho$PEVDhksIi2dSqx0~CSnijBH< zl(zb8HhO3{nMDyv&*0pS(Jvj*Ar-ZZmLeimi4N!6AeQtPfj>0urs>qpK^{gfe!;3} zK9#0MODVoAIqh%B$D*Z95H#P7mPYY5O6(-{1xS=TNpHcJxVn?{LB~+pYz|P&;X+x5 z&MD0v#r;pH73s3?e*~a1HS54!mTRzCZPhCJyfd~?s_B=`(heQ~eQ}KRW^h@BSi=Ke zcF%b7-s)>z@CjW02ov^zpDoQ)-ix=(k zlN&N~rXoVud^+40YkDeO?u%_QjI8XUGllCU4|hoYI;Tp{9b~{jDMx&6fo4oSw5GbLHO`Tn0}Km#a0{ zEK5yAW2HTc0mlM-`AK+Z&~U5ffPZQL{ge*G^E}eWyV5gXN4f|B&^7Y(+2165^8 z-4*liQOG1oi>paDNov6l3NNfmLg+v5-@ctE7nV#%<8pqo)Md3(iavD}woHHG2;js2YdYmi0 zmn*$>bG!(`3r9kOQp2rDRcTiar^(Z#E^fnBTEz$|#BJ<|BpfjQdNGT>%IxS&A*dHHrCDK3(cLq74)v+#x;S_Q6|C{iTu^ zGg!g~?%qFG+P#woZVz;>?)}H1XdoqV3i)6xV7BF8H%K2V4|a7}P;vKuc3kcDXUP8% z>E4t&dQ3Ho4mqOjvko->O(`}z3PKpJ@@O*r^B07r!G&p(MgSYEdA@;@PQ3&q^I7_} zaBw@9!f%r;A1+$q^mDz@4Jj+|?8cP$8`{D~32*ak2HS?t40*BtXmo36hZJUZg_epw zcc|4NuTDMgU~;QeZX}o@rA>>z2Hf`%23zhzDBzXfP*BqJ^@rkZhtt`%+fDTMART;L3I%9B^R|>0-TW++ zBsn)9SBAY%S4l#qr&y6ONLRYji*)M1XiA(VE#q_HaR%jg(A8N|SpU&REmT9eB1q>) z3Y;D4E9+Hou?5aqWI!2KDy+5Me*|mh(71IRD03VV(KtQ z>eKNN3d@cFXV47Ybe#3s4EIde&=~_6uX$}29hrj@ zIhr)@NU<%-00b^%aD0{vzF$q!d$uyzWFH#yj?|~$W2OTI;enRxdN>=#_r=^ZJGKT5WDq~MNOIDfz#d9N%<>$%NfTajq? zYHIw&n-B2jPfD6AMYv_5AERmJT*;6!9{i_Cu70$3^<&C^m4*he7na}hs{c_hd!s&ZG7h_#j0&6C=PjQfEJw8m91hj{>{Z^Ie_@MUKpj@|ooah^07RE&1Mv>unT`BFcR za$_FA`GpKk&OvIJj};w6Aq%8dA-omI02uFn)d(=w#RFh;L4&^Z+5)L-B62texDFF3 z6272j>v2ERRUN_j5j;8R1Qr{NmjVg^wo(XY>?TbmeN#o99k5}q8 zjyp?>7fSsmZY_w;j~Z9AYRR1z0B9v+BsU+}Ku5@v5v-ew6d>Q(lS;Tky4;d-`V`SSU~g!rJ+ZB(#WYB4&tVnTdo={CmR_v~V0br8(2v}iQUdn5w$O~#ph0fv;tRe5EQj0#!qX83R0NI4wMYFSMM%Ac_Ii<0ELqP7@l%NgI8vPySod`!Xh_u5!4I=g~EH9Yg8&$h+*m^!%CMm5tZW0}<2 zS4O|8UL46mGUYFmVmp10gG18zDz&((fmdC?eHcS;T=(I)_i)`uP}MT*cCa+Eq)tPN zRROZ5m^r+$S;nxBrQ*2na@QQ$;JW{Qf2?z{DYej~bbL;ZQ- zyjxa6;WEu}HrN)Nri0m1xT0kZozIqnQJ^{-RA)MMkfn~I#c@u*N#kTtTM~RDNsKjk zTn1@0o!oPPFnmoTbEIWsgP=%Z`}Cj#jbx6YDw)?+hP*<|tS?T0`VhivAN6A?xR3nk z)KP!eefuK;3}eP$BzFq_+BiAt`xNG(6$~ewfx-K!!%8VC`}wMH16R<~(k_l#0s&ld9cF${xyZ-}d3Dd-mrPZ|!a z3b#m%cv}??ZzjrB;jnIpRNr8mcZ(Fc(x8aZIEHNp?|rXgz!Omm+Q21%{h1qjQ0_4G zRR<&dLar3tOLlb=CbBpy4*eJQhqk}_v&oc50c6xu^**$6Z1ZyIbgtB0I*7>eXow1p z_{yUx$O!DeJ?V{7Sax4y8whh2u%8jqUL~2O0)R8u+({!-r^=z9R~EF~G4{ zpjB>1IG(yYoc^u$X#sqI1~zi5Ligoz5^mqtJX~@@>&QM&{$X^6CQK z^3>Q?ryd^YK_J!SOTD_WSUA9t*4M*z%nnqRW4&oK%T>Cg<1?Od ztHP4aoD8Tr@kZtCs5rMBSRBR0G;WR5X;^K+2|piMlKVk|-)Tw=6XNw8TyUM9S}fmr zvi6K^o%n@MCGd;22HX5Y)|)K8NduQNDJRijo0Bb@nc{@;^#(0QfOsNnq)1;o13@3Z zk2d3&9vqVW)?zWiiexQN>t2+xR_fK4870_09>lOHF5NTFapgQexYEjrKws+VoTVpY zk|nKGrRA7=jbz})Svqy7iq5T-dJbUYW=YY`aX)_F#R)8iCwSZJpU|}c=*#K-=5T%u zK#;iU@=EB;*&D{PruR>9{MOOHckxlnY5u!Xq&g$1nAftoqP_1*ow73k08(M3Rl`iM z^P;bHVRNDj&Ai))v8_K3j15TX+~YWKwFhGk#yaU$XcS(^n4*ToJ0p_0_!l+Ef-ZEb z>?og{5u3Xis&0iS&qzd0KEV)0ko&3U+|W5Lo9k$m8T8NK)XY;H#+oamy3Y-^cfuO6 z)xW(d$D1>aCFFL_<$|pd!Yh(6 zi;K+X^tJKXPEO`4yYpEQMVPASq@RIX)0GueXjMh*s=^t6BjI+-ZSJnV4>BUcD903J zS&6MDLs6oGtHjn9CGI$mGT_exSu%lbnFhWCgb5yLh+0#%N)zq6=VnwsBlF>UNH+ zR^66e1JW^l&g&p{^^0+S6u&Z+W2ys+(Q)>^I7BhTkzs?%F)c>3-yD@=paGeRRJx2F zz6##NY|H;xRWo6z@Ci2h3KdM}(&x+il3rB;*2yg0^EZNCvIWwF#7!$J>0Po6{f3H; z>&}x#u9voi-mrXGvb>}>6>JJSCm53qT%JvCXK`bmbn^ZpVS|(~s&(2NPKBet_@i2c z*27cwvyVQXf4N}|C%}CnIu*-8G2hN7p8 zjZ!Dy-dNJGCn)P*KCvbjv~n#KZj=TLs7La_lJ4-xdbm6rp5RmPyyv5O=L!GtE1kL( zLhqoF5ayRwDŽ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 m-AcJ}ZJg)ps!p+;qNBS;TZY7W#MZ&;J3k7hib* delta 80668 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 diff --git a/feeds/mediatek-sdk/mt76/src/firmware/mt7916_wa.bin b/feeds/mediatek-sdk/mt76/src/firmware/mt7916_wa.bin index b6ddf15fcd47dba89bc0dcb43eb12d84e0b7f384..4ff7c6b9dca98b90e21e9e7d76109646cc02fc58 100644 GIT binary patch delta 43196 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 delta 43196 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

Wf9*jA&Z^T;gN4N9hpa_X+c{a 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