diff --git a/config-nstorm-bananapi-bpi-r4 b/config-nstorm-bananapi-bpi-r4 index e0db2191693445..050a457779d15d 100644 --- a/config-nstorm-bananapi-bpi-r4 +++ b/config-nstorm-bananapi-bpi-r4 @@ -12,7 +12,6 @@ CONFIG_BPF_TOOLCHAIN_BUILD_LLVM=y # CONFIG_BPF_TOOLCHAIN_NONE is not set CONFIG_BUILD_PATENTED=y CONFIG_BUSYBOX_CONFIG_ASH_HELP=y -CONFIG_BUSYBOX_CONFIG_ASH_SLEEP=y CONFIG_BUSYBOX_CONFIG_BLKDISCARD=y CONFIG_BUSYBOX_CONFIG_BLKID=y CONFIG_BUSYBOX_CONFIG_BUNZIP2=y @@ -648,7 +647,6 @@ CONFIG_PACKAGE_luci-mod-network=y CONFIG_PACKAGE_luci-mod-rpc=y CONFIG_PACKAGE_luci-mod-status=y CONFIG_PACKAGE_luci-mod-system=y -CONFIG_PACKAGE_luci-proto-bonding=y CONFIG_PACKAGE_luci-proto-external=y CONFIG_PACKAGE_luci-proto-ipv6=y CONFIG_PACKAGE_luci-proto-ppp=y @@ -767,7 +765,7 @@ CONFIG_USE_LTO=y CONFIG_USE_MOLD=y CONFIG_VERSIONOPT=y CONFIG_VERSION_BUG_URL="" -CONFIG_VERSION_CODE="20241205-r42" +CONFIG_VERSION_CODE="20241220-r43" CONFIG_VERSION_CODE_FILENAMES=y CONFIG_VERSION_DIST="OpenWrt" CONFIG_VERSION_FILENAMES=y diff --git a/config/Config-build.in b/config/Config-build.in index c8739afa8770c5..ec3a8d1f8033c1 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -70,7 +70,7 @@ menu "Global build settings" config USE_APK imply PACKAGE_apk-mbedtls - bool "Use APK instead of OPKG to build distribution (EXPERIMENTAL)" + bool "Use APK instead of OPKG to build distribution" default y comment "General build options" diff --git a/feeds.conf.default b/feeds.conf.default index 090e1129908277..f2e760b0dd3c07 100644 --- a/feeds.conf.default +++ b/feeds.conf.default @@ -1,6 +1,7 @@ src-git packages https://git.openwrt.org/feed/packages.git #src-git luci https://github.com/rmandrad/luci;11be -src-git luci https://github.com/openwrt/luci +#src-git luci https://github.com/openwrt/luci +src-git luci https://git.openwrt.org/project/luci.git src-git routing https://git.openwrt.org/feed/routing.git src-git telephony https://git.openwrt.org/feed/telephony.git #src-git video https://github.com/openwrt/video.git diff --git a/include/feeds.mk b/include/feeds.mk index 87b1562c3edbf7..c3a47cf5f92252 100644 --- a/include/feeds.mk +++ b/include/feeds.mk @@ -37,7 +37,7 @@ define FeedSourcesAppendOPKG echo 'src/gz %d_core %U/targets/%S/packages'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo 'src/gz %d_base %U/packages/%A/base'; \ - $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ + $(if $(CONFIG_BUILDBOT), \ echo 'src/gz %d_kmods %U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)';) \ $(foreach feed,$(FEEDS_AVAILABLE), \ $(if $(CONFIG_FEED_$(feed)), \ @@ -51,7 +51,7 @@ define FeedSourcesAppendAPK echo '%U/targets/%S/packages/packages.adb'; \ $(strip $(if $(CONFIG_PER_FEED_REPO), \ echo '%U/packages/%A/base/packages.adb'; \ - $(if $(filter %SNAPSHOT-y,$(VERSION_NUMBER)-$(CONFIG_BUILDBOT)), \ + $(if $(CONFIG_BUILDBOT), \ echo '%U/targets/%S/kmods/$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC)/packages.adb';) \ $(foreach feed,$(FEEDS_AVAILABLE), \ $(if $(CONFIG_FEED_$(feed)), \ diff --git a/include/image-commands.mk b/include/image-commands.mk index 2568fb3ade5f3d..2e129e0347d703 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -391,8 +391,8 @@ define Build/fit $(if $(DEVICE_DTS_OVERLAY),$(foreach dtso,$(DEVICE_DTS_OVERLAY), -O $(dtso):$(KERNEL_BUILD_DIR)/image-$(dtso).dtbo)) \ -c $(if $(DEVICE_DTS_CONFIG),$(DEVICE_DTS_CONFIG),"config-1") \ -A $(LINUX_KARCH) -v $(LINUX_VERSION), gen-cpio$(if $(TARGET_PER_DEVICE_ROOTFS),.$(ROOTFS_ID/$(DEVICE_NAME)))) - PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ - -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new + $(call locked,PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) mkimage $(if $(findstring external,$(word 3,$(1))),\ + -E -B 0x1000 $(if $(findstring static,$(word 3,$(1))),-p 0x1000)) -f $@.its $@.new) @mv $@.new $@ endef @@ -732,6 +732,10 @@ define Build/zip rm -rf $@.tmp endef +define Build/zyimage + $(STAGING_DIR_HOST)/bin/zyimage $(1) $@ +endef + define Build/zyxel-ras-image let \ newsize="$(call exp_units,$(RAS_ROOTFS_SIZE))"; \ diff --git a/include/image.mk b/include/image.mk index 70dc8e069b8eeb..fd6f76b27711c3 100644 --- a/include/image.mk +++ b/include/image.mk @@ -373,7 +373,7 @@ ifneq ($(CONFIG_USE_APK),) rm -rf $(mkfs_cur_target_dir) $(CP) $(TARGET_DIR_ORIG) $(mkfs_cur_target_dir) $(if $(mkfs_packages_remove), \ - $(apk_target) del $(mkfs_packages_remove)) + -$(apk_target) del $(mkfs_packages_remove)) $(if $(mkfs_packages_add), \ $(apk_target) add $(mkfs_packages_add)) else diff --git a/include/meson.mk b/include/meson.mk index ff452d8b01fa4c..62dc7bd5dec30b 100644 --- a/include/meson.mk +++ b/include/meson.mk @@ -55,8 +55,14 @@ else MESON_CPU:="$(CPU_TYPE)$(if $(CPU_SUBTYPE),+$(CPU_SUBTYPE))" endif +ifeq ($(MESON_USE_STAGING_PYTHON),) +PYTHON_BIN:=$(STAGING_DIR_HOST)/bin/$(PYTHON) +else +PYTHON_BIN:=$(STAGING_DIR_HOSTPKG)/bin/$(PYTHON) +endif + define Meson - $(2) $(STAGING_DIR_HOST)/bin/$(PYTHON) $(STAGING_DIR_HOST)/bin/meson.py $(1) + $(2) $(PYTHON_BIN) $(STAGING_DIR_HOST)/bin/meson.py $(1) endef define Meson/CreateNativeFile @@ -65,7 +71,7 @@ define Meson/CreateNativeFile -e "s|@CXX@|$(foreach BIN,$(HOSTCXX),'$(BIN)',)|" \ -e "s|@PKGCONFIG@|$(PKG_CONFIG)|" \ -e "s|@CMAKE@|$(STAGING_DIR_HOST)/bin/cmake|" \ - -e "s|@PYTHON@|$(STAGING_DIR_HOST)/bin/python3|" \ + -e "s|@PYTHON@|$(PYTHON_BIN)|" \ -e "s|@CFLAGS@|$(foreach FLAG,$(HOST_CFLAGS) $(HOST_CPPFLAGS),'$(FLAG)',)|" \ -e "s|@CXXFLAGS@|$(foreach FLAG,$(HOST_CXXFLAGS) $(HOST_CPPFLAGS),'$(FLAG)',)|" \ -e "s|@LDFLAGS@|$(foreach FLAG,$(HOST_LDFLAGS),'$(FLAG)',)|" \ @@ -84,7 +90,7 @@ define Meson/CreateCrossFile -e "s|@NM@|$(TARGET_NM)|" \ -e "s|@PKGCONFIG@|$(PKG_CONFIG)|" \ -e "s|@CMAKE@|$(STAGING_DIR_HOST)/bin/cmake|" \ - -e "s|@PYTHON@|$(STAGING_DIR_HOST)/bin/python3|" \ + -e "s|@PYTHON@|$(PYTHON_BIN)|" \ -e "s|@CFLAGS@|$(foreach FLAG,$(TARGET_CFLAGS) $(EXTRA_CFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS),'$(FLAG)',)|" \ -e "s|@CXXFLAGS@|$(foreach FLAG,$(TARGET_CXXFLAGS) $(EXTRA_CXXFLAGS) $(TARGET_CPPFLAGS) $(EXTRA_CPPFLAGS),'$(FLAG)',)|" \ -e "s|@LDFLAGS@|$(foreach FLAG,$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS),'$(FLAG)',)|" \ @@ -108,7 +114,7 @@ define Host/Configure/Meson endef define Host/Compile/Meson - +$(NINJA) -C $(MESON_HOST_BUILD_DIR) $(1) + +$(MESON_HOST_VARS) $(NINJA) -C $(MESON_HOST_BUILD_DIR) $(1) endef define Host/Install/Meson @@ -135,7 +141,7 @@ define Build/Configure/Meson endef define Build/Compile/Meson - +$(NINJA) -C $(MESON_BUILD_DIR) $(1) + +$(MESON_VARS) $(NINJA) -C $(MESON_BUILD_DIR) $(1) endef define Build/Install/Meson diff --git a/include/target.mk b/include/target.mk index 1b32bf905d6d3c..a4428efab710dd 100644 --- a/include/target.mk +++ b/include/target.mk @@ -90,6 +90,11 @@ else endif endif +# include ujail on systems with enough storage +ifeq ($(filter small_flash,$(FEATURES)),) + DEFAULT_PACKAGES+=procd-ujail +endif + # Add device specific packages (here below to allow device type set from subtarget) DEFAULT_PACKAGES += $(DEFAULT_PACKAGES.$(DEVICE_TYPE)) @@ -370,6 +375,7 @@ define BuildTargets/DumpCurrent echo 'Target-Description:'; \ echo "$$$$DESCRIPTION"; \ echo '@@'; \ + $(if $(DEFAULT_PROFILE),echo 'Target-Default-Profile: $(DEFAULT_PROFILE)';) \ echo 'Default-Packages: $(DEFAULT_PACKAGES) $(call extra_packages,$(DEFAULT_PACKAGES))'; \ $(DUMPINFO) $(if $(CUR_SUBTARGET),$(SUBMAKE) -r --no-print-directory -C image -s DUMP=1 SUBTARGET=$(CUR_SUBTARGET)) diff --git a/include/toplevel.mk b/include/toplevel.mk index a52c56832eca03..092dff786c9922 100644 --- a/include/toplevel.mk +++ b/include/toplevel.mk @@ -75,22 +75,7 @@ endif _ignore = $(foreach p,$(IGNORE_PACKAGES),--ignore $(p)) -# Config that will invalidate the .targetinfo as they will affect -# DEFAULT_PACKAGES. -# Keep DYNAMIC_DEF_PKG_CONF in sync with target.mk to reflect the same configs -DYNAMIC_DEF_PKG_CONF := CONFIG_USE_APK CONFIG_SELINUX CONFIG_SMALL_FLASH CONFIG_USE_SECCOMP -check-dynamic-def-pkg: FORCE - @+DEF_PKG_CONFS=""; \ - if [ -f $(TOPDIR)/.config ]; then \ - for config in $(DYNAMIC_DEF_PKG_CONF); do \ - DEF_PKG_CONFS="$$DEF_PKG_CONFS "$$(grep "$$config"=y $(TOPDIR)/.config); \ - done; \ - fi; \ - [ ! -f tmp/.packagedynamicdefault ] || OLD_DEF_PKG_CONFS=$$(cat tmp/.packagedynamicdefault); \ - [ "$$DEF_PKG_CONFS" = "$$OLD_DEF_PKG_CONFS" ] || rm -rf tmp/info/.targetinfo*; \ - mkdir -p tmp && echo "$$DEF_PKG_CONFS" > tmp/.packagedynamicdefault; - -prepare-tmpinfo: check-dynamic-def-pkg FORCE +prepare-tmpinfo: FORCE @+$(MAKE) -r -s $(STAGING_DIR_HOST)/.prereq-build $(PREP_MK) mkdir -p tmp/info feeds [ -e $(TOPDIR)/feeds/base ] || ln -sf $(TOPDIR)/package $(TOPDIR)/feeds/base diff --git a/package/base-files/Makefile b/package/base-files/Makefile index ff7891f18cb0c7..b90ee3a64ebca2 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -43,7 +43,7 @@ define Package/base-files +netifd +libc +jsonfilter +SIGNED_PACKAGES:usign +SIGNED_PACKAGES:openwrt-keyring \ +NAND_SUPPORT:ubi-utils +fstools +fwtool \ +SELINUX:procd-selinux +!SELINUX:procd +USE_SECCOMP:procd-seccomp \ - +SELINUX:busybox-selinux +!SELINUX:busybox +!SMALL_FLASH:procd-ujail + +SELINUX:busybox-selinux +!SELINUX:busybox TITLE:=Base filesystem for OpenWrt URL:=http://openwrt.org/ VERSION:=$(PKG_RELEASE)~$(lastword $(subst -, ,$(REVISION))) diff --git a/package/base-files/files/etc/init.d/led b/package/base-files/files/etc/init.d/led index 7f05254c2ba3a3..377b9dcf3ebce6 100755 --- a/package/base-files/files/etc/init.d/led +++ b/package/base-files/files/etc/init.d/led @@ -3,6 +3,10 @@ START=96 +extra_command "turnon" "Put the LEDs into their default state" +extra_command "turnoff" "Turn all LEDs off" +extra_command "blink" "Blink all LEDs" + led_color_set() { local cfg="$1" local sysfs="$2" @@ -168,7 +172,31 @@ load_led() { } } +turnoff() { + for led in `ls /sys/class/leds/`; do + echo 0 > /sys/class/leds/$led/brightness + done +} + +turnon() { + turnoff + . /etc/diag.sh + set_state done + start +} + +blink() { + for led in `ls /sys/class/leds/`; do + echo 0 > /sys/class/leds/$led/brightness + echo timer > /sys/class/leds/$led/trigger + done +} + start() { + [ "$(uci -q get system.@system[-1].leds_off)" = '1' ] && { + turnoff + exit 0 + } [ -e /sys/class/leds/ ] && { [ -s /var/run/led.state ] && { local led trigger brightness color diff --git a/package/base-files/files/etc/profile b/package/base-files/files/etc/profile index 76b149b9fae5e5..f9acdb439fa630 100644 --- a/package/base-files/files/etc/profile +++ b/package/base-files/files/etc/profile @@ -38,3 +38,24 @@ in order to prevent unauthorized SSH logins. -------------------------------------------------- EOF fi + +if [ -x /usr/bin/apk ]; then +cat << EOF + + OpenWrt recently switched to the "apk" package manager! + + OPKG Command APK Equivalent Description + ------------------------------------------------------------------ + opkg install apk add Install a package + opkg remove apk del Remove a package + opkg upgrade apk upgrade Upgrade all packages + opkg files apk info -L List package contents + opkg list-installed apk info List installed packages + opkg update apk update Update package lists + opkg search apk search Search for packages + ------------------------------------------------------------------ + +For more https://openwrt.org/docs/guide-user/additional-software/opkg-to-apk-cheatsheet + +EOF +fi diff --git a/package/base-files/files/etc/rc.button/reset b/package/base-files/files/etc/rc.button/reset index 2403122ad21d1a..84651334710dce 100755 --- a/package/base-files/files/etc/rc.button/reset +++ b/package/base-files/files/etc/rc.button/reset @@ -23,7 +23,7 @@ released) elif [ "$SEEN" -ge 5 -a -n "$OVERLAY" ] then echo "FACTORY RESET" > /dev/console - jffs2reset -y && reboot & + factoryreset -y && reboot & fi ;; esac diff --git a/package/base-files/files/sbin/firstboot b/package/base-files/files/sbin/firstboot index d9af57d59645bc..3dd6f1e7d24676 100755 --- a/package/base-files/files/sbin/firstboot +++ b/package/base-files/files/sbin/firstboot @@ -1,3 +1,3 @@ #!/bin/sh -/sbin/jffs2reset $@ +/sbin/factoryreset $@ diff --git a/package/boot/arm-trusted-firmware-mediatek/Makefile b/package/boot/arm-trusted-firmware-mediatek/Makefile index 3f70f337845150..c8988fa4003719 100644 --- a/package/boot/arm-trusted-firmware-mediatek/Makefile +++ b/package/boot/arm-trusted-firmware-mediatek/Makefile @@ -352,6 +352,15 @@ define Trusted-Firmware-A/mt7986-spim-nand-ddr3 DDR_TYPE:=ddr3 endef +define Trusted-Firmware-A/mt7986-spim-nand-ubi-ddr3 + NAME:=MediaTek MT7986 (SPI-NAND via SPIM using UBI, DDR3) + BOOT_DEVICE:=spim-nand + BUILD_SUBTARGET:=filogic + PLAT:=mt7986 + DDR_TYPE:=ddr3 + USE_UBI:=1 +endef + define Trusted-Firmware-A/mt7988-nor-ddr3 NAME:=MediaTek MT7988 (SPI-NOR, DDR3) BOOT_DEVICE:=nor @@ -531,6 +540,7 @@ TFA_TARGETS:= \ mt7986-sdmmc-ddr3 \ mt7986-snand-ddr3 \ mt7986-spim-nand-ddr3 \ + mt7986-spim-nand-ubi-ddr3 \ mt7986-ram-ddr4 \ mt7986-emmc-ddr4 \ mt7986-nor-ddr4 \ @@ -570,6 +580,7 @@ TFA_MAKE_FLAGS += \ $(if $(RAM_BOOT_UART_DL),RAM_BOOT_UART_DL=1) \ $(if $(USE_UBI),UBI=1 $(if $(findstring mt7622,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x80000)) \ $(if $(USE_UBI),UBI=1 $(if $(findstring mt7981,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x100000)) \ + $(if $(USE_UBI),UBI=1 $(if $(findstring mt7986,$(PLAT)),OVERRIDE_UBI_START_ADDR=0x200000)) \ $(if $(RAM_BOOT_UART_DL),bl2,all) define Package/trusted-firmware-a-ram/install diff --git a/package/boot/uboot-envtools/files/mediatek_filogic b/package/boot/uboot-envtools/files/mediatek_filogic index 58db7dad281c0c..5bde699a47a47d 100644 --- a/package/boot/uboot-envtools/files/mediatek_filogic +++ b/package/boot/uboot-envtools/files/mediatek_filogic @@ -36,6 +36,7 @@ case "$board" in abt,asr3000|\ h3c,magic-nx30-pro|\ jcg,q30-pro|\ +mercusys,mr90x-v1-ubi|\ netcore,n60|\ nokia,ea0326gmp|\ qihoo,360t7|\ diff --git a/package/boot/uboot-mediatek/Makefile b/package/boot/uboot-mediatek/Makefile index fa314da3998e65..8fda29afa6f3db 100644 --- a/package/boot/uboot-mediatek/Makefile +++ b/package/boot/uboot-mediatek/Makefile @@ -570,6 +570,18 @@ define U-Boot/mt7986_jdcloud_re-cp-03 DEPENDS:=+trusted-firmware-a-mt7986-emmc-ddr4 endef +define U-Boot/mt7986_mercusys_mr90x-v1 + NAME:=MERCUSYS MR90X v1 + BUILD_SUBTARGET:=filogic + BUILD_DEVICES:=mercusys_mr90x-v1-ubi + UBOOT_CONFIG:=mt7986_mercusys_mr90x-v1 + UBOOT_IMAGE:=u-boot.fip + BL2_BOOTDEV:=spim-nand-ubi + BL2_SOC:=mt7986 + BL2_DDRTYPE:=ddr3 + DEPENDS:=+trusted-firmware-a-mt7986-spim-nand-ubi-ddr3 +endef + define U-Boot/mt7986_netcore_n60 NAME:=Netcore N60 BUILD_SUBTARGET:=filogic @@ -847,6 +859,7 @@ UBOOT_TARGETS := \ mt7986_bananapi_bpi-r3-mini-snand \ mt7986_glinet_gl-mt6000 \ mt7986_jdcloud_re-cp-03 \ + mt7986_mercusys_mr90x-v1 \ mt7986_netcore_n60 \ mt7986_tplink_tl-xdr4288 \ mt7986_tplink_tl-xdr6086 \ diff --git a/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch b/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch index cf5f79f5841996..6c31d88be81825 100644 --- a/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch +++ b/package/boot/uboot-mediatek/patches/453-add-openwrt-one.patch @@ -469,7 +469,7 @@ +CONFIG_LMB_MAX_REGIONS=64 --- /dev/null +++ b/openwrt-one-nor_env -@@ -0,0 +1,47 @@ +@@ -0,0 +1,48 @@ +ethaddr_factory=mtd read factory 0x46000000 0x0 0x20000 && env readmem -b ethaddr 0x4600002a 0x6 ; setenv ethaddr_factory +bl2_mtd_write=mtd erase bl2-nor && mtd write bl2-nor $loadaddr 0x0 0x40000 +bl2_tftp_write=tftpboot $loadaddr $bootfile_bl2_nor && run bl2_mtd_write @@ -510,6 +510,7 @@ +serverip=192.168.11.23 +tftp_boot=run led_start ; tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf +tftp_write=run led_start ; tftpboot $loadaddr $bootfile && mtd erase recovery 0x0 ${filesize} && mtd write recovery $loadaddr 0x0 ${filesize} ++usb_pgood_delay=4000 +usb_recovery=run led_start ; usb start && run usb_recovery_bl2 && run usb_recovery_ubi && run led_loop_done +usb_recovery_bl2=fatload usb 0:1 ${loadaddr} ${recoverfile_bl2} && run recovery_write_bl2 +usb_recovery_ubi=fatload usb 0:1 ${loadaddr} ${recoverfile_ubi} && run recovery_write_ubi @@ -519,7 +520,7 @@ +_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" --- /dev/null +++ b/openwrt-one-spi-nand_env -@@ -0,0 +1,60 @@ +@@ -0,0 +1,61 @@ +ethaddr_factory=mtd read factory 0x46000000 0x0 0x20000 && env readmem -b ethaddr 0x4600002a 0x6 ; setenv ethaddr_factory +ipaddr=192.168.11.11 +serverip=192.168.11.23 @@ -571,6 +572,7 @@ +ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs +ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery +ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++usb_pgood_delay=4000 +usb_recover=run led_start ; usb start && run usb_recover_production && run led_loop_done +usb_recover_production=fatload usb 0:1 ${loadaddr} ${bootfile_upg} && iminfo $loadaddr && run ubi_write_production +ubi_write_fip=run ubi_remove_rootfs ; ubi check fip && ubi remove fip ; ubi create fip $filesize static && ubi write $loadaddr fip $filesize diff --git a/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch b/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch new file mode 100644 index 00000000000000..4fae619aa1a2a9 --- /dev/null +++ b/package/boot/uboot-mediatek/patches/459-add-mercusys-mr90x-v1.patch @@ -0,0 +1,343 @@ +--- /dev/null ++++ b/configs/mt7986_mercusys_mr90x-v1_defconfig +@@ -0,0 +1,107 @@ ++CONFIG_ARM=y ++CONFIG_SYS_HAS_NONCACHED_MEMORY=y ++CONFIG_POSITION_INDEPENDENT=y ++CONFIG_ARCH_MEDIATEK=y ++CONFIG_TEXT_BASE=0x41e00000 ++CONFIG_SYS_MALLOC_F_LEN=0x4000 ++CONFIG_NR_DRAM_BANKS=1 ++CONFIG_DEFAULT_DEVICE_TREE="mt7986b-mercusys_mr90x-v1" ++CONFIG_OF_LIBFDT_OVERLAY=y ++CONFIG_TARGET_MT7986=y ++CONFIG_PRE_CON_BUF_ADDR=0x4007ef00 ++CONFIG_DEBUG_UART_BASE=0x11002000 ++CONFIG_DEBUG_UART_CLOCK=40000000 ++CONFIG_SYS_LOAD_ADDR=0x46000000 ++CONFIG_DEBUG_UART=y ++CONFIG_FIT=y ++CONFIG_BOOTDELAY=30 ++CONFIG_AUTOBOOT_KEYED=y ++CONFIG_AUTOBOOT_MENU_SHOW=y ++CONFIG_DEFAULT_FDT_FILE="mediatek/mt7986b-mercusys_mr90x-v1.dtb" ++CONFIG_LOGLEVEL=7 ++CONFIG_PRE_CONSOLE_BUFFER=y ++CONFIG_LOG=y ++CONFIG_BOARD_LATE_INIT=y ++CONFIG_HUSH_PARSER=y ++CONFIG_SYS_PROMPT="MT7986> " ++CONFIG_CMD_CPU=y ++CONFIG_CMD_LICENSE=y ++CONFIG_CMD_BOOTMENU=y ++CONFIG_CMD_ASKENV=y ++CONFIG_CMD_ERASEENV=y ++CONFIG_CMD_ENV_FLAGS=y ++CONFIG_CMD_STRINGS=y ++CONFIG_CMD_DM=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_MTD=y ++CONFIG_CMD_DHCP=y ++CONFIG_CMD_TFTPSRV=y ++CONFIG_CMD_RARP=y ++CONFIG_CMD_PING=y ++CONFIG_CMD_CDP=y ++CONFIG_CMD_SNTP=y ++CONFIG_CMD_DNS=y ++CONFIG_CMD_LINK_LOCAL=y ++CONFIG_CMD_PXE=y ++CONFIG_CMD_CACHE=y ++CONFIG_CMD_PSTORE=y ++CONFIG_CMD_PSTORE_MEM_ADDR=0x42ff0000 ++CONFIG_CMD_UUID=y ++CONFIG_CMD_HASH=y ++CONFIG_CMD_SMC=y ++CONFIG_CMD_UBI=y ++CONFIG_CMD_UBI_RENAME=y ++CONFIG_OF_EMBED=y ++CONFIG_ENV_OVERWRITE=y ++CONFIG_ENV_IS_IN_UBI=y ++CONFIG_SYS_REDUNDAND_ENVIRONMENT=y ++CONFIG_ENV_UBI_PART="ubi" ++CONFIG_ENV_UBI_VOLUME="ubootenv" ++CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2" ++CONFIG_SYS_RELOC_GD_ENV_ADDR=y ++CONFIG_USE_DEFAULT_ENV_FILE=y ++CONFIG_DEFAULT_ENV_FILE="mercusys_mr90x-v1_env" ++CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y ++CONFIG_VERSION_VARIABLE=y ++CONFIG_NET_RANDOM_ETHADDR=y ++CONFIG_NETCONSOLE=y ++CONFIG_USE_IPADDR=y ++CONFIG_IPADDR="192.168.1.1" ++CONFIG_USE_SERVERIP=y ++CONFIG_SERVERIP="192.168.1.254" ++CONFIG_REGMAP=y ++CONFIG_SYSCON=y ++CONFIG_BUTTON=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_CLK=y ++CONFIG_GPIO_HOG=y ++# CONFIG_I2C is not set ++# CONFIG_MMC is not set ++CONFIG_LED=y ++CONFIG_LED_BLINK=y ++CONFIG_LED_GPIO=y ++CONFIG_MTD=y ++CONFIG_DM_MTD=y ++CONFIG_MTD_SPI_NAND=y ++CONFIG_MTD_UBI_FASTMAP=y ++CONFIG_PHY_FIXED=y ++CONFIG_MEDIATEK_ETH=y ++CONFIG_PHY=y ++CONFIG_PINCTRL=y ++CONFIG_PINCONF=y ++CONFIG_PINCTRL_MT7986=y ++CONFIG_POWER_DOMAIN=y ++CONFIG_MTK_POWER_DOMAIN=y ++CONFIG_DM_REGULATOR=y ++CONFIG_DM_REGULATOR_FIXED=y ++CONFIG_DM_REGULATOR_GPIO=y ++CONFIG_RAM=y ++CONFIG_DM_SERIAL=y ++CONFIG_MTK_SERIAL=y ++CONFIG_SPI=y ++CONFIG_DM_SPI=y ++CONFIG_MTK_SPIM=y ++CONFIG_RANDOM_UUID=y ++CONFIG_ZSTD=y ++CONFIG_HEXDUMP=y ++CONFIG_LMB_MAX_REGIONS=64 +--- /dev/null ++++ b/arch/arm/dts/mt7986b-mercusys_mr90x-v1.dts +@@ -0,0 +1,174 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2024 ++ * Author: Mikhail Zhilkin ++ */ ++ ++/dts-v1/; ++#include "mt7986.dtsi" ++#include ++#include ++ ++/ { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ model = "MERCUSYS MR90X v1"; ++ compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; ++ ++ chosen { ++ stdout-path = &uart0; ++ tick-timer = &timer0; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0x40000000 0x20000000>; ++ }; ++ ++ keys { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "reset"; ++ linux,code = ; ++ gpios = <&gpio 10 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ led-0 { ++ label = "green:lan2"; ++ gpios = <&gpio 7 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-1 { ++ label = "green:lan1"; ++ gpios = <&gpio 9 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-2 { ++ label = "green:lan0"; ++ gpios = <&gpio 12 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-3 { ++ label = "green:wan"; ++ gpios = <&gpio 13 GPIO_ACTIVE_LOW>; ++ }; ++ ++ led-4 { ++ label = "amber:status"; ++ gpios = <&gpio 16 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ led_status_green: led-5 { ++ label = "green:status"; ++ gpios = <&gpio 17 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "disabled"; ++}; ++ ++ð { ++ status = "okay"; ++ mediatek,gmac-id = <0>; ++ phy-mode = "2500base-x"; ++ mediatek,switch = "mt7531"; ++ reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&pinctrl { ++ spi_flash_pins: spi0-pins-func-1 { ++ mux { ++ function = "flash"; ++ groups = "spi0", "spi0_wp_hold"; ++ }; ++ ++ conf-pu { ++ pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; ++ drive-strength = ; ++ bias-pull-up = ; ++ }; ++ ++ conf-pd { ++ pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; ++ drive-strength = ; ++ bias-pull-down = ; ++ }; ++ }; ++ ++ spic_pins: spi1-pins-func-1 { ++ mux { ++ function = "spi"; ++ groups = "spi1_2"; ++ }; ++ }; ++ ++ uart1_pins: spi1-pins-func-3 { ++ mux { ++ function = "uart"; ++ groups = "uart1_2"; ++ }; ++ }; ++}; ++ ++&spi0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi_flash_pins>; ++ status = "okay"; ++ must_tx; ++ enhance_timing; ++ dma_ext; ++ ipm_design; ++ tick_dly = <2>; ++ sample_sel = <0>; ++ ++ spi_nand@1 { ++ compatible = "spi-nand"; ++ reg = <1>; ++ spi-max-frequency = <20000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ reg = <0x0 0x100000>; ++ label = "bl2"; ++ }; ++ ++ partition@100000 { ++ reg = <0x100000 0x100000>; ++ label = "factory"; ++ }; ++ ++ partition@200000 { ++ reg = <0x200000 0x7e00000>; ++ label = "ubi"; ++ }; ++ }; ++ }; ++}; ++ ++&watchdog { ++ status = "disabled"; ++}; +--- /dev/null ++++ b/mercusys_mr90x-v1_env +@@ -0,0 +1,53 @@ ++ipaddr=192.168.1.1 ++serverip=192.168.1.254 ++loadaddr=0x46000000 ++console=earlycon=uart8250,mmio32,0x11002000 console=ttyS0 ++bootargs=console=ttyS0,115200n8 console_msg_format=syslog ++bootcmd=run check_buttons ; run boot_production ; run boot_recovery ++bootconf=config-1 ++bootdelay=0 ++bootfile=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-initramfs-recovery.itb ++bootfile_bl2=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-preloader.bin ++bootfile_fip=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-bl31-uboot.fip ++bootfile_upg=openwrt-mediatek-filogic-mercusys_mr90x-v1-ubi-squashfs-sysupgrade.itb ++bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60 ++bootmenu_default=0 ++bootmenu_delay=0 ++bootmenu_title= ( ( ( OpenWrt ) ) ) [SPI-NAND] ++bootmenu_0=Initialize environment.=run _firstboot ++bootmenu_0d=Run default boot command.=run boot_default ++bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return ++bootmenu_2=Boot production system from NAND.=run boot_production ; run bootmenu_confirm_return ++bootmenu_3=Boot recovery system from NAND.=run boot_recovery ; run bootmenu_confirm_return ++bootmenu_4=Load production system via TFTP then write to NAND.=noboot=1 ; replacevol=1 ; run boot_tftp_production ; noboot= ; replacevol= ; run bootmenu_confirm_return ++bootmenu_5=Load recovery system via TFTP then write to NAND.=noboot=1 ; replacevol=1 ; run boot_tftp_recovery ; noboot= ; replacevol= ; run bootmenu_confirm_return ++bootmenu_6=Load BL31+U-Boot FIP via TFTP then write to NAND.=run boot_tftp_write_fip ; run bootmenu_confirm_return ++bootmenu_7=Load BL2 preloader via TFTP then write to NAND.=run boot_tftp_write_bl2 ; run bootmenu_confirm_return ++bootmenu_8=Reboot.=reset ++bootmenu_9=Reset all settings to factory defaults.=run reset_factory ; reset ++boot_default=run led_boot ; run bootcmd ; run boot_recovery ; replacevol=1 ; run boot_tftp_forever ++boot_production=run led_boot ; run ubi_read_production && bootm $loadaddr#$bootconf ++boot_recovery=run led_boot ; run ubi_read_recovery && bootm $loadaddr#$bootconf ++boot_tftp=run led_boot ; tftpboot $loadaddr $bootfile && bootm $loadaddr#$bootconf ++boot_tftp_forever=run led_boot ; while true ; do run boot_tftp ; sleep 1 ; done ++boot_tftp_production=run led_boot ; tftpboot $loadaddr $bootfile_upg && test $replacevol = 1 && iminfo $loadaddr && run ubi_write_production ; if test $noboot = 1 ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_recovery=run led_boot ; tftpboot $loadaddr $bootfile && test $replacevol = 1 && iminfo $loadaddr && run ubi_write_recovery ; if test $noboot = 1 ; then else bootm $loadaddr#$bootconf ; fi ++boot_tftp_write_fip=run led_boot ; tftpboot $loadaddr $bootfile_fip && run ubi_write_fip && run reset_factory ++boot_tftp_write_bl2=run led_boot ; tftpboot $loadaddr $bootfile_bl2 && run snand_write_bl2 ++check_buttons=if button reset ; then run boot_tftp ; fi ++ethaddr_factory=mtd read factory 0x40080000 0x0 0x20000 && env readmem -b ethaddr 0x40088000 0x6 ; setenv ethaddr_factory ++led_boot=led green:status off ; led amber:status on ++reset_factory=mw $loadaddr 0xff 0x1f000 ; ubi write $loadaddr ubootenv 0x1f000 ; ubi write $loadaddr ubootenv2 0x1f000 ; ubi remove rootfs_data ++snand_write_bl2=mtd erase bl2 && mtd write bl2 $loadaddr 0x0 0x40000 ++ubi_create_env=ubi check ubootenv || ubi create ubootenv 0x1f000 dynamic ; ubi check ubootenv2 || ubi create ubootenv2 0x1f000 dynamic ++ubi_prepare_rootfs=if ubi check rootfs_data ; then else if env exists rootfs_data_max ; then ubi create rootfs_data $rootfs_data_max dynamic || ubi create rootfs_data - dynamic ; else ubi create rootfs_data - dynamic ; fi ; fi ++ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr && run ubi_prepare_rootfs ++ubi_read_recovery=ubi check recovery && ubi read $loadaddr recovery ++ubi_remove_rootfs=ubi check rootfs_data && ubi remove rootfs_data ++ubi_write_fip=run ubi_remove_rootfs ; ubi check fip && ubi remove fip ; ubi create fip $filesize static && ubi write $loadaddr fip $filesize ++ubi_write_production=ubi check fit && ubi remove fit ; run ubi_remove_rootfs ; ubi create fit $filesize dynamic && ubi write $loadaddr fit $filesize ++ubi_write_recovery=ubi check recovery && ubi remove recovery ; run ubi_remove_rootfs ; ubi create recovery $filesize dynamic && ubi write $loadaddr recovery $filesize ++_init_env=setenv _init_env ; run ubi_create_env ; saveenv ; saveenv ++_firstboot=setenv _firstboot ; run ethaddr_factory ; run _switch_to_menu ; run _init_env ; bootmenu ++_switch_to_menu=setenv _switch_to_menu ; setenv bootdelay 3 ; setenv bootmenu_delay 3 ; setenv bootmenu_0 $bootmenu_0d ; setenv bootmenu_0d ; run _bootmenu_update_title ++_bootmenu_update_title=setenv _bootmenu_update_title ; setenv bootmenu_title "$bootmenu_title $ver" diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile index de69360aff5232..433ff03a21b032 100644 --- a/package/firmware/linux-firmware/Makefile +++ b/package/firmware/linux-firmware/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=linux-firmware -PKG_VERSION:=20241017 +PKG_VERSION:=20241110 PKG_RELEASE:=1 PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_HASH:=a26c38ef5a83272f2b98ce8bf8ca1865a852a3deea49ce5a8dd804b914351273 +PKG_HASH:=32e6d3eb5c7fcb69fe5d58976c6deafa0d6552719c6e74835064aff049d25bd7 PKG_MAINTAINER:=Felix Fietkau diff --git a/package/firmware/linux-firmware/qca_ath11k.mk b/package/firmware/linux-firmware/qca_ath11k.mk index 3571198d1b666b..9fdd6119488dd9 100644 --- a/package/firmware/linux-firmware/qca_ath11k.mk +++ b/package/firmware/linux-firmware/qca_ath11k.mk @@ -10,7 +10,11 @@ Package/ath11k-firmware-wcn6750 = $(call Package/firmware-default,WCN6750 ath11k define Package/ath11k-firmware-wcn6750/install $(INSTALL_DIR) $(1)/lib/firmware/ath11k/WCN6750/hw1.0 $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/* $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/board-2.bin $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/Notice.txt $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/ath11k/WCN6750/hw1.0/sc7280/wpss.mbn $(1)/lib/firmware/ath11k/WCN6750/hw1.0/ endef $(eval $(call BuildPackage,ath11k-firmware-wcn6750)) diff --git a/package/firmware/linux-firmware/realtek.mk b/package/firmware/linux-firmware/realtek.mk index c2ab1c9d0dee0a..749d93be3e2909 100644 --- a/package/firmware/linux-firmware/realtek.mk +++ b/package/firmware/linux-firmware/realtek.mk @@ -140,6 +140,20 @@ define Package/rtl8761bu-firmware/install endef $(eval $(call BuildPackage,rtl8761bu-firmware)) +Package/rtl8812a-firmware = $(call Package/firmware-default,RealTek RTL8812AU firmware) +define Package/rtl8812a-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/rtw88 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8812a_fw.bin $(1)/lib/firmware/rtw88 +endef +$(eval $(call BuildPackage,rtl8812a-firmware)) + +Package/rtl8821a-firmware = $(call Package/firmware-default,RealTek RTL8821AU firmware) +define Package/rtl8821a-firmware/install + $(INSTALL_DIR) $(1)/lib/firmware/rtw88 + $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtw88/rtw8821a_fw.bin $(1)/lib/firmware/rtw88 +endef +$(eval $(call BuildPackage,rtl8821a-firmware)) + Package/rtl8821ae-firmware = $(call Package/firmware-default,RealTek RTL8821AE firmware,,LICENCE.rtlwifi_firmware.txt) define Package/rtl8821ae-firmware/install $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi diff --git a/package/kernel/linux/modules/leds.mk b/package/kernel/linux/modules/leds.mk index 8b24cb0ef88e94..0c42895bb2f3c9 100644 --- a/package/kernel/linux/modules/leds.mk +++ b/package/kernel/linux/modules/leds.mk @@ -147,6 +147,24 @@ endef $(eval $(call KernelPackage,leds-apu)) +define KernelPackage/leds-ktd202x + SUBMENU:=LED modules + TITLE:=LED support for KTD202x Chips + DEPENDS:=+kmod-i2c-core +kmod-regmap-i2c + KCONFIG:=CONFIG_LEDS_KTD202X + FILES:= $(LINUX_DIR)/drivers/leds/rgb/leds-ktd202x.ko + AUTOLOAD:=$(call AutoProbe,leds-ktd202x,1) +endef + +define KernelPackage/leds-ktd202x/description + This option enables support for the Kinetic KTD2026/KTD2027 + RGB/White LED driver found in different BQ mobile phones. + It is a 3 or 4 channel LED driver programmed via an I2C interface. +endef + +$(eval $(call KernelPackage,leds-ktd202x)) + + define KernelPackage/leds-mlxcpld SUBMENU:=$(LEDS_MENU) TITLE:=LED support for the Mellanox boards diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 22cd0e97b41770..1c848d1f57ebe1 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -100,7 +100,7 @@ PKG_CONFIG_DEPENDS += \ define KernelPackage/cfg80211 $(call KernelPackage/mac80211/Default) TITLE:=cfg80211 - wireless configuration API - DEPENDS+= +iw +iwinfo +wifi-scripts +wireless-regdb +USE_RFKILL:kmod-rfkill + DEPENDS+= +iw +!WIFI_SCRIPTS_UCODE:iwinfo +wifi-scripts +wireless-regdb +USE_RFKILL:kmod-rfkill ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) FILES:= \ $(PKG_BUILD_DIR)/compat/compat.ko \ diff --git a/package/kernel/mac80211/patches/rtl/001-v6.12-wifi-rtw88-Set-efuse-ext_lna_5g-fix-typo.patch b/package/kernel/mac80211/patches/rtl/001-v6.12-wifi-rtw88-Set-efuse-ext_lna_5g-fix-typo.patch new file mode 100644 index 00000000000000..96a6743c5bc9d0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/001-v6.12-wifi-rtw88-Set-efuse-ext_lna_5g-fix-typo.patch @@ -0,0 +1,30 @@ +From 8fbcaa308591b91e9037ab6a8d733873b749a70d Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Sat, 6 Jul 2024 01:40:58 +0300 +Subject: [PATCH] wifi: rtw88: Set efuse->ext_lna_5g - fix typo + +efuse->ext_lna_2g is set twice and efuse->ext_lna_5g is not set at all. +Set each one once. + +Nothing uses these members right now. They will be used by the RTL8821AU +and RTL8812AU drivers. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/8ccc9e13-0d45-417d-8f88-93a0ad294f77@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -2006,7 +2006,7 @@ static int rtw_chip_efuse_info_setup(str + efuse->ext_pa_2g = efuse->pa_type_2g & BIT(4) ? 1 : 0; + efuse->ext_lna_2g = efuse->lna_type_2g & BIT(3) ? 1 : 0; + efuse->ext_pa_5g = efuse->pa_type_5g & BIT(0) ? 1 : 0; +- efuse->ext_lna_2g = efuse->lna_type_5g & BIT(3) ? 1 : 0; ++ efuse->ext_lna_5g = efuse->lna_type_5g & BIT(3) ? 1 : 0; + + if (!is_valid_ether_addr(efuse->addr)) { + eth_random_addr(efuse->addr); diff --git a/package/kernel/mac80211/patches/rtl/002-v6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch b/package/kernel/mac80211/patches/rtl/002-v6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch new file mode 100644 index 00000000000000..2faa59d760ee4d --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/002-v6.12-wifi-rtw88-usb-Support-USB-3-with-RTL8822CU-RTL8822B.patch @@ -0,0 +1,284 @@ +From 315c23a64e99552502dd4d18d6ddc073fad9a7c3 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 11 Jul 2024 01:11:33 +0300 +Subject: [PATCH] wifi: rtw88: usb: Support USB 3 with RTL8822CU/RTL8822BU + +The Realtek wifi 5 devices which support USB 3 are weird: when first +plugged in, they pretend to be USB 2. The driver needs to send some +commands to the device, which make it disappear and come back as a +USB 3 device. + +Implement the required commands in rtw88. + +When a USB 3 device is plugged into a USB 2 port, rtw88 will try to +switch it to USB 3 mode only once. The device will disappear and come +back still in USB 2 mode, of course. + +Some people experience heavy interference in the 2.4 GHz band in +USB 3 mode, so add a module parameter switch_usb_mode with the +default value 1 to let people disable the switching. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/77906c62-5674-426f-bde1-1b2a12a0339d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/debug.h | 1 + + drivers/net/wireless/realtek/rtw88/main.h | 2 + + drivers/net/wireless/realtek/rtw88/reg.h | 11 +++ + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 4 +- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.h | 24 +++--- + drivers/net/wireless/realtek/rtw88/usb.c | 84 +++++++++++++++++++ + 8 files changed, 116 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/debug.h ++++ b/drivers/net/wireless/realtek/rtw88/debug.h +@@ -25,6 +25,7 @@ enum rtw_debug_mask { + RTW_DBG_HW_SCAN = 0x00010000, + RTW_DBG_STATE = 0x00020000, + RTW_DBG_SDIO = 0x00040000, ++ RTW_DBG_USB = 0x00080000, + + RTW_DBG_UNEXP = 0x80000000, + RTW_DBG_ALL = 0xffffffff +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1785,6 +1785,8 @@ struct rtw_efuse { + bool share_ant; + u8 bt_setting; + ++ u8 usb_mode_switch; ++ + struct { + u8 hci; + u8 bw; +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -15,6 +15,7 @@ + #define BIT_WLOCK_1C_B6 BIT(5) + #define REG_SYS_PW_CTRL 0x0004 + #define BIT_PFM_WOWL BIT(3) ++#define BIT_APFM_OFFMAC BIT(9) + #define REG_SYS_CLK_CTRL 0x0008 + #define BIT_CPU_CLK_EN BIT(14) + +@@ -133,6 +134,14 @@ + #define REG_PMC_DBG_CTRL1 0xa8 + #define BITS_PMC_BT_IQK_STS GENMASK(22, 21) + ++#define REG_PAD_CTRL2 0x00C4 ++#define BIT_RSM_EN_V1 BIT(16) ++#define BIT_NO_PDN_CHIPOFF_V1 BIT(17) ++#define BIT_MASK_USB23_SW_MODE_V1 GENMASK(19, 18) ++#define BIT_USB3_USB2_TRANSITION BIT(20) ++#define BIT_USB_MODE_U2 1 ++#define BIT_USB_MODE_U3 2 ++ + #define REG_EFUSE_ACCESS 0x00CF + #define EFUSE_ACCESS_ON 0x69 + #define EFUSE_ACCESS_OFF 0x00 +@@ -568,6 +577,8 @@ + #define BIT_WL_SECURITY_CLK BIT(15) + #define BIT_DDMA_EN BIT(8) + ++#define REG_SW_MDIO 0x10C0 ++ + #define REG_H2C_PKT_READADDR 0x10D0 + #define REG_H2C_PKT_WRITEADDR 0x10D4 + #define REG_FW_DBG6 0x10F8 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -46,6 +46,7 @@ static int rtw8822b_read_efuse(struct rt + + map = (struct rtw8822b_efuse *)log_map; + ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k; +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +@@ -72,7 +72,9 @@ struct rtw8822bs_efuse { + + struct rtw8822b_efuse { + __le16 rtl_id; +- u8 res0[0x0e]; ++ u8 res0[4]; ++ u8 usb_mode; ++ u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -49,6 +49,7 @@ static int rtw8822c_read_efuse(struct rt + + map = (struct rtw8822c_efuse *)log_map; + ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(7)); + efuse->rfe_option = map->rfe_option; + efuse->rf_board_option = map->rf_board_option; + efuse->crystal_cap = map->xtal_k & XCAP_MASK; +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.h +@@ -59,16 +59,18 @@ struct rtw8822ce_efuse { + + struct rtw8822c_efuse { + __le16 rtl_id; +- u8 res0[0x0e]; ++ u8 res0[4]; ++ u8 usb_mode; ++ u8 res1[0x09]; + + /* power index for four RF paths */ + struct rtw_txpwr_idx txpwr_idx_table[4]; + + u8 channel_plan; /* 0xb8 */ + u8 xtal_k; +- u8 res1; ++ u8 res2; + u8 iqk_lck; +- u8 res2[5]; /* 0xbc */ ++ u8 res3[5]; /* 0xbc */ + u8 rf_board_option; + u8 rf_feature_option; + u8 rf_bt_setting; +@@ -80,21 +82,21 @@ struct rtw8822c_efuse { + u8 rf_antenna_option; /* 0xc9 */ + u8 rfe_option; + u8 country_code[2]; +- u8 res3[3]; ++ u8 res4[3]; + u8 path_a_thermal; /* 0xd0 */ + u8 path_b_thermal; +- u8 res4[2]; ++ u8 res5[2]; + u8 rx_gain_gap_2g_ofdm; +- u8 res5; +- u8 rx_gain_gap_2g_cck; + u8 res6; +- u8 rx_gain_gap_5gl; ++ u8 rx_gain_gap_2g_cck; + u8 res7; +- u8 rx_gain_gap_5gm; ++ u8 rx_gain_gap_5gl; + u8 res8; +- u8 rx_gain_gap_5gh; ++ u8 rx_gain_gap_5gm; + u8 res9; +- u8 res10[0x42]; ++ u8 rx_gain_gap_5gh; ++ u8 res10; ++ u8 res11[0x42]; + union { + struct rtw8822ce_efuse e; + struct rtw8822cu_efuse u; +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -14,6 +14,11 @@ + #include "ps.h" + #include "usb.h" + ++static bool rtw_switch_usb_mode = true; ++module_param_named(switch_usb_mode, rtw_switch_usb_mode, bool, 0644); ++MODULE_PARM_DESC(switch_usb_mode, ++ "Set to N to disable switching to USB 3 mode to avoid potential interference in the 2.4 GHz band (default: Y)"); ++ + #define RTW_USB_MAX_RXQ_LEN 512 + + struct rtw_usb_txcb { +@@ -841,6 +846,77 @@ static void rtw_usb_intf_deinit(struct r + usb_set_intfdata(intf, NULL); + } + ++static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) ++{ ++ enum usb_device_speed cur_speed; ++ u8 id = rtwdev->chip->id; ++ bool can_switch; ++ u32 pad_ctrl2; ++ ++ if (rtw_read8(rtwdev, REG_SYS_CFG2 + 3) == 0x20) ++ cur_speed = USB_SPEED_SUPER; ++ else ++ cur_speed = USB_SPEED_HIGH; ++ ++ if (cur_speed == USB_SPEED_SUPER) ++ return 0; ++ ++ pad_ctrl2 = rtw_read32(rtwdev, REG_PAD_CTRL2); ++ ++ can_switch = !!(pad_ctrl2 & (BIT_MASK_USB23_SW_MODE_V1 | ++ BIT_USB3_USB2_TRANSITION)); ++ ++ if (!can_switch) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode unsupported by the chip\n"); ++ return 0; ++ } ++ ++ /* At this point cur_speed is USB_SPEED_HIGH. If we already tried ++ * to switch don't try again - it's a USB 2 port. ++ */ ++ if (u32_get_bits(pad_ctrl2, BIT_MASK_USB23_SW_MODE_V1) == BIT_USB_MODE_U3) ++ return 0; ++ ++ /* Enable IO wrapper timeout */ ++ if (id == RTW_CHIP_TYPE_8822B || id == RTW_CHIP_TYPE_8821C) ++ rtw_write8_clr(rtwdev, REG_SW_MDIO + 3, BIT(0)); ++ ++ u32p_replace_bits(&pad_ctrl2, BIT_USB_MODE_U3, BIT_MASK_USB23_SW_MODE_V1); ++ pad_ctrl2 |= BIT_RSM_EN_V1; ++ ++ rtw_write32(rtwdev, REG_PAD_CTRL2, pad_ctrl2); ++ rtw_write8(rtwdev, REG_PAD_CTRL2 + 1, 4); ++ ++ rtw_write16_set(rtwdev, REG_SYS_PW_CTRL, BIT_APFM_OFFMAC); ++ usleep_range(1000, 1001); ++ rtw_write32_set(rtwdev, REG_PAD_CTRL2, BIT_NO_PDN_CHIPOFF_V1); ++ ++ return 1; ++} ++ ++static int rtw_usb_switch_mode(struct rtw_dev *rtwdev) ++{ ++ u8 id = rtwdev->chip->id; ++ ++ if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B) ++ return 0; ++ ++ if (!rtwdev->efuse.usb_mode_switch) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode disabled by chip's efuse\n"); ++ return 0; ++ } ++ ++ if (!rtw_switch_usb_mode) { ++ rtw_dbg(rtwdev, RTW_DBG_USB, ++ "Switching to USB 3 mode disabled by module parameter\n"); ++ return 0; ++ } ++ ++ return rtw_usb_switch_mode_new(rtwdev); ++} ++ + int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) + { + struct rtw_dev *rtwdev; +@@ -896,6 +972,14 @@ int rtw_usb_probe(struct usb_interface * + goto err_destroy_rxwq; + } + ++ ret = rtw_usb_switch_mode(rtwdev); ++ if (ret) { ++ /* Not a fail, but we do need to skip rtw_register_hw. */ ++ rtw_dbg(rtwdev, RTW_DBG_USB, "switching to USB 3 mode\n"); ++ ret = 0; ++ goto err_destroy_rxwq; ++ } ++ + ret = rtw_register_hw(rtwdev, rtwdev->hw); + if (ret) { + rtw_err(rtwdev, "failed to register hw\n"); diff --git a/package/kernel/mac80211/patches/rtl/004-v6.12-wifi-rtw88-debugfs-support-multiple-adapters-debuggi.patch b/package/kernel/mac80211/patches/rtl/004-v6.12-wifi-rtw88-debugfs-support-multiple-adapters-debuggi.patch new file mode 100644 index 00000000000000..d965fbce927eba --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/004-v6.12-wifi-rtw88-debugfs-support-multiple-adapters-debuggi.patch @@ -0,0 +1,454 @@ +From 8db6c1ca64664ef9b071e6eeb646023ac5b240a8 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Thu, 18 Jul 2024 14:41:55 +0800 +Subject: [PATCH] wifi: rtw88: debugfs: support multiple adapters debugging + +Originally in order to read partial registers from large area, we write +a range value stored into a static variable and read registers according +to the static variable. + +However, if we install more than one adapters supported by this driver, +the static variables will be overwritten by latter adapters. To resolve +the problem, move the static variables to struct rtw_dev for each adapter. + +With changes, smatch spends too much time to parse rtw_debugfs_init(): + debug.c:1289 rtw_debugfs_init() parse error: turning off implications + after 60 seconds +Move stuffs of adding debugfs entries to three rtw_debugfs_add_xxx() +functions. + +Reported-by: Bitterblue Smith +Closes: https://lore.kernel.org/linux-wireless/cd6a2acf3c2c36d938b40140b52a779516f446a9.camel@realtek.com/T/#m27662022c70d9f893ba96f6c6a8dd8fce2434dfe +Tested-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240718064155.38955-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/debug.c | 303 ++++++++++++--------- + drivers/net/wireless/realtek/rtw88/debug.h | 2 + + drivers/net/wireless/realtek/rtw88/main.c | 1 + + drivers/net/wireless/realtek/rtw88/main.h | 3 +- + 4 files changed, 180 insertions(+), 129 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -43,6 +43,62 @@ struct rtw_debugfs_priv { + }; + }; + ++struct rtw_debugfs { ++ struct rtw_debugfs_priv mac_0; ++ struct rtw_debugfs_priv mac_1; ++ struct rtw_debugfs_priv mac_2; ++ struct rtw_debugfs_priv mac_3; ++ struct rtw_debugfs_priv mac_4; ++ struct rtw_debugfs_priv mac_5; ++ struct rtw_debugfs_priv mac_6; ++ struct rtw_debugfs_priv mac_7; ++ struct rtw_debugfs_priv mac_10; ++ struct rtw_debugfs_priv mac_11; ++ struct rtw_debugfs_priv mac_12; ++ struct rtw_debugfs_priv mac_13; ++ struct rtw_debugfs_priv mac_14; ++ struct rtw_debugfs_priv mac_15; ++ struct rtw_debugfs_priv mac_16; ++ struct rtw_debugfs_priv mac_17; ++ struct rtw_debugfs_priv bb_8; ++ struct rtw_debugfs_priv bb_9; ++ struct rtw_debugfs_priv bb_a; ++ struct rtw_debugfs_priv bb_b; ++ struct rtw_debugfs_priv bb_c; ++ struct rtw_debugfs_priv bb_d; ++ struct rtw_debugfs_priv bb_e; ++ struct rtw_debugfs_priv bb_f; ++ struct rtw_debugfs_priv bb_18; ++ struct rtw_debugfs_priv bb_19; ++ struct rtw_debugfs_priv bb_1a; ++ struct rtw_debugfs_priv bb_1b; ++ struct rtw_debugfs_priv bb_1c; ++ struct rtw_debugfs_priv bb_1d; ++ struct rtw_debugfs_priv bb_1e; ++ struct rtw_debugfs_priv bb_1f; ++ struct rtw_debugfs_priv bb_2c; ++ struct rtw_debugfs_priv bb_2d; ++ struct rtw_debugfs_priv bb_40; ++ struct rtw_debugfs_priv bb_41; ++ struct rtw_debugfs_priv rf_dump; ++ struct rtw_debugfs_priv tx_pwr_tbl; ++ struct rtw_debugfs_priv write_reg; ++ struct rtw_debugfs_priv h2c; ++ struct rtw_debugfs_priv rf_write; ++ struct rtw_debugfs_priv rf_read; ++ struct rtw_debugfs_priv read_reg; ++ struct rtw_debugfs_priv fix_rate; ++ struct rtw_debugfs_priv dump_cam; ++ struct rtw_debugfs_priv rsvd_page; ++ struct rtw_debugfs_priv phy_info; ++ struct rtw_debugfs_priv coex_enable; ++ struct rtw_debugfs_priv coex_info; ++ struct rtw_debugfs_priv edcca_enable; ++ struct rtw_debugfs_priv fw_crash; ++ struct rtw_debugfs_priv force_lowest_basic_rate; ++ struct rtw_debugfs_priv dm_cap; ++}; ++ + static const char * const rtw_dm_cap_strs[] = { + [RTW_DM_CAP_NA] = "NA", + [RTW_DM_CAP_TXGAPK] = "TXGAPK", +@@ -524,7 +580,7 @@ static int rtw_debug_get_bb_page(struct + return 0; + } + +-static int rtw_debug_get_rf_dump(struct seq_file *m, void *v) ++static int rtw_debugfs_get_rf_dump(struct seq_file *m, void *v) + { + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +@@ -1074,139 +1130,102 @@ static int rtw_debugfs_get_dm_cap(struct + return 0; + } + +-#define rtw_debug_impl_mac(page, addr) \ +-static struct rtw_debugfs_priv rtw_debug_priv_mac_ ##page = { \ ++#define rtw_debug_priv_mac(addr) \ ++{ \ + .cb_read = rtw_debug_get_mac_page, \ + .cb_data = addr, \ + } + +-rtw_debug_impl_mac(0, 0x0000); +-rtw_debug_impl_mac(1, 0x0100); +-rtw_debug_impl_mac(2, 0x0200); +-rtw_debug_impl_mac(3, 0x0300); +-rtw_debug_impl_mac(4, 0x0400); +-rtw_debug_impl_mac(5, 0x0500); +-rtw_debug_impl_mac(6, 0x0600); +-rtw_debug_impl_mac(7, 0x0700); +-rtw_debug_impl_mac(10, 0x1000); +-rtw_debug_impl_mac(11, 0x1100); +-rtw_debug_impl_mac(12, 0x1200); +-rtw_debug_impl_mac(13, 0x1300); +-rtw_debug_impl_mac(14, 0x1400); +-rtw_debug_impl_mac(15, 0x1500); +-rtw_debug_impl_mac(16, 0x1600); +-rtw_debug_impl_mac(17, 0x1700); +- +-#define rtw_debug_impl_bb(page, addr) \ +-static struct rtw_debugfs_priv rtw_debug_priv_bb_ ##page = { \ ++#define rtw_debug_priv_bb(addr) \ ++{ \ + .cb_read = rtw_debug_get_bb_page, \ + .cb_data = addr, \ + } + +-rtw_debug_impl_bb(8, 0x0800); +-rtw_debug_impl_bb(9, 0x0900); +-rtw_debug_impl_bb(a, 0x0a00); +-rtw_debug_impl_bb(b, 0x0b00); +-rtw_debug_impl_bb(c, 0x0c00); +-rtw_debug_impl_bb(d, 0x0d00); +-rtw_debug_impl_bb(e, 0x0e00); +-rtw_debug_impl_bb(f, 0x0f00); +-rtw_debug_impl_bb(18, 0x1800); +-rtw_debug_impl_bb(19, 0x1900); +-rtw_debug_impl_bb(1a, 0x1a00); +-rtw_debug_impl_bb(1b, 0x1b00); +-rtw_debug_impl_bb(1c, 0x1c00); +-rtw_debug_impl_bb(1d, 0x1d00); +-rtw_debug_impl_bb(1e, 0x1e00); +-rtw_debug_impl_bb(1f, 0x1f00); +-rtw_debug_impl_bb(2c, 0x2c00); +-rtw_debug_impl_bb(2d, 0x2d00); +-rtw_debug_impl_bb(40, 0x4000); +-rtw_debug_impl_bb(41, 0x4100); +- +-static struct rtw_debugfs_priv rtw_debug_priv_rf_dump = { +- .cb_read = rtw_debug_get_rf_dump, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_tx_pwr_tbl = { +- .cb_read = rtw_debugfs_get_tx_pwr_tbl, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_write_reg = { +- .cb_write = rtw_debugfs_set_write_reg, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_h2c = { +- .cb_write = rtw_debugfs_set_h2c, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_rf_write = { +- .cb_write = rtw_debugfs_set_rf_write, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_rf_read = { +- .cb_write = rtw_debugfs_set_rf_read, +- .cb_read = rtw_debugfs_get_rf_read, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_read_reg = { +- .cb_write = rtw_debugfs_set_read_reg, +- .cb_read = rtw_debugfs_get_read_reg, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_fix_rate = { +- .cb_write = rtw_debugfs_set_fix_rate, +- .cb_read = rtw_debugfs_get_fix_rate, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_dump_cam = { +- .cb_write = rtw_debugfs_set_single_input, +- .cb_read = rtw_debugfs_get_dump_cam, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_rsvd_page = { +- .cb_write = rtw_debugfs_set_rsvd_page, +- .cb_read = rtw_debugfs_get_rsvd_page, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_phy_info = { +- .cb_read = rtw_debugfs_get_phy_info, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_coex_enable = { +- .cb_write = rtw_debugfs_set_coex_enable, +- .cb_read = rtw_debugfs_get_coex_enable, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_coex_info = { +- .cb_read = rtw_debugfs_get_coex_info, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_edcca_enable = { +- .cb_write = rtw_debugfs_set_edcca_enable, +- .cb_read = rtw_debugfs_get_edcca_enable, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_fw_crash = { +- .cb_write = rtw_debugfs_set_fw_crash, +- .cb_read = rtw_debugfs_get_fw_crash, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_force_lowest_basic_rate = { +- .cb_write = rtw_debugfs_set_force_lowest_basic_rate, +- .cb_read = rtw_debugfs_get_force_lowest_basic_rate, +-}; +- +-static struct rtw_debugfs_priv rtw_debug_priv_dm_cap = { +- .cb_write = rtw_debugfs_set_dm_cap, +- .cb_read = rtw_debugfs_get_dm_cap, ++#define rtw_debug_priv_get(name) \ ++{ \ ++ .cb_read = rtw_debugfs_get_ ##name, \ ++} ++ ++#define rtw_debug_priv_set(name) \ ++{ \ ++ .cb_write = rtw_debugfs_set_ ##name, \ ++} ++ ++#define rtw_debug_priv_set_and_get(name) \ ++{ \ ++ .cb_write = rtw_debugfs_set_ ##name, \ ++ .cb_read = rtw_debugfs_get_ ##name, \ ++} ++ ++#define rtw_debug_priv_set_single_and_get(name) \ ++{ \ ++ .cb_write = rtw_debugfs_set_single_input, \ ++ .cb_read = rtw_debugfs_get_ ##name, \ ++} ++ ++static const struct rtw_debugfs rtw_debugfs_templ = { ++ .mac_0 = rtw_debug_priv_mac(0x0000), ++ .mac_1 = rtw_debug_priv_mac(0x0100), ++ .mac_2 = rtw_debug_priv_mac(0x0200), ++ .mac_3 = rtw_debug_priv_mac(0x0300), ++ .mac_4 = rtw_debug_priv_mac(0x0400), ++ .mac_5 = rtw_debug_priv_mac(0x0500), ++ .mac_6 = rtw_debug_priv_mac(0x0600), ++ .mac_7 = rtw_debug_priv_mac(0x0700), ++ .mac_10 = rtw_debug_priv_mac(0x1000), ++ .mac_11 = rtw_debug_priv_mac(0x1100), ++ .mac_12 = rtw_debug_priv_mac(0x1200), ++ .mac_13 = rtw_debug_priv_mac(0x1300), ++ .mac_14 = rtw_debug_priv_mac(0x1400), ++ .mac_15 = rtw_debug_priv_mac(0x1500), ++ .mac_16 = rtw_debug_priv_mac(0x1600), ++ .mac_17 = rtw_debug_priv_mac(0x1700), ++ .bb_8 = rtw_debug_priv_bb(0x0800), ++ .bb_9 = rtw_debug_priv_bb(0x0900), ++ .bb_a = rtw_debug_priv_bb(0x0a00), ++ .bb_b = rtw_debug_priv_bb(0x0b00), ++ .bb_c = rtw_debug_priv_bb(0x0c00), ++ .bb_d = rtw_debug_priv_bb(0x0d00), ++ .bb_e = rtw_debug_priv_bb(0x0e00), ++ .bb_f = rtw_debug_priv_bb(0x0f00), ++ .bb_18 = rtw_debug_priv_bb(0x1800), ++ .bb_19 = rtw_debug_priv_bb(0x1900), ++ .bb_1a = rtw_debug_priv_bb(0x1a00), ++ .bb_1b = rtw_debug_priv_bb(0x1b00), ++ .bb_1c = rtw_debug_priv_bb(0x1c00), ++ .bb_1d = rtw_debug_priv_bb(0x1d00), ++ .bb_1e = rtw_debug_priv_bb(0x1e00), ++ .bb_1f = rtw_debug_priv_bb(0x1f00), ++ .bb_2c = rtw_debug_priv_bb(0x2c00), ++ .bb_2d = rtw_debug_priv_bb(0x2d00), ++ .bb_40 = rtw_debug_priv_bb(0x4000), ++ .bb_41 = rtw_debug_priv_bb(0x4100), ++ .rf_dump = rtw_debug_priv_get(rf_dump), ++ .tx_pwr_tbl = rtw_debug_priv_get(tx_pwr_tbl), ++ .write_reg = rtw_debug_priv_set(write_reg), ++ .h2c = rtw_debug_priv_set(h2c), ++ .rf_write = rtw_debug_priv_set(rf_write), ++ .rf_read = rtw_debug_priv_set_and_get(rf_read), ++ .read_reg = rtw_debug_priv_set_and_get(read_reg), ++ .fix_rate = rtw_debug_priv_set_and_get(fix_rate), ++ .dump_cam = rtw_debug_priv_set_single_and_get(dump_cam), ++ .rsvd_page = rtw_debug_priv_set_and_get(rsvd_page), ++ .phy_info = rtw_debug_priv_get(phy_info), ++ .coex_enable = rtw_debug_priv_set_and_get(coex_enable), ++ .coex_info = rtw_debug_priv_get(coex_info), ++ .edcca_enable = rtw_debug_priv_set_and_get(edcca_enable), ++ .fw_crash = rtw_debug_priv_set_and_get(fw_crash), ++ .force_lowest_basic_rate = rtw_debug_priv_set_and_get(force_lowest_basic_rate), ++ .dm_cap = rtw_debug_priv_set_and_get(dm_cap), + }; + + #define rtw_debugfs_add_core(name, mode, fopname, parent) \ + do { \ +- rtw_debug_priv_ ##name.rtwdev = rtwdev; \ ++ struct rtw_debugfs_priv *priv = &rtwdev->debugfs->name; \ ++ priv->rtwdev = rtwdev; \ + if (IS_ERR(debugfs_create_file(#name, mode, \ +- parent, &rtw_debug_priv_ ##name,\ ++ parent, priv, \ + &file_ops_ ##fopname))) \ + pr_debug("Unable to initialize debugfs:%s\n", \ + #name); \ +@@ -1219,12 +1238,9 @@ static struct rtw_debugfs_priv rtw_debug + #define rtw_debugfs_add_r(name) \ + rtw_debugfs_add_core(name, S_IFREG | 0444, single_r, debugfs_topdir) + +-void rtw_debugfs_init(struct rtw_dev *rtwdev) ++static ++void rtw_debugfs_add_basic(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) + { +- struct dentry *debugfs_topdir; +- +- debugfs_topdir = debugfs_create_dir("rtw88", +- rtwdev->hw->wiphy->debugfsdir); + rtw_debugfs_add_w(write_reg); + rtw_debugfs_add_rw(read_reg); + rtw_debugfs_add_w(rf_write); +@@ -1236,6 +1252,17 @@ void rtw_debugfs_init(struct rtw_dev *rt + rtw_debugfs_add_r(coex_info); + rtw_debugfs_add_rw(coex_enable); + rtw_debugfs_add_w(h2c); ++ rtw_debugfs_add_r(rf_dump); ++ rtw_debugfs_add_r(tx_pwr_tbl); ++ rtw_debugfs_add_rw(edcca_enable); ++ rtw_debugfs_add_rw(fw_crash); ++ rtw_debugfs_add_rw(force_lowest_basic_rate); ++ rtw_debugfs_add_rw(dm_cap); ++} ++ ++static ++void rtw_debugfs_add_sec0(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) ++{ + rtw_debugfs_add_r(mac_0); + rtw_debugfs_add_r(mac_1); + rtw_debugfs_add_r(mac_2); +@@ -1252,6 +1279,11 @@ void rtw_debugfs_init(struct rtw_dev *rt + rtw_debugfs_add_r(bb_d); + rtw_debugfs_add_r(bb_e); + rtw_debugfs_add_r(bb_f); ++} ++ ++static ++void rtw_debugfs_add_sec1(struct rtw_dev *rtwdev, struct dentry *debugfs_topdir) ++{ + rtw_debugfs_add_r(mac_10); + rtw_debugfs_add_r(mac_11); + rtw_debugfs_add_r(mac_12); +@@ -1274,14 +1306,29 @@ void rtw_debugfs_init(struct rtw_dev *rt + rtw_debugfs_add_r(bb_40); + rtw_debugfs_add_r(bb_41); + } +- rtw_debugfs_add_r(rf_dump); +- rtw_debugfs_add_r(tx_pwr_tbl); +- rtw_debugfs_add_rw(edcca_enable); +- rtw_debugfs_add_rw(fw_crash); +- rtw_debugfs_add_rw(force_lowest_basic_rate); +- rtw_debugfs_add_rw(dm_cap); + } + ++void rtw_debugfs_init(struct rtw_dev *rtwdev) ++{ ++ struct dentry *debugfs_topdir; ++ ++ rtwdev->debugfs = kmemdup(&rtw_debugfs_templ, sizeof(rtw_debugfs_templ), ++ GFP_KERNEL); ++ if (!rtwdev->debugfs) ++ return; ++ ++ debugfs_topdir = debugfs_create_dir("rtw88", ++ rtwdev->hw->wiphy->debugfsdir); ++ ++ rtw_debugfs_add_basic(rtwdev, debugfs_topdir); ++ rtw_debugfs_add_sec0(rtwdev, debugfs_topdir); ++ rtw_debugfs_add_sec1(rtwdev, debugfs_topdir); ++} ++ ++void rtw_debugfs_deinit(struct rtw_dev *rtwdev) ++{ ++ kfree(rtwdev->debugfs); ++} + #endif /* CPTCFG_RTW88_DEBUGFS */ + + #ifdef CPTCFG_RTW88_DEBUG +--- a/drivers/net/wireless/realtek/rtw88/debug.h ++++ b/drivers/net/wireless/realtek/rtw88/debug.h +@@ -34,11 +34,13 @@ enum rtw_debug_mask { + #ifdef CPTCFG_RTW88_DEBUGFS + + void rtw_debugfs_init(struct rtw_dev *rtwdev); ++void rtw_debugfs_deinit(struct rtw_dev *rtwdev); + void rtw_debugfs_get_simple_phy_info(struct seq_file *m); + + #else + + static inline void rtw_debugfs_init(struct rtw_dev *rtwdev) {} ++static inline void rtw_debugfs_deinit(struct rtw_dev *rtwdev) {} + + #endif /* CPTCFG_RTW88_DEBUGFS */ + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -2300,6 +2300,7 @@ void rtw_unregister_hw(struct rtw_dev *r + + ieee80211_unregister_hw(hw); + rtw_unset_supported_band(hw, chip); ++ rtw_debugfs_deinit(rtwdev); + } + EXPORT_SYMBOL(rtw_unregister_hw); + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -50,6 +50,7 @@ extern const struct ieee80211_ops rtw_op + #define RTW_MAX_CHANNEL_NUM_5G 49 + + struct rtw_dev; ++struct rtw_debugfs; + + enum rtw_hci_type { + RTW_HCI_TYPE_PCIE, +@@ -2053,7 +2054,7 @@ struct rtw_dev { + bool beacon_loss; + struct completion lps_leave_check; + +- struct dentry *debugfs; ++ struct rtw_debugfs *debugfs; + + u8 sta_cnt; + u32 rts_threshold; diff --git a/package/kernel/mac80211/patches/rtl/005-v6.12-wifi-rtw88-select-WANT_DEV_COREDUMP.patch b/package/kernel/mac80211/patches/rtl/005-v6.12-wifi-rtw88-select-WANT_DEV_COREDUMP.patch new file mode 100644 index 00000000000000..6c31b5e848f2f3 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/005-v6.12-wifi-rtw88-select-WANT_DEV_COREDUMP.patch @@ -0,0 +1,25 @@ +From 7e989b0c1e33210c07340bf5228aa83ea52515b5 Mon Sep 17 00:00:00 2001 +From: Zong-Zhe Yang +Date: Thu, 18 Jul 2024 15:06:15 +0800 +Subject: [PATCH] wifi: rtw88: select WANT_DEV_COREDUMP + +We have invoked device coredump when fw crash. +Should select WANT_DEV_COREDUMP by ourselves. + +Signed-off-by: Zong-Zhe Yang +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240718070616.42217-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -14,6 +14,7 @@ if RTW88 + config RTW88_CORE + tristate + depends on m ++ select BPAUTO_WANT_DEV_COREDUMP + + config RTW88_PCI + tristate diff --git a/package/kernel/mac80211/patches/rtl/008-v6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch b/package/kernel/mac80211/patches/rtl/008-v6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch new file mode 100644 index 00000000000000..a304cd7d0504c2 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/008-v6.12-wifi-rtw88-8822c-Parse-channel-from-IE-to-correct-in.patch @@ -0,0 +1,151 @@ +From 53ed4b25a79aeec5991c2dc579e635b136ef7676 Mon Sep 17 00:00:00 2001 +From: Po-Hao Huang +Date: Wed, 24 Jul 2024 13:05:01 +0800 +Subject: [PATCH] wifi: rtw88: 8822c: Parse channel from IE to correct invalid + hardware reports + +For CCK packets we could get incorrect reports from hardware. +And this causes wrong frequencies being reported. Parse the channel +information from IE if provided by AP to fix this. + +Signed-off-by: Po-Hao Huang +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240724050501.7550-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/pci.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 7 ++-- + drivers/net/wireless/realtek/rtw88/rx.c | 41 +++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rx.h | 13 ++++++ + drivers/net/wireless/realtek/rtw88/sdio.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 2 + + 7 files changed, 63 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -623,6 +623,7 @@ struct rtw_rx_pkt_stat { + bool crc_err; + bool decrypted; + bool is_c2h; ++ bool channel_invalid; + + s32 signal_power; + u16 pkt_len; +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -1088,6 +1088,7 @@ static u32 rtw_pci_rx_napi(struct rtw_de + /* remove rx_desc */ + skb_pull(new, pkt_offset); + ++ rtw_update_rx_freq_for_invalid(rtwdev, new, &rx_status, &pkt_stat); + rtw_rx_stats(rtwdev, pkt_stat.vif, new); + memcpy(new->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_napi(rtwdev->hw, NULL, new, napi); +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2576,9 +2576,10 @@ static void query_phy_status_page0(struc + rx_power[RF_PATH_B] -= 110; + + channel = GET_PHY_STAT_P0_CHANNEL(phy_status); +- if (channel == 0) +- channel = rtwdev->hal.current_channel; +- rtw_set_rx_freq_band(pkt_stat, channel); ++ if (channel != 0) ++ rtw_set_rx_freq_band(pkt_stat, channel); ++ else ++ pkt_stat->channel_invalid = true; + + pkt_stat->rx_power[RF_PATH_A] = rx_power[RF_PATH_A]; + pkt_stat->rx_power[RF_PATH_B] = rx_power[RF_PATH_B]; +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/rx.c +@@ -146,6 +146,47 @@ static void rtw_set_rx_freq_by_pktstat(s + rx_status->band = pkt_stat->band; + } + ++void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, ++ struct ieee80211_rx_status *rx_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; ++ int channel = rtwdev->hal.current_channel; ++ size_t hdr_len, ielen; ++ int channel_number; ++ u8 *variable; ++ ++ if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags)) ++ goto fill_rx_status; ++ ++ if (ieee80211_is_beacon(mgmt->frame_control)) { ++ variable = mgmt->u.beacon.variable; ++ hdr_len = offsetof(struct ieee80211_mgmt, ++ u.beacon.variable); ++ } else if (ieee80211_is_probe_resp(mgmt->frame_control)) { ++ variable = mgmt->u.probe_resp.variable; ++ hdr_len = offsetof(struct ieee80211_mgmt, ++ u.probe_resp.variable); ++ } else { ++ goto fill_rx_status; ++ } ++ ++ if (skb->len > hdr_len) ++ ielen = skb->len - hdr_len; ++ else ++ goto fill_rx_status; ++ ++ channel_number = cfg80211_get_ies_channel_number(variable, ielen, ++ NL80211_BAND_2GHZ); ++ if (channel_number != -1) ++ channel = channel_number; ++ ++fill_rx_status: ++ rtw_set_rx_freq_band(pkt_stat, channel); ++ rtw_set_rx_freq_by_pktstat(pkt_stat, rx_status); ++} ++EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); ++ + void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, + struct rtw_rx_pkt_stat *pkt_stat, + struct ieee80211_hdr *hdr, +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/rx.h +@@ -50,5 +50,18 @@ void rtw_rx_fill_rx_status(struct rtw_de + struct ieee80211_hdr *hdr, + struct ieee80211_rx_status *rx_status, + u8 *phy_status); ++void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, ++ struct ieee80211_rx_status *rx_status, ++ struct rtw_rx_pkt_stat *pkt_stat); ++ ++static inline ++void rtw_update_rx_freq_for_invalid(struct rtw_dev *rtwdev, struct sk_buff *skb, ++ struct ieee80211_rx_status *rx_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ if (pkt_stat->channel_invalid) ++ rtw_update_rx_freq_from_ie(rtwdev, skb, rx_status, pkt_stat); ++} ++ + + #endif +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -948,6 +948,7 @@ static void rtw_sdio_rx_skb(struct rtw_d + skb_put(skb, pkt_stat->pkt_len); + skb_reserve(skb, pkt_offset); + ++ rtw_update_rx_freq_for_invalid(rtwdev, skb, rx_status, pkt_stat); + rtw_rx_stats(rtwdev, pkt_stat->vif, skb); + + ieee80211_rx_irqsafe(rtwdev->hw, skb); +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -579,6 +579,8 @@ static void rtw_usb_rx_handler(struct wo + + skb_put(skb, pkt_stat.pkt_len); + skb_reserve(skb, pkt_offset); ++ ++ rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat); + memcpy(skb->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(rtwdev->hw, skb); + } diff --git a/package/kernel/mac80211/patches/rtl/010-v6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch b/package/kernel/mac80211/patches/rtl/010-v6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch new file mode 100644 index 00000000000000..191c87ff37adc5 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/010-v6.12-wifi-rtw88-usb-Init-RX-burst-length-according-to-USB.patch @@ -0,0 +1,73 @@ +From fbbd8cb347e25b68d25c4f3871821afc495ee7a9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:19:36 +0300 +Subject: [PATCH] wifi: rtw88: usb: Init RX burst length according to USB speed + +This is needed in order to make USB RX aggregation work with RTL8811CU +(and presumably RTL8822BU and RTL8822CU also). + +I don't know what BIT_DMA_BURST_CNT, BIT_DMA_MODE, and BIT_DROP_DATA_EN +are doing. + +Tested with RTL8822CU, RTL8811CU, and RTL8723DU. + +The RX speed is unchanged in my tests. + +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/ac569c6f-7129-4341-b523-901fe10cabff@gmail.com +--- + drivers/net/wireless/realtek/rtw88/reg.h | 6 ++++++ + drivers/net/wireless/realtek/rtw88/usb.c | 23 ++++++++++++++++++++++- + 2 files changed, 28 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -322,6 +322,12 @@ + #define REG_RXDMA_DPR 0x028C + #define REG_RXDMA_MODE 0x0290 + #define BIT_DMA_MODE BIT(1) ++#define BIT_DMA_BURST_CNT GENMASK(3, 2) ++#define BIT_DMA_BURST_SIZE GENMASK(5, 4) ++#define BIT_DMA_BURST_SIZE_64 2 ++#define BIT_DMA_BURST_SIZE_512 1 ++#define BIT_DMA_BURST_SIZE_1024 0 ++ + #define REG_RXPKTNUM 0x02B0 + + #define REG_INT_MIG 0x0304 +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -720,9 +720,30 @@ static void rtw_usb_link_ps(struct rtw_d + /* empty function for rtw_hci_ops */ + } + ++static void rtw_usb_init_burst_pkt_len(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ enum usb_device_speed speed = rtwusb->udev->speed; ++ u8 rxdma, burst_size; ++ ++ rxdma = BIT_DMA_BURST_CNT | BIT_DMA_MODE; ++ ++ if (speed == USB_SPEED_SUPER) ++ burst_size = BIT_DMA_BURST_SIZE_1024; ++ else if (speed == USB_SPEED_HIGH) ++ burst_size = BIT_DMA_BURST_SIZE_512; ++ else ++ burst_size = BIT_DMA_BURST_SIZE_64; ++ ++ u8p_replace_bits(&rxdma, burst_size, BIT_DMA_BURST_SIZE); ++ ++ rtw_write8(rtwdev, REG_RXDMA_MODE, rxdma); ++ rtw_write16_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); ++} ++ + static void rtw_usb_interface_cfg(struct rtw_dev *rtwdev) + { +- /* empty function for rtw_hci_ops */ ++ rtw_usb_init_burst_pkt_len(rtwdev); + } + + static struct rtw_hci_ops rtw_usb_ops = { diff --git a/package/kernel/mac80211/patches/rtl/011-v6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch b/package/kernel/mac80211/patches/rtl/011-v6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch new file mode 100644 index 00000000000000..f78f43b4647d10 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/011-v6.12-wifi-rtw88-usb-Update-the-RX-stats-after-every-frame.patch @@ -0,0 +1,31 @@ +From 38ea04a79ad0f8cc30bb5e9ad98d665e4ae5060c Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:20:36 +0300 +Subject: [PATCH] wifi: rtw88: usb: Update the RX stats after every frame + +Update the number of received unicast data frames and bytes every time +a frame is received. This is what the PCI and SDIO drivers do. + +This has an influence on the power saving, bluetooth coexistence, and +(in a future patch) the use of RX aggregation. + +Tested with RTL8822CU, RTL8811CU, and RTL8723DU. + +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/75a2ca52-8f01-45c5-926f-d3a68ae3b284@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -581,6 +581,7 @@ static void rtw_usb_rx_handler(struct wo + skb_reserve(skb, pkt_offset); + + rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat); ++ rtw_rx_stats(rtwdev, pkt_stat.vif, skb); + memcpy(skb->cb, &rx_status, sizeof(rx_status)); + ieee80211_rx_irqsafe(rtwdev->hw, skb); + } diff --git a/package/kernel/mac80211/patches/rtl/012-v6.12-wifi-rtw88-usb-Support-RX-aggregation.patch b/package/kernel/mac80211/patches/rtl/012-v6.12-wifi-rtw88-usb-Support-RX-aggregation.patch new file mode 100644 index 00000000000000..bc8eac898b24b0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/012-v6.12-wifi-rtw88-usb-Support-RX-aggregation.patch @@ -0,0 +1,118 @@ +From df3d8f463b1dfc7cb8f4fb52b1b81d290b850d03 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:21:36 +0300 +Subject: [PATCH] wifi: rtw88: usb: Support RX aggregation + +The chips can be configured to aggregate several frames into a single +USB transfer. Modify rtw_usb_rx_handler() to support this case. + +RX aggregation improves the RX speed of RTL8811CU on certain ARM +systems, like the NanoPi NEO Core2. It also improves the RX speed of +RTL8822CU on some x86_64 systems. + +Currently none of the chips are configured to aggregate frames. + +Tested with RTL8822CU, RTL8811CU, and RTL8723DU. + +Reviewed-by: Sascha Hauer +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f845826d-de71-492d-9a22-e48c07989a1f@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 61 ++++++++++++++++-------- + 1 file changed, 40 insertions(+), 21 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -546,11 +546,12 @@ static void rtw_usb_rx_handler(struct wo + struct rtw_usb *rtwusb = container_of(work, struct rtw_usb, rx_work); + struct rtw_dev *rtwdev = rtwusb->rtwdev; + const struct rtw_chip_info *chip = rtwdev->chip; +- struct rtw_rx_pkt_stat pkt_stat; ++ u32 pkt_desc_sz = chip->rx_pkt_desc_sz; + struct ieee80211_rx_status rx_status; ++ u32 pkt_offset, next_pkt, urb_len; ++ struct rtw_rx_pkt_stat pkt_stat; ++ struct sk_buff *next_skb; + struct sk_buff *skb; +- u32 pkt_desc_sz = chip->rx_pkt_desc_sz; +- u32 pkt_offset; + u8 *rx_desc; + int limit; + +@@ -559,31 +560,48 @@ static void rtw_usb_rx_handler(struct wo + if (!skb) + break; + +- rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); +- pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + +- pkt_stat.shift; +- +- if (pkt_stat.is_c2h) { +- skb_put(skb, pkt_stat.pkt_len + pkt_offset); +- rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); +- continue; +- } +- + if (skb_queue_len(&rtwusb->rx_queue) >= RTW_USB_MAX_RXQ_LEN) { + dev_dbg_ratelimited(rtwdev->dev, "failed to get rx_queue, overflow\n"); + dev_kfree_skb_any(skb); + continue; + } + +- skb_put(skb, pkt_stat.pkt_len); +- skb_reserve(skb, pkt_offset); ++ urb_len = skb->len; ++ ++ do { ++ rx_desc = skb->data; ++ chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, ++ &rx_status); ++ pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + ++ pkt_stat.shift; ++ ++ next_pkt = round_up(pkt_stat.pkt_len + pkt_offset, 8); ++ ++ if (urb_len >= next_pkt + pkt_desc_sz) ++ next_skb = skb_clone(skb, GFP_KERNEL); ++ else ++ next_skb = NULL; ++ ++ if (pkt_stat.is_c2h) { ++ skb_trim(skb, pkt_stat.pkt_len + pkt_offset); ++ rtw_fw_c2h_cmd_rx_irqsafe(rtwdev, pkt_offset, skb); ++ } else { ++ skb_pull(skb, pkt_offset); ++ skb_trim(skb, pkt_stat.pkt_len); ++ rtw_update_rx_freq_for_invalid(rtwdev, skb, ++ &rx_status, ++ &pkt_stat); ++ rtw_rx_stats(rtwdev, pkt_stat.vif, skb); ++ memcpy(skb->cb, &rx_status, sizeof(rx_status)); ++ ieee80211_rx_irqsafe(rtwdev->hw, skb); ++ } ++ ++ skb = next_skb; ++ if (skb) ++ skb_pull(skb, next_pkt); + +- rtw_update_rx_freq_for_invalid(rtwdev, skb, &rx_status, &pkt_stat); +- rtw_rx_stats(rtwdev, pkt_stat.vif, skb); +- memcpy(skb->cb, &rx_status, sizeof(rx_status)); +- ieee80211_rx_irqsafe(rtwdev->hw, skb); ++ urb_len -= next_pkt; ++ } while (skb); + } + } + +@@ -627,6 +645,7 @@ static void rtw_usb_read_port_complete(s + if (skb) + dev_kfree_skb_any(skb); + } else { ++ skb_put(skb, urb->actual_length); + skb_queue_tail(&rtwusb->rx_queue, skb); + queue_work(rtwusb->rxwq, &rtwusb->rx_work); + } diff --git a/package/kernel/mac80211/patches/rtl/013-v6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch b/package/kernel/mac80211/patches/rtl/013-v6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch new file mode 100644 index 00000000000000..71175324e6da6b --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/013-v6.12-wifi-rtw88-Enable-USB-RX-aggregation-for-8822c-8822b.patch @@ -0,0 +1,168 @@ +From 002a5db9a52a0e7af0fa9a450d31049748435748 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Thu, 8 Aug 2024 01:23:06 +0300 +Subject: [PATCH] wifi: rtw88: Enable USB RX aggregation for 8822c/8822b/8821c + +Enable USB RX aggregation when there is at least 1 Mbps RX or TX +traffic, otherwise disable it. + +USB RX aggregation improves the RX speed of RTL8811CU on certain ARM +systems, like the NanoPi NEO Core2. Before: 28 Mbps, after: 231 Mbps. + +It also improves the RX speed of RTL8822CU on some x86_64 systems. +Before: ~200 Mbps, after: ~300 Mbps. + +The official drivers for these chips use the same logic for SDIO, but +for some reason the SDIO driver in rtw88 always enables RX aggregation, +so this patch only toggles aggregation for USB devices. + +RTL8703B is likely not found in USB devices, and RTL8723DU doesn't like +aggregation. + +Tested-by: Sascha Hauer +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/b4c0d54c-6755-4b0f-9dd7-f9196fd74b68@gmail.com +--- + drivers/net/wireless/realtek/rtw88/hci.h | 7 ++++ + drivers/net/wireless/realtek/rtw88/main.c | 13 +++++--- + drivers/net/wireless/realtek/rtw88/pci.c | 1 + + drivers/net/wireless/realtek/rtw88/sdio.c | 1 + + drivers/net/wireless/realtek/rtw88/usb.c | 40 +++++++++++++++++++++++ + 5 files changed, 58 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/hci.h ++++ b/drivers/net/wireless/realtek/rtw88/hci.h +@@ -18,6 +18,7 @@ struct rtw_hci_ops { + void (*deep_ps)(struct rtw_dev *rtwdev, bool enter); + void (*link_ps)(struct rtw_dev *rtwdev, bool enter); + void (*interface_cfg)(struct rtw_dev *rtwdev); ++ void (*dynamic_rx_agg)(struct rtw_dev *rtwdev, bool enable); + + int (*write_data_rsvd_page)(struct rtw_dev *rtwdev, u8 *buf, u32 size); + int (*write_data_h2c)(struct rtw_dev *rtwdev, u8 *buf, u32 size); +@@ -72,6 +73,12 @@ static inline void rtw_hci_interface_cfg + rtwdev->hci.ops->interface_cfg(rtwdev); + } + ++static inline void rtw_hci_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) ++{ ++ if (rtwdev->hci.ops->dynamic_rx_agg) ++ rtwdev->hci.ops->dynamic_rx_agg(rtwdev, enable); ++} ++ + static inline int + rtw_hci_write_data_rsvd_page(struct rtw_dev *rtwdev, u8 *buf, u32 size) + { +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -212,6 +212,7 @@ static void rtw_watch_dog_work(struct wo + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_watch_dog_iter_data data = {}; + bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); ++ u32 tx_unicast_mbps, rx_unicast_mbps; + bool ps_active; + + mutex_lock(&rtwdev->mutex); +@@ -236,10 +237,11 @@ static void rtw_watch_dog_work(struct wo + else + ps_active = false; + +- ewma_tp_add(&stats->tx_ewma_tp, +- (u32)(stats->tx_unicast >> RTW_TP_SHIFT)); +- ewma_tp_add(&stats->rx_ewma_tp, +- (u32)(stats->rx_unicast >> RTW_TP_SHIFT)); ++ tx_unicast_mbps = stats->tx_unicast >> RTW_TP_SHIFT; ++ rx_unicast_mbps = stats->rx_unicast >> RTW_TP_SHIFT; ++ ++ ewma_tp_add(&stats->tx_ewma_tp, tx_unicast_mbps); ++ ewma_tp_add(&stats->rx_ewma_tp, rx_unicast_mbps); + stats->tx_throughput = ewma_tp_read(&stats->tx_ewma_tp); + stats->rx_throughput = ewma_tp_read(&stats->rx_ewma_tp); + +@@ -259,6 +261,9 @@ static void rtw_watch_dog_work(struct wo + + rtw_phy_dynamic_mechanism(rtwdev); + ++ rtw_hci_dynamic_rx_agg(rtwdev, ++ tx_unicast_mbps >= 1 || rx_unicast_mbps >= 1); ++ + data.rtwdev = rtwdev; + /* rtw_iterate_vifs internally uses an atomic iterator which is needed + * to avoid taking local->iflist_mtx mutex +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -1601,6 +1601,7 @@ static struct rtw_hci_ops rtw_pci_ops = + .deep_ps = rtw_pci_deep_ps, + .link_ps = rtw_pci_link_ps, + .interface_cfg = rtw_pci_interface_cfg, ++ .dynamic_rx_agg = NULL, + + .read8 = rtw_pci_read8, + .read16 = rtw_pci_read16, +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -1157,6 +1157,7 @@ static struct rtw_hci_ops rtw_sdio_ops = + .deep_ps = rtw_sdio_deep_ps, + .link_ps = rtw_sdio_link_ps, + .interface_cfg = rtw_sdio_interface_cfg, ++ .dynamic_rx_agg = NULL, + + .read8 = rtw_sdio_read8, + .read16 = rtw_sdio_read16, +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -766,6 +766,45 @@ static void rtw_usb_interface_cfg(struct + rtw_usb_init_burst_pkt_len(rtwdev); + } + ++static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable) ++{ ++ u8 size, timeout; ++ u16 val16; ++ ++ rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); ++ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); ++ rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); ++ ++ if (enable) { ++ size = 0x5; ++ timeout = 0x20; ++ } else { ++ size = 0x0; ++ timeout = 0x1; ++ } ++ val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | ++ u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); ++ ++ rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); ++} ++ ++static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) ++{ ++ switch (rtwdev->chip->id) { ++ case RTW_CHIP_TYPE_8822C: ++ case RTW_CHIP_TYPE_8822B: ++ case RTW_CHIP_TYPE_8821C: ++ rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); ++ break; ++ case RTW_CHIP_TYPE_8723D: ++ /* Doesn't like aggregation. */ ++ break; ++ case RTW_CHIP_TYPE_8703B: ++ /* Likely not found in USB devices. */ ++ break; ++ } ++} ++ + static struct rtw_hci_ops rtw_usb_ops = { + .tx_write = rtw_usb_tx_write, + .tx_kick_off = rtw_usb_tx_kick_off, +@@ -775,6 +814,7 @@ static struct rtw_hci_ops rtw_usb_ops = + .deep_ps = rtw_usb_deep_ps, + .link_ps = rtw_usb_link_ps, + .interface_cfg = rtw_usb_interface_cfg, ++ .dynamic_rx_agg = rtw_usb_dynamic_rx_agg, + + .write8 = rtw_usb_write8, + .write16 = rtw_usb_write16, diff --git a/package/kernel/mac80211/patches/rtl/016-v6.12-wifi-rtw88-assign-mac_id-for-vif-sta-and-update-to-T.patch b/package/kernel/mac80211/patches/rtl/016-v6.12-wifi-rtw88-assign-mac_id-for-vif-sta-and-update-to-T.patch new file mode 100644 index 00000000000000..ce110c5c90c1a0 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/016-v6.12-wifi-rtw88-assign-mac_id-for-vif-sta-and-update-to-T.patch @@ -0,0 +1,231 @@ +From 902cb7b11f9a7ff07233cc4c626b54c3e4703149 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Mon, 19 Aug 2024 10:52:48 +0800 +Subject: [PATCH] wifi: rtw88: assign mac_id for vif/sta and update to TX desc + +A mac_id as an instance in firmware has to be assigned for each station +including AP and connected stations. Firmware will use the mac_id to +control TX rate and do statistics. + +Assignment rule is to assign mac_id to each vif when adding vif. +For station mode, sta->mac_id will reuse vif->mac_id. For AP mode, +dynamically allocate an sta->mac_id to a station, and vif->mac_id is +used to send broadcast/multicast packets which are not belong to +a station. For example, + + vif->mac_id sta->mac_id +vif0 (STA mode) 0 0 +vif1 (AP mode) 1 2... + +By the way, remove unused RTW_BC_MC_MACID, which was planed to send +broadcast/multicast packets on fixed mac_id. + +Tested-on RTL8822CE with STA + AP SCC mode. + +Link: https://lore.kernel.org/linux-wireless/e4be0a75-43b2-4ae5-9aab-5c4a88e78097@gmail.com/ +Cc: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20240819025248.17939-1-pkshih@realtek.com +--- + drivers/net/wireless/realtek/rtw88/mac80211.c | 13 ++++++-- + drivers/net/wireless/realtek/rtw88/main.c | 30 ++++++++----------- + drivers/net/wireless/realtek/rtw88/main.h | 14 +++++++-- + drivers/net/wireless/realtek/rtw88/tx.c | 11 +++++-- + drivers/net/wireless/realtek/rtw88/tx.h | 1 + + 5 files changed, 44 insertions(+), 25 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c +@@ -167,6 +167,12 @@ static int rtw_ops_add_interface(struct + + mutex_lock(&rtwdev->mutex); + ++ rtwvif->mac_id = rtw_acquire_macid(rtwdev); ++ if (rtwvif->mac_id >= RTW_MAX_MAC_ID_NUM) { ++ mutex_unlock(&rtwdev->mutex); ++ return -ENOSPC; ++ } ++ + port = find_first_zero_bit(rtwdev->hw_port, RTW_PORT_NUM); + if (port >= RTW_PORT_NUM) { + mutex_unlock(&rtwdev->mutex); +@@ -214,7 +220,8 @@ static int rtw_ops_add_interface(struct + + mutex_unlock(&rtwdev->mutex); + +- rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port); ++ rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM mac_id %d on port %d\n", ++ vif->addr, rtwvif->mac_id, rtwvif->port); + return 0; + } + +@@ -225,7 +232,8 @@ static void rtw_ops_remove_interface(str + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + u32 config = 0; + +- rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port); ++ rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM mac_id %d on port %d\n", ++ vif->addr, rtwvif->mac_id, rtwvif->port); + + mutex_lock(&rtwdev->mutex); + +@@ -242,6 +250,7 @@ static void rtw_ops_remove_interface(str + config |= PORT_SET_BCN_CTRL; + rtw_vif_port_config(rtwdev, rtwvif, config); + clear_bit(rtwvif->port, rtwdev->hw_port); ++ rtw_release_macid(rtwdev, rtwvif->mac_id); + rtw_recalc_lps(rtwdev, NULL); + + mutex_unlock(&rtwdev->mutex); +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -311,17 +311,6 @@ static void rtw_ips_work(struct work_str + mutex_unlock(&rtwdev->mutex); + } + +-static u8 rtw_acquire_macid(struct rtw_dev *rtwdev) +-{ +- unsigned long mac_id; +- +- mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); +- if (mac_id < RTW_MAX_MAC_ID_NUM) +- set_bit(mac_id, rtwdev->mac_id_map); +- +- return mac_id; +-} +- + static void rtw_sta_rc_work(struct work_struct *work) + { + struct rtw_sta_info *si = container_of(work, struct rtw_sta_info, +@@ -340,12 +329,14 @@ int rtw_sta_add(struct rtw_dev *rtwdev, + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv; + int i; + +- si->mac_id = rtw_acquire_macid(rtwdev); +- if (si->mac_id >= RTW_MAX_MAC_ID_NUM) +- return -ENOSPC; ++ if (vif->type == NL80211_IFTYPE_STATION) { ++ si->mac_id = rtwvif->mac_id; ++ } else { ++ si->mac_id = rtw_acquire_macid(rtwdev); ++ if (si->mac_id >= RTW_MAX_MAC_ID_NUM) ++ return -ENOSPC; ++ } + +- if (vif->type == NL80211_IFTYPE_STATION && vif->cfg.assoc == 0) +- rtwvif->mac_id = si->mac_id; + si->rtwdev = rtwdev; + si->sta = sta; + si->vif = vif; +@@ -370,11 +361,13 @@ void rtw_sta_remove(struct rtw_dev *rtwd + bool fw_exist) + { + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; ++ struct ieee80211_vif *vif = si->vif; + int i; + + cancel_work_sync(&si->rc_work); + +- rtw_release_macid(rtwdev, si->mac_id); ++ if (vif->type != NL80211_IFTYPE_STATION) ++ rtw_release_macid(rtwdev, si->mac_id); + if (fw_exist) + rtw_fw_media_status_report(rtwdev, si->mac_id, false); + +@@ -614,6 +607,8 @@ static void rtw_reset_vif_iter(void *dat + rtw_bf_disassoc(rtwdev, vif, NULL); + rtw_vif_assoc_changed(rtwvif, NULL); + rtw_txq_cleanup(rtwdev, vif->txq); ++ ++ rtw_release_macid(rtwdev, rtwvif->mac_id); + } + + void rtw_fw_recovery(struct rtw_dev *rtwdev) +@@ -2139,7 +2134,6 @@ int rtw_core_init(struct rtw_dev *rtwdev + rtwdev->sec.total_cam_num = 32; + rtwdev->hal.current_channel = 1; + rtwdev->dm_info.fix_rate = U8_MAX; +- set_bit(RTW_BC_MC_MACID, rtwdev->mac_id_map); + + rtw_stats_init(rtwdev); + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -742,7 +742,6 @@ struct rtw_txq { + unsigned long flags; + }; + +-#define RTW_BC_MC_MACID 1 + DECLARE_EWMA(rssi, 10, 16); + + struct rtw_sta_info { +@@ -805,7 +804,7 @@ struct rtw_bf_info { + struct rtw_vif { + enum rtw_net_type net_type; + u16 aid; +- u8 mac_id; /* for STA mode only */ ++ u8 mac_id; + u8 mac_addr[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 port; +@@ -2131,6 +2130,17 @@ static inline bool rtw_chip_has_tx_stbc( + return rtwdev->chip->tx_stbc; + } + ++static inline u8 rtw_acquire_macid(struct rtw_dev *rtwdev) ++{ ++ unsigned long mac_id; ++ ++ mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM); ++ if (mac_id < RTW_MAX_MAC_ID_NUM) ++ set_bit(mac_id, rtwdev->mac_id_map); ++ ++ return mac_id; ++} ++ + static inline void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id) + { + clear_bit(mac_id, rtwdev->mac_id_map); +--- a/drivers/net/wireless/realtek/rtw88/tx.c ++++ b/drivers/net/wireless/realtek/rtw88/tx.c +@@ -46,7 +46,8 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p + le32_encode_bits(pkt_info->ls, RTW_TX_DESC_W0_LS) | + le32_encode_bits(pkt_info->dis_qselseq, RTW_TX_DESC_W0_DISQSELSEQ); + +- tx_desc->w1 = le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | ++ tx_desc->w1 = le32_encode_bits(pkt_info->mac_id, RTW_TX_DESC_W1_MACID) | ++ le32_encode_bits(pkt_info->qsel, RTW_TX_DESC_W1_QSEL) | + le32_encode_bits(pkt_info->rate_id, RTW_TX_DESC_W1_RATE_ID) | + le32_encode_bits(pkt_info->sec_type, RTW_TX_DESC_W1_SEC_TYPE) | + le32_encode_bits(pkt_info->pkt_offset, RTW_TX_DESC_W1_PKT_OFFSET) | +@@ -401,14 +402,18 @@ void rtw_tx_pkt_info_update(struct rtw_d + const struct rtw_chip_info *chip = rtwdev->chip; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; ++ struct ieee80211_vif *vif = info->control.vif; + struct rtw_sta_info *si; +- struct ieee80211_vif *vif = NULL; ++ struct rtw_vif *rtwvif; + __le16 fc = hdr->frame_control; + bool bmc; + + if (sta) { + si = (struct rtw_sta_info *)sta->drv_priv; +- vif = si->vif; ++ pkt_info->mac_id = si->mac_id; ++ } else if (vif) { ++ rtwvif = (struct rtw_vif *)vif->drv_priv; ++ pkt_info->mac_id = rtwvif->mac_id; + } + + if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc)) +--- a/drivers/net/wireless/realtek/rtw88/tx.h ++++ b/drivers/net/wireless/realtek/rtw88/tx.h +@@ -27,6 +27,7 @@ struct rtw_tx_desc { + #define RTW_TX_DESC_W0_BMC BIT(24) + #define RTW_TX_DESC_W0_LS BIT(26) + #define RTW_TX_DESC_W0_DISQSELSEQ BIT(31) ++#define RTW_TX_DESC_W1_MACID GENMASK(7, 0) + #define RTW_TX_DESC_W1_QSEL GENMASK(12, 8) + #define RTW_TX_DESC_W1_RATE_ID GENMASK(20, 16) + #define RTW_TX_DESC_W1_SEC_TYPE GENMASK(23, 22) diff --git a/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch b/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch new file mode 100644 index 00000000000000..8d2bb9aa7a918c --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/017-v6.13-wifi-rtw88-Constify-some-arrays-and-structs.patch @@ -0,0 +1,374 @@ +From 140403599b74839b0a57c5397b7e8579e5332364 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 18 Sep 2024 01:53:55 +0300 +Subject: [PATCH] wifi: rtw88: Constify some arrays and structs + +These are never modified, so make them const: + +card_enable_flow_8703b +card_disable_flow_8703b +rtw8703b_ops + +rtw8723d_ops +card_enable_flow_8723d +card_disable_flow_8723d + +trans_carddis_to_cardemu_8821c +trans_cardemu_to_act_8821c +trans_act_to_cardemu_8821c +trans_cardemu_to_carddis_8821c +card_enable_flow_8821c +card_disable_flow_8821c +rtw8821c_dig +page_table_8821c +rqpn_table_8821c +prioq_addrs_8821c +rtw8821c_ops + +card_enable_flow_8822b +card_disable_flow_8822b +prioq_addrs_8822b +rtw8822b_ops +rtw8822b_edcca_th + +card_enable_flow_8822c +card_disable_flow_8822c +prioq_addrs_8822c +rtw8822c_ops +rtw8822c_edcca_th + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/dae7994f-3491-40de-b537-ebf68df084bb@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/mac.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/main.h | 8 +++---- + drivers/net/wireless/realtek/rtw88/phy.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 6 ++--- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 22 +++++++++---------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 10 ++++----- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 10 ++++----- + 9 files changed, 35 insertions(+), 35 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -267,7 +267,7 @@ static void rtw_fw_scan_result(struct rt + static void rtw_fw_adaptivity_result(struct rtw_dev *rtwdev, u8 *payload, + u8 length) + { +- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + struct rtw_c2h_adaptivity *result = (struct rtw_c2h_adaptivity *)payload; + + rtw_dbg(rtwdev, RTW_DBG_ADAPTIVITY, +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -228,7 +228,7 @@ static int rtw_sub_pwr_seq_parser(struct + } + + static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, +- const struct rtw_pwr_seq_cmd **cmd_seq) ++ const struct rtw_pwr_seq_cmd * const *cmd_seq) + { + u8 cut_mask; + u8 intf_mask; +@@ -271,7 +271,7 @@ static int rtw_pwr_seq_parser(struct rtw + static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + { + const struct rtw_chip_info *chip = rtwdev->chip; +- const struct rtw_pwr_seq_cmd **pwr_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_seq; + u32 imr = 0; + u8 rpwm; + bool cur_pwr; +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1167,7 +1167,7 @@ enum rtw_fwcd_item { + + /* hardware configuration for each IC */ + struct rtw_chip_info { +- struct rtw_chip_ops *ops; ++ const struct rtw_chip_ops *ops; + u8 id; + + const char *fw_name; +@@ -1209,8 +1209,8 @@ struct rtw_chip_info { + + /* init values */ + u8 sys_func_en; +- const struct rtw_pwr_seq_cmd **pwr_on_seq; +- const struct rtw_pwr_seq_cmd **pwr_off_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_on_seq; ++ const struct rtw_pwr_seq_cmd * const *pwr_off_seq; + const struct rtw_rqpn *rqpn_table; + const struct rtw_prioq_addrs *prioq_addrs; + const struct rtw_page_table *page_table; +@@ -1242,7 +1242,7 @@ struct rtw_chip_info { + u8 bfer_su_max_num; + u8 bfer_mu_max_num; + +- struct rtw_hw_reg_offset *edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th; + s8 l2h_th_ini_cs; + s8 l2h_th_ini_ad; + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -123,7 +123,7 @@ static void rtw_phy_cck_pd_init(struct r + + void rtw_phy_set_edcca_th(struct rtw_dev *rtwdev, u8 l2h, u8 h2l) + { +- struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; ++ const struct rtw_hw_reg_offset *edcca_th = rtwdev->chip->edcca_th; + + rtw_write32_mask(rtwdev, + edcca_th[EDCCA_TH_L2H_IDX].hw_reg.addr, +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -481,14 +481,14 @@ static const struct rtw_pwr_seq_cmd tran + {TRANS_SEQ_END}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8703b[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8703b[] = { + trans_pre_enable_8703b, + trans_carddis_to_cardemu_8703b, + trans_cardemu_to_act_8703b, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8703b[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8703b[] = { + trans_act_to_lps_8703b, + trans_act_to_reset_mcu_8703b, + trans_act_to_cardemu_8703b, +@@ -1941,7 +1941,7 @@ static const struct coex_tdma_para tdma_ + { {0x61, 0x08, 0x03, 0x11, 0x11} }, + }; + +-static struct rtw_chip_ops rtw8703b_ops = { ++static const struct rtw_chip_ops rtw8703b_ops = { + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -1430,7 +1430,7 @@ static void rtw8723d_pwr_track(struct rt + dm_info->pwr_trk_triggered = false; + } + +-static struct rtw_chip_ops rtw8723d_ops = { ++static const struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_rx_desc = rtw8723d_query_rx_desc, +@@ -1788,7 +1788,7 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8723d[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8723d[] = { + trans_carddis_to_cardemu_8723d, + trans_cardemu_to_act_8723d, + NULL +@@ -2004,7 +2004,7 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8723d[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8723d[] = { + trans_act_to_lps_8723d, + trans_act_to_pre_carddis_8723d, + trans_act_to_cardemu_8723d, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1254,7 +1254,7 @@ static void rtw8821c_fill_txdesc_checksu + fill_txdesc_checksum_common(txdesc, 16); + } + +-static struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821c[] = { + {0x0086, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_SDIO_MSK, +@@ -1292,7 +1292,7 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821c[] = { + {0x0020, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, +@@ -1396,7 +1396,7 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821c[] = { + {0x0093, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_ALL_MSK, +@@ -1454,7 +1454,7 @@ static struct rtw_pwr_seq_cmd trans_act_ + RTW_PWR_CMD_END, 0, 0}, + }; + +-static struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821c[] = { + {0x0007, + RTW_PWR_CUT_ALL_MSK, + RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, +@@ -1567,13 +1567,13 @@ static struct rtw_pwr_seq_cmd trans_card + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8821c[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8821c[] = { + trans_carddis_to_cardemu_8821c, + trans_cardemu_to_act_8821c, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8821c[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8821c[] = { + trans_act_to_cardemu_8821c, + trans_cardemu_to_carddis_8821c, + NULL +@@ -1629,7 +1629,7 @@ static const struct rtw_rfe_def rtw8821c + [6] = RTW_DEF_RFE(8821c, 0, 0), + }; + +-static struct rtw_hw_reg rtw8821c_dig[] = { ++static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; + +@@ -1639,7 +1639,7 @@ static const struct rtw_ltecoex_addr rtw + .rdata = LTECOEX_READ_DATA, + }; + +-static struct rtw_page_table page_table_8821c[] = { ++static const struct rtw_page_table page_table_8821c[] = { + /* not sure what [0] stands for */ + {16, 16, 16, 14, 1}, + {16, 16, 16, 14, 1}, +@@ -1648,7 +1648,7 @@ static struct rtw_page_table page_table_ + {16, 16, 16, 14, 1}, + }; + +-static struct rtw_rqpn rqpn_table_8821c[] = { ++static const struct rtw_rqpn rqpn_table_8821c[] = { + /* not sure what [0] stands for */ + {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, + RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, +@@ -1667,7 +1667,7 @@ static struct rtw_rqpn rqpn_table_8821c[ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8821c = { ++static const struct rtw_prioq_addrs prioq_addrs_8821c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -1683,7 +1683,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8821c_ops = { ++static const struct rtw_chip_ops rtw8821c_ops = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_rx_desc = rtw8821c_query_rx_desc, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -1978,13 +1978,13 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822b[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822b[] = { + trans_carddis_to_cardemu_8822b, + trans_cardemu_to_act_8822b, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822b[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822b[] = { + trans_act_to_cardemu_8822b, + trans_cardemu_to_carddis_8822b, + NULL +@@ -2156,7 +2156,7 @@ static const struct rtw_rqpn rqpn_table_ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8822b = { ++static const struct rtw_prioq_addrs prioq_addrs_8822b = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -2172,7 +2172,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8822b_ops = { ++static const struct rtw_chip_ops rtw8822b_ops = { + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_rx_desc = rtw8822b_query_rx_desc, +@@ -2521,7 +2521,7 @@ static const struct rtw_reg_domain coex_ + {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, + }; + +-static struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { ++static const struct rtw_hw_reg_offset rtw8822b_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE0}, .offset = 0}, + [EDCCA_TH_H2L_IDX] = {{.addr = 0x8a4, .mask = MASKBYTE1}, .offset = 0}, + }; +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4874,13 +4874,13 @@ static const struct rtw_pwr_seq_cmd tran + RTW_PWR_CMD_END, 0, 0}, + }; + +-static const struct rtw_pwr_seq_cmd *card_enable_flow_8822c[] = { ++static const struct rtw_pwr_seq_cmd * const card_enable_flow_8822c[] = { + trans_carddis_to_cardemu_8822c, + trans_cardemu_to_act_8822c, + NULL + }; + +-static const struct rtw_pwr_seq_cmd *card_disable_flow_8822c[] = { ++static const struct rtw_pwr_seq_cmd * const card_disable_flow_8822c[] = { + trans_act_to_cardemu_8822c, + trans_cardemu_to_carddis_8822c, + NULL +@@ -4972,7 +4972,7 @@ static const struct rtw_rqpn rqpn_table_ + RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, + }; + +-static struct rtw_prioq_addrs prioq_addrs_8822c = { ++static const struct rtw_prioq_addrs prioq_addrs_8822c = { + .prio[RTW_DMA_MAPPING_EXTRA] = { + .rsvd = REG_FIFOPAGE_INFO_4, .avail = REG_FIFOPAGE_INFO_4 + 2, + }, +@@ -4988,7 +4988,7 @@ static struct rtw_prioq_addrs prioq_addr + .wsize = true, + }; + +-static struct rtw_chip_ops rtw8822c_ops = { ++static const struct rtw_chip_ops rtw8822c_ops = { + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_rx_desc = rtw8822c_query_rx_desc, +@@ -5301,7 +5301,7 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + +-static struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { ++static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 + }, diff --git a/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch new file mode 100644 index 00000000000000..9828f507b643eb --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/019-v6.13-wifi-rtw88-Parse-the-RX-descriptor-with-a-single-fun.patch @@ -0,0 +1,560 @@ +From bbb6f9be7f99464d5ab7e2f321fa728d33eeec9a Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 20 Sep 2024 22:27:30 +0300 +Subject: [PATCH] wifi: rtw88: Parse the RX descriptor with a single function + +rtw8703b_query_rx_desc(), rtw8723d_query_rx_desc(), +rtw8821c_query_rx_desc(), rtw8822b_query_rx_desc(), and +rtw8822c_query_rx_desc() are almost identical, so replace them all with +a single function, rtw_rx_query_rx_desc(). + +Also, access the RX descriptor using a struct with __le32 members and +le32_get_bits(). + +Tested with RTL8811CU, RTL8811AU, and RTL8812AU. + +Signed-off-by: Bitterblue Smith +Tested-by: Ping-Ke Shih # RTL8723DE and RTL8822CE +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/913f1747-38fc-4409-85a4-57bb9cee506b@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 5 +- + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 56 +-------------- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 43 +----------- + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 44 +----------- + drivers/net/wireless/realtek/rtw88/rx.c | 70 +++++++++++++++++-- + drivers/net/wireless/realtek/rtw88/rx.h | 64 ++++++++--------- + drivers/net/wireless/realtek/rtw88/sdio.c | 3 +- + drivers/net/wireless/realtek/rtw88/usb.c | 4 +- + 11 files changed, 106 insertions(+), 271 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -848,9 +848,8 @@ struct rtw_chip_ops { + void (*phy_set_param)(struct rtw_dev *rtwdev); + void (*set_channel)(struct rtw_dev *rtwdev, u8 channel, + u8 bandwidth, u8 primary_chan_idx); +- void (*query_rx_desc)(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status); ++ void (*query_phy_status)(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat); + u32 (*read_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, + u32 addr, u32 mask); + bool (*write_rf)(struct rtw_dev *rtwdev, enum rtw_rf_path rf_path, +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -1065,7 +1065,7 @@ static u32 rtw_pci_rx_napi(struct rtw_de + dma_sync_single_for_cpu(rtwdev->dev, dma, RTK_PCI_RX_BUF_SIZE, + DMA_FROM_DEVICE); + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); + + /* offset from rx_desc to payload */ + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -29,9 +29,6 @@ + #define TBTT_PROHIBIT_HOLD_TIME 0x80 + #define TBTT_PROHIBIT_HOLD_TIME_STOP_BCN 0x64 + +-/* raw pkt_stat->drv_info_sz is in unit of 8-bytes */ +-#define RX_DRV_INFO_SZ_UNIT_8703B 8 +- + #define TRANS_SEQ_END \ + 0xFFFF, \ + RTW_PWR_CUT_ALL_MSK, \ +@@ -1032,57 +1029,6 @@ static void query_phy_status(struct rtw_ + query_phy_status_ofdm(rtwdev, phy_status, pkt_stat); + } + +-static void rtw8703b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = 0; +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- pkt_stat->drv_info_sz *= RX_DRV_INFO_SZ_UNIT_8703B; +- +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- +- pkt_stat->bw = GET_RX_DESC_BW(rx_desc); +- +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +- +- /* Rtl8723cs driver checks for size < 14 or size > 8192 and +- * simply drops the packet. Maybe this should go into +- * rtw_rx_fill_rx_status()? +- */ +- if (pkt_stat->pkt_len == 0) { +- rx_status->flag |= RX_FLAG_NO_PSDU; +- rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); +- } +-} +- + #define ADDA_ON_VAL_8703B 0x03c00014 + + static +@@ -1948,7 +1894,7 @@ static const struct rtw_chip_ops rtw8703 + .read_efuse = rtw8703b_read_efuse, + .phy_set_param = rtw8703b_phy_set_param, + .set_channel = rtw8703b_set_channel, +- .query_rx_desc = rtw8703b_query_rx_desc, ++ .query_phy_status = query_phy_status, + .read_rf = rtw_phy_read_rf_sipi, + .write_rf = rtw_phy_write_rf_reg_sipi, + .set_tx_power_index = rtw8723x_set_tx_power_index, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -227,47 +227,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8723d_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = 0; +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static bool rtw8723d_check_spur_ov_thres(struct rtw_dev *rtwdev, + u8 channel, u32 thres) + { +@@ -1433,7 +1392,7 @@ static void rtw8723d_pwr_track(struct rt + static const struct rtw_chip_ops rtw8723d_ops = { + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, +- .query_rx_desc = rtw8723d_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8723d_set_channel, + .mac_init = rtw8723x_mac_init, + .shutdown = rtw8723d_shutdown, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -679,47 +679,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8821c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8821c_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) + { +@@ -1686,7 +1645,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8821c_ops = { + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, +- .query_rx_desc = rtw8821c_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8821c_set_channel, + .mac_init = rtw8821c_mac_init, + .read_rf = rtw_phy_read_rf, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -934,47 +934,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8822b_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8822b_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, u8 rs) + { +@@ -2175,7 +2134,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8822b_ops = { + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, +- .query_rx_desc = rtw8822b_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8822b_set_channel, + .mac_init = rtw8822b_mac_init, + .read_rf = rtw_phy_read_rf, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -2690,48 +2690,6 @@ static void query_phy_status(struct rtw_ + } + } + +-static void rtw8822c_query_rx_desc(struct rtw_dev *rtwdev, u8 *rx_desc, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_rx_status *rx_status) +-{ +- struct ieee80211_hdr *hdr; +- u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; +- u8 *phy_status = NULL; +- +- memset(pkt_stat, 0, sizeof(*pkt_stat)); +- +- pkt_stat->phy_status = GET_RX_DESC_PHYST(rx_desc); +- pkt_stat->icv_err = GET_RX_DESC_ICV_ERR(rx_desc); +- pkt_stat->crc_err = GET_RX_DESC_CRC32(rx_desc); +- pkt_stat->decrypted = !GET_RX_DESC_SWDEC(rx_desc) && +- GET_RX_DESC_ENC_TYPE(rx_desc) != RX_DESC_ENC_NONE; +- pkt_stat->is_c2h = GET_RX_DESC_C2H(rx_desc); +- pkt_stat->pkt_len = GET_RX_DESC_PKT_LEN(rx_desc); +- pkt_stat->drv_info_sz = GET_RX_DESC_DRV_INFO_SIZE(rx_desc); +- pkt_stat->shift = GET_RX_DESC_SHIFT(rx_desc); +- pkt_stat->rate = GET_RX_DESC_RX_RATE(rx_desc); +- pkt_stat->cam_id = GET_RX_DESC_MACID(rx_desc); +- pkt_stat->ppdu_cnt = GET_RX_DESC_PPDU_CNT(rx_desc); +- pkt_stat->tsf_low = GET_RX_DESC_TSFL(rx_desc); +- +- /* drv_info_sz is in unit of 8-bytes */ +- pkt_stat->drv_info_sz *= 8; +- +- /* c2h cmd pkt's rx/phy status is not interested */ +- if (pkt_stat->is_c2h) +- return; +- +- hdr = (struct ieee80211_hdr *)(rx_desc + desc_sz + pkt_stat->shift + +- pkt_stat->drv_info_sz); +- pkt_stat->hdr = hdr; +- if (pkt_stat->phy_status) { +- phy_status = rx_desc + desc_sz + pkt_stat->shift; +- query_phy_status(rtwdev, phy_status, pkt_stat); +- } +- +- rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status, phy_status); +-} +- + static void + rtw8822c_set_write_tx_power_ref(struct rtw_dev *rtwdev, u8 *tx_pwr_ref_cck, + u8 *tx_pwr_ref_ofdm) +@@ -4991,7 +4949,7 @@ static const struct rtw_prioq_addrs prio + static const struct rtw_chip_ops rtw8822c_ops = { + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, +- .query_rx_desc = rtw8822c_query_rx_desc, ++ .query_phy_status = query_phy_status, + .set_channel = rtw8822c_set_channel, + .mac_init = rtw8822c_mac_init, + .dump_fw_crash = rtw8822c_dump_fw_crash, +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/rx.c +@@ -187,11 +187,10 @@ fill_rx_status: + } + EXPORT_SYMBOL(rtw_update_rx_freq_from_ie); + +-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_hdr *hdr, +- struct ieee80211_rx_status *rx_status, +- u8 *phy_status) ++static void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_hdr *hdr, ++ struct ieee80211_rx_status *rx_status) + { + struct ieee80211_hw *hw = rtwdev->hw; + u8 path; +@@ -242,5 +241,64 @@ void rtw_rx_fill_rx_status(struct rtw_de + } + + rtw_rx_addr_match(rtwdev, pkt_stat, hdr); ++ ++ /* Rtl8723cs driver checks for size < 14 or size > 8192 and ++ * simply drops the packet. ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8703B && pkt_stat->pkt_len == 0) { ++ rx_status->flag |= RX_FLAG_NO_PSDU; ++ rtw_dbg(rtwdev, RTW_DBG_RX, "zero length packet"); ++ } ++} ++ ++void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_rx_status *rx_status) ++{ ++ u32 desc_sz = rtwdev->chip->rx_pkt_desc_sz; ++ struct rtw_rx_desc *rx_desc = rx_desc8; ++ struct ieee80211_hdr *hdr; ++ u32 enc_type, swdec; ++ void *phy_status; ++ ++ memset(pkt_stat, 0, sizeof(*pkt_stat)); ++ ++ pkt_stat->pkt_len = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PKT_LEN); ++ pkt_stat->crc_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_CRC32); ++ pkt_stat->icv_err = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ICV_ERR); ++ pkt_stat->drv_info_sz = le32_get_bits(rx_desc->w0, ++ RTW_RX_DESC_W0_DRV_INFO_SIZE); ++ enc_type = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_ENC_TYPE); ++ pkt_stat->shift = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SHIFT); ++ pkt_stat->phy_status = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_PHYST); ++ swdec = le32_get_bits(rx_desc->w0, RTW_RX_DESC_W0_SWDEC); ++ pkt_stat->decrypted = !swdec && enc_type != RX_DESC_ENC_NONE; ++ ++ pkt_stat->cam_id = le32_get_bits(rx_desc->w1, RTW_RX_DESC_W1_MACID); ++ ++ pkt_stat->is_c2h = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_C2H); ++ pkt_stat->ppdu_cnt = le32_get_bits(rx_desc->w2, RTW_RX_DESC_W2_PPDU_CNT); ++ ++ pkt_stat->rate = le32_get_bits(rx_desc->w3, RTW_RX_DESC_W3_RX_RATE); ++ ++ pkt_stat->bw = le32_get_bits(rx_desc->w4, RTW_RX_DESC_W4_BW); ++ ++ pkt_stat->tsf_low = le32_get_bits(rx_desc->w5, RTW_RX_DESC_W5_TSFL); ++ ++ /* drv_info_sz is in unit of 8-bytes */ ++ pkt_stat->drv_info_sz *= 8; ++ ++ /* c2h cmd pkt's rx/phy status is not interested */ ++ if (pkt_stat->is_c2h) ++ return; ++ ++ phy_status = rx_desc8 + desc_sz + pkt_stat->shift; ++ hdr = phy_status + pkt_stat->drv_info_sz; ++ pkt_stat->hdr = hdr; ++ ++ if (pkt_stat->phy_status) ++ rtwdev->chip->ops->query_phy_status(rtwdev, phy_status, pkt_stat); ++ ++ rtw_rx_fill_rx_status(rtwdev, pkt_stat, hdr, rx_status); + } +-EXPORT_SYMBOL(rtw_rx_fill_rx_status); ++EXPORT_SYMBOL(rtw_rx_query_rx_desc); +--- a/drivers/net/wireless/realtek/rtw88/rx.h ++++ b/drivers/net/wireless/realtek/rtw88/rx.h +@@ -14,42 +14,40 @@ enum rtw_rx_desc_enc { + RX_DESC_ENC_WEP104 = 5, + }; + +-#define GET_RX_DESC_PHYST(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(26)) +-#define GET_RX_DESC_ICV_ERR(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(15)) +-#define GET_RX_DESC_CRC32(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(14)) +-#define GET_RX_DESC_SWDEC(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), BIT(27)) +-#define GET_RX_DESC_C2H(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), BIT(28)) +-#define GET_RX_DESC_PKT_LEN(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(13, 0)) +-#define GET_RX_DESC_DRV_INFO_SIZE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(19, 16)) +-#define GET_RX_DESC_SHIFT(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(25, 24)) +-#define GET_RX_DESC_ENC_TYPE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x00), GENMASK(22, 20)) +-#define GET_RX_DESC_RX_RATE(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x03), GENMASK(6, 0)) +-#define GET_RX_DESC_MACID(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x01), GENMASK(6, 0)) +-#define GET_RX_DESC_PPDU_CNT(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x02), GENMASK(30, 29)) +-#define GET_RX_DESC_TSFL(rxdesc) \ +- le32_get_bits(*((__le32 *)(rxdesc) + 0x05), GENMASK(31, 0)) +-#define GET_RX_DESC_BW(rxdesc) \ +- (le32_get_bits(*((__le32 *)(rxdesc) + 0x04), GENMASK(5, 4))) ++struct rtw_rx_desc { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++} __packed; ++ ++#define RTW_RX_DESC_W0_PKT_LEN GENMASK(13, 0) ++#define RTW_RX_DESC_W0_CRC32 BIT(14) ++#define RTW_RX_DESC_W0_ICV_ERR BIT(15) ++#define RTW_RX_DESC_W0_DRV_INFO_SIZE GENMASK(19, 16) ++#define RTW_RX_DESC_W0_ENC_TYPE GENMASK(22, 20) ++#define RTW_RX_DESC_W0_SHIFT GENMASK(25, 24) ++#define RTW_RX_DESC_W0_PHYST BIT(26) ++#define RTW_RX_DESC_W0_SWDEC BIT(27) ++ ++#define RTW_RX_DESC_W1_MACID GENMASK(6, 0) ++ ++#define RTW_RX_DESC_W2_C2H BIT(28) ++#define RTW_RX_DESC_W2_PPDU_CNT GENMASK(30, 29) ++ ++#define RTW_RX_DESC_W3_RX_RATE GENMASK(6, 0) ++ ++#define RTW_RX_DESC_W4_BW GENMASK(5, 4) ++ ++#define RTW_RX_DESC_W5_TSFL GENMASK(31, 0) + + void rtw_rx_stats(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + struct sk_buff *skb); +-void rtw_rx_fill_rx_status(struct rtw_dev *rtwdev, +- struct rtw_rx_pkt_stat *pkt_stat, +- struct ieee80211_hdr *hdr, +- struct ieee80211_rx_status *rx_status, +- u8 *phy_status); ++void rtw_rx_query_rx_desc(struct rtw_dev *rtwdev, void *rx_desc8, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ struct ieee80211_rx_status *rx_status); + void rtw_update_rx_freq_from_ie(struct rtw_dev *rtwdev, struct sk_buff *skb, + struct ieee80211_rx_status *rx_status, + struct rtw_rx_pkt_stat *pkt_stat); +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -981,8 +981,7 @@ static void rtw_sdio_rxfifo_recv(struct + + while (true) { + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, &rx_status); + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -570,8 +570,8 @@ static void rtw_usb_rx_handler(struct wo + + do { + rx_desc = skb->data; +- chip->ops->query_rx_desc(rtwdev, rx_desc, &pkt_stat, +- &rx_status); ++ rtw_rx_query_rx_desc(rtwdev, rx_desc, &pkt_stat, ++ &rx_status); + pkt_offset = pkt_desc_sz + pkt_stat.drv_info_sz + + pkt_stat.shift; + diff --git a/package/kernel/mac80211/patches/rtl/020-v6.12-wifi-rtw88-Fix-the-RX-aggregation-in-USB-3-mode.patch b/package/kernel/mac80211/patches/rtl/020-v6.12-wifi-rtw88-Fix-the-RX-aggregation-in-USB-3-mode.patch new file mode 100644 index 00000000000000..174ee10816e6a3 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/020-v6.12-wifi-rtw88-Fix-the-RX-aggregation-in-USB-3-mode.patch @@ -0,0 +1,70 @@ +From 4aefde403da7af30757915e0462d88398c9388c5 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Tue, 8 Oct 2024 21:44:02 +0300 +Subject: [PATCH] wifi: rtw88: Fix the RX aggregation in USB 3 mode + +RTL8822CU, RTL8822BU, and RTL8821CU don't need BIT_EN_PRE_CALC. +In fact, RTL8822BU in USB 3 mode doesn't pass all the frames to the +driver, resulting in much lower download speed than normal: + +$ iperf3 -c 192.168.0.1 -R +Connecting to host 192.168.0.1, port 5201 +Reverse mode, remote host 192.168.0.1 is sending +[ 5] local 192.168.0.50 port 43062 connected to 192.168.0.1 port 5201 +[ ID] Interval Transfer Bitrate +[ 5] 0.00-1.00 sec 26.9 MBytes 225 Mbits/sec +[ 5] 1.00-2.00 sec 7.50 MBytes 62.9 Mbits/sec +[ 5] 2.00-3.00 sec 8.50 MBytes 71.3 Mbits/sec +[ 5] 3.00-4.00 sec 8.38 MBytes 70.3 Mbits/sec +[ 5] 4.00-5.00 sec 7.75 MBytes 65.0 Mbits/sec +[ 5] 5.00-6.00 sec 8.00 MBytes 67.1 Mbits/sec +[ 5] 6.00-7.00 sec 8.00 MBytes 67.1 Mbits/sec +[ 5] 7.00-8.00 sec 7.75 MBytes 65.0 Mbits/sec +[ 5] 8.00-9.00 sec 7.88 MBytes 66.1 Mbits/sec +[ 5] 9.00-10.00 sec 7.88 MBytes 66.1 Mbits/sec +- - - - - - - - - - - - - - - - - - - - - - - - - +[ ID] Interval Transfer Bitrate Retr +[ 5] 0.00-10.02 sec 102 MBytes 85.1 Mbits/sec 224 sender +[ 5] 0.00-10.00 sec 98.6 MBytes 82.7 Mbits/sec receiver + +Don't set BIT_EN_PRE_CALC. Then the speed is much better: + +% iperf3 -c 192.168.0.1 -R +Connecting to host 192.168.0.1, port 5201 +Reverse mode, remote host 192.168.0.1 is sending +[ 5] local 192.168.0.50 port 39000 connected to 192.168.0.1 port 5201 +[ ID] Interval Transfer Bitrate +[ 5] 0.00-1.00 sec 52.8 MBytes 442 Mbits/sec +[ 5] 1.00-2.00 sec 71.9 MBytes 603 Mbits/sec +[ 5] 2.00-3.00 sec 74.8 MBytes 627 Mbits/sec +[ 5] 3.00-4.00 sec 75.9 MBytes 636 Mbits/sec +[ 5] 4.00-5.00 sec 76.0 MBytes 638 Mbits/sec +[ 5] 5.00-6.00 sec 74.1 MBytes 622 Mbits/sec +[ 5] 6.00-7.00 sec 74.0 MBytes 621 Mbits/sec +[ 5] 7.00-8.00 sec 76.0 MBytes 638 Mbits/sec +[ 5] 8.00-9.00 sec 74.4 MBytes 624 Mbits/sec +[ 5] 9.00-10.00 sec 63.9 MBytes 536 Mbits/sec +- - - - - - - - - - - - - - - - - - - - - - - - - +[ ID] Interval Transfer Bitrate Retr +[ 5] 0.00-10.00 sec 717 MBytes 601 Mbits/sec 24 sender +[ 5] 0.00-10.00 sec 714 MBytes 599 Mbits/sec receiver + +Fixes: 002a5db9a52a ("wifi: rtw88: Enable USB RX aggregation for 8822c/8822b/8821c") +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://patch.msgid.link/afb94a82-3d18-459e-97fc-1a217608cdf0@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(st + u8 size, timeout; + u16 val16; + +- rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); + rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); + rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); + diff --git a/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch b/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch new file mode 100644 index 00000000000000..4f019617d4799f --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/022-v6.13-wifi-rtw88-Refactor-looping-in-rtw_phy_store_tx_powe.patch @@ -0,0 +1,34 @@ +From 7846f0b63562f4db45f712cc7dab091985baf07b Mon Sep 17 00:00:00 2001 +From: Mohammed Anees +Date: Thu, 17 Oct 2024 13:36:38 +0530 +Subject: [PATCH] wifi: rtw88: Refactor looping in + rtw_phy_store_tx_power_by_rate + +The previous implementation included an unnecessary else +condition paired with a continue statement. Since a check +is already performed to determine if the band is either +2G or 5G, the else condition will never be triggered. +We can remove this check. + +Signed-off-by: Mohammed Anees +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20241017080638.13074-1-pvmohammedanees2003@gmail.com +--- + drivers/net/wireless/realtek/rtw88/phy.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -1470,10 +1470,8 @@ static void rtw_phy_store_tx_power_by_ra + rate = rates[i]; + if (band == PHY_BAND_2G) + hal->tx_pwr_by_rate_offset_2g[rfpath][rate] = offset; +- else if (band == PHY_BAND_5G) +- hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + else +- continue; ++ hal->tx_pwr_by_rate_offset_5g[rfpath][rate] = offset; + } + } + diff --git a/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch b/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch new file mode 100644 index 00000000000000..accbf2b484f7f1 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/023-v6.13-wifi-rtw88-Report-the-signal-strength-only-if-it-s-k.patch @@ -0,0 +1,39 @@ +From 47f754b3f838205f3b25c4839f74801d180995bf Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Tue, 22 Oct 2024 20:20:26 +0300 +Subject: [PATCH] wifi: rtw88: Report the signal strength only if it's known + +RTL8811CU doesn't report the signal strength for many (any?) data +frames. When the signal strength is not known, set +RX_FLAG_NO_SIGNAL_VAL in order to avoid reporting a signal +strength of 0. + +Signed-off-by: Bitterblue Smith +Acked-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f7e1e448-2c9b-498f-b8b1-a14dd967d7d3@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rx.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/rx.c ++++ b/drivers/net/wireless/realtek/rtw88/rx.c +@@ -234,10 +234,14 @@ static void rtw_rx_fill_rx_status(struct + else + rx_status->bw = RATE_INFO_BW_20; + +- rx_status->signal = pkt_stat->signal_power; +- for (path = 0; path < rtwdev->hal.rf_path_num; path++) { +- rx_status->chains |= BIT(path); +- rx_status->chain_signal[path] = pkt_stat->rx_power[path]; ++ if (pkt_stat->phy_status) { ++ rx_status->signal = pkt_stat->signal_power; ++ for (path = 0; path < rtwdev->hal.rf_path_num; path++) { ++ rx_status->chains |= BIT(path); ++ rx_status->chain_signal[path] = pkt_stat->rx_power[path]; ++ } ++ } else { ++ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; + } + + rtw_rx_addr_match(rtwdev, pkt_stat, hdr); diff --git a/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch b/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch new file mode 100644 index 00000000000000..bf3d2fe267f4b2 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/024-v6.13-wifi-rtw88-Add-some-definitions-for-RTL8821AU-RTL881.patch @@ -0,0 +1,490 @@ +From d12722830ea4f562e91586927ec21b64d0369544 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:00:59 +0300 +Subject: [PATCH] wifi: rtw88: Add some definitions for RTL8821AU/RTL8812AU + +Add 8821A and 8812A chip type enums. + +Add cck_high_power member to struct rtw_hal. This will be used to +calculate the RX signal strength of RTL8812AU. + +Add various register definitions which will be used by the new drivers. + +Move some existing register definitions from rtw8821c.h and rtw8822b.h. +They were duplicated in those headers and will also be used by the new +drivers. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/9279a9cd-6f86-4dc3-a095-7c36cb9b9d06@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 3 + + drivers/net/wireless/realtek/rtw88/reg.h | 174 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821c.h | 24 --- + drivers/net/wireless/realtek/rtw88/rtw8822b.h | 12 -- + 4 files changed, 177 insertions(+), 36 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -189,6 +189,8 @@ enum rtw_chip_type { + RTW_CHIP_TYPE_8723D, + RTW_CHIP_TYPE_8821C, + RTW_CHIP_TYPE_8703B, ++ RTW_CHIP_TYPE_8821A, ++ RTW_CHIP_TYPE_8812A, + }; + + enum rtw_tx_queue_type { +@@ -1934,6 +1936,7 @@ struct rtw_hal { + u32 antenna_rx; + u8 bfee_sts_cap; + bool txrx_1ss; ++ bool cck_high_power; + + /* protect tx power section */ + struct mutex tx_power_mutex; +--- a/drivers/net/wireless/realtek/rtw88/reg.h ++++ b/drivers/net/wireless/realtek/rtw88/reg.h +@@ -9,6 +9,7 @@ + #define BIT_FEN_EN_25_1 BIT(13) + #define BIT_FEN_ELDR BIT(12) + #define BIT_FEN_CPUEN BIT(2) ++#define BIT_FEN_USBA BIT(2) + #define BIT_FEN_BB_GLB_RST BIT(1) + #define BIT_FEN_BB_RSTB BIT(0) + #define BIT_R_DIS_PRST BIT(6) +@@ -16,6 +17,10 @@ + #define REG_SYS_PW_CTRL 0x0004 + #define BIT_PFM_WOWL BIT(3) + #define BIT_APFM_OFFMAC BIT(9) ++#define REG_APS_FSMCO 0x0004 ++#define APS_FSMCO_MAC_ENABLE BIT(8) ++#define APS_FSMCO_MAC_OFF BIT(9) ++#define APS_FSMCO_HW_POWERDOWN BIT(15) + #define REG_SYS_CLK_CTRL 0x0008 + #define BIT_CPU_CLK_EN BIT(14) + +@@ -58,6 +63,8 @@ + #define BIT_SHIFT_LDO25_VOLTAGE 4 + #define BIT_LDO25_EN BIT(7) + ++#define REG_ACLK_MON 0x3e ++ + #define REG_GPIO_MUXCFG 0x0040 + #define BIT_FSPI_EN BIT(19) + #define BIT_EN_SIC BIT(12) +@@ -90,6 +97,8 @@ + #define BIT_USB_SUS_DIS BIT(8) + #define BIT_SDIO_PAD_E5 BIT(18) + ++#define REG_RF_B_CTRL 0x76 ++ + #define REG_AFE_CTRL_4 0x0078 + #define BIT_CK320M_AFE_EN BIT(4) + #define BIT_EN_SYN BIT(15) +@@ -134,6 +143,11 @@ + #define REG_PMC_DBG_CTRL1 0xa8 + #define BITS_PMC_BT_IQK_STS GENMASK(22, 21) + ++#define REG_HIMR0 0xb0 ++#define REG_HISR0 0xb4 ++#define REG_HIMR1 0xb8 ++#define REG_HISR1 0xbc ++ + #define REG_PAD_CTRL2 0x00C4 + #define BIT_RSM_EN_V1 BIT(16) + #define BIT_NO_PDN_CHIPOFF_V1 BIT(17) +@@ -185,6 +199,15 @@ + #define MAC_TRX_ENABLE (BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | \ + BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | \ + BIT_MACTXEN | BIT_MACRXEN) ++#define REG_PBP 0x104 ++#define PBP_RX_MASK 0x0f ++#define PBP_TX_MASK 0xf0 ++#define PBP_64 0x0 ++#define PBP_128 0x1 ++#define PBP_256 0x2 ++#define PBP_512 0x3 ++#define PBP_1024 0x4 ++ + #define BIT_SHIFT_TXDMA_VOQ_MAP 4 + #define BIT_MASK_TXDMA_VOQ_MAP 0x3 + #define BIT_TXDMA_VOQ_MAP(x) \ +@@ -256,6 +279,8 @@ + #define REG_HMEBOX1 0x01D4 + #define REG_HMEBOX2 0x01D8 + #define REG_HMEBOX3 0x01DC ++#define REG_LLT_INIT 0x01E0 ++#define BIT_LLT_WRITE_ACCESS BIT(30) + #define REG_HMEBOX0_EX 0x01F0 + #define REG_HMEBOX1_EX 0x01F4 + #define REG_HMEBOX2_EX 0x01F8 +@@ -298,6 +323,7 @@ + + #define REG_AUTO_LLT 0x0224 + #define BIT_AUTO_INIT_LLT BIT(16) ++#define REG_DWBCN1_CTRL 0x0228 + #define REG_RQPN_CTRL_1 0x0228 + #define REG_RQPN_CTRL_2 0x022C + #define BIT_LD_RQPN BIT(31) +@@ -329,6 +355,7 @@ + #define BIT_DMA_BURST_SIZE_1024 0 + + #define REG_RXPKTNUM 0x02B0 ++#define REG_EARLY_MODE_CONTROL 0x02BC + + #define REG_INT_MIG 0x0304 + #define REG_HCI_MIX_CFG 0x03FC +@@ -336,6 +363,7 @@ + + #define REG_BCNQ_INFO 0x0418 + #define BIT_MGQ_CPU_EMPTY BIT(24) ++#define REG_TXPKT_EMPTY 0x041A + #define REG_FWHW_TXQ_CTRL 0x0420 + #define BIT_EN_BCNQ_DL BIT(22) + #define BIT_EN_WR_FREE_TAIL BIT(20) +@@ -362,10 +390,12 @@ + #define REG_AMPDU_MAX_TIME_V1 0x0455 + #define REG_BCNQ1_BDNY_V1 0x0456 + #define REG_AMPDU_MAX_TIME 0x0456 ++#define REG_AMPDU_MAX_LENGTH 0x0458 + #define REG_WMAC_LBK_BF_HD 0x045D + #define REG_TX_HANG_CTRL 0x045E + #define BIT_EN_GNT_BT_AWAKE BIT(3) + #define BIT_EN_EOF_V1 BIT(2) ++#define REG_FAST_EDCA_CTRL 0x0460 + #define REG_DATA_SC 0x0483 + #define REG_ARFR2_V1 0x048C + #define REG_ARFRH2_V1 0x0490 +@@ -390,6 +420,8 @@ + #define REG_PRECNT_CTRL 0x04E5 + #define BIT_BTCCA_CTRL (BIT(0) | BIT(1)) + #define BIT_EN_PRECNT BIT(11) ++#define REG_TX_RPT_CTRL 0x04EC ++#define REG_TX_RPT_TIME 0x04F0 + #define REG_DUMMY_PAGE4_V1 0x04FC + + #define REG_EDCA_VO_PARAM 0x0500 +@@ -400,6 +432,7 @@ + #define BIT_MASK_CWMAX GENMASK(15, 12) + #define BIT_MASK_CWMIN GENMASK(11, 8) + #define BIT_MASK_AIFS GENMASK(7, 0) ++#define REG_BCNTCFG 0x0510 + #define REG_PIFS 0x0512 + #define REG_SIFS 0x0514 + #define BIT_SHIFT_SIFS_OFDM_CTX 8 +@@ -526,6 +559,8 @@ + #define REG_BT_COEX_V2 0x0762 + #define BIT_GNT_BT_POLARITY BIT(12) + #define BIT_LTE_COEX_EN BIT(7) ++#define REG_GNT_BT 0x0765 ++#define BIT_PTA_SW_CTL GENMASK(4, 3) + #define REG_BT_COEX_ENH_INTR_CTRL 0x76E + #define BIT_R_GRANTALL_WLMASK BIT(3) + #define BIT_STATIS_BT_EN BIT(2) +@@ -543,14 +578,43 @@ + #define REG_FPGA0_RFMOD 0x0800 + #define BIT_CCKEN BIT(24) + #define BIT_OFDMEN BIT(25) ++#define REG_CCK_RPT_FORMAT 0x0804 ++#define BIT_CCK_RPT_FORMAT BIT(16) ++#define REG_RXPSEL 0x0808 ++#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) ++#define REG_TXPSEL 0x080C + #define REG_RX_GAIN_EN 0x081c ++#define REG_CCASEL 0x082C ++#define REG_PDMFTH 0x0830 ++#define REG_BWINDICATION 0x0834 ++#define REG_CCA2ND 0x0838 ++#define REG_L1PKTH 0x0848 ++#define REG_CLKTRK 0x0860 ++#define REG_ADCCLK 0x08AC ++#define REG_HSSI_READ 0x08B0 ++#define REG_FPGA0_XCD_RF_PARA 0x08B4 ++#define REG_RX_MCS_LIMIT 0x08BC ++#define REG_ADC160 0x08C4 ++#define REG_ANTSEL_SW 0x0900 ++#define REG_DAC_RSTB 0x090c ++#define REG_SINGLE_TONE_CONT_TX 0x0914 + + #define REG_RFE_CTRL_E 0x0974 + #define REG_2ND_CCA_CTRL 0x0976 ++#define REG_IQK_COM00 0x0978 ++#define REG_IQK_COM32 0x097c ++#define REG_IQK_COM64 0x0980 ++#define REG_IQK_COM96 0x0984 ++ ++#define REG_FAS 0x09a4 ++#define REG_RXSB 0x0a00 ++#define REG_CCK_RX 0x0a04 ++#define REG_CCK_PD_TH 0x0a0a + + #define REG_CCK0_FAREPORT 0xa2c + #define BIT_CCK0_2RX BIT(18) + #define BIT_CCK0_MRC BIT(22) ++#define REG_FA_CCK 0x0a5c + + #define REG_DIS_DPD 0x0a70 + #define DIS_DPD_MASK GENMASK(9, 0) +@@ -566,13 +630,109 @@ + #define DIS_DPD_RATEVHT2SS_MCS1 BIT(9) + #define DIS_DPD_RATEALL GENMASK(9, 0) + ++#define REG_CNTRST 0x0b58 ++ ++#define REG_3WIRE_SWA 0x0c00 ++#define REG_RX_IQC_AB_A 0x0c10 ++#define REG_TXSCALE_A 0x0c1c ++#define BB_SWING_MASK GENMASK(31, 21) ++#define REG_TX_AGC_A_CCK_11_CCK_1 0xc20 ++#define REG_TX_AGC_A_OFDM18_OFDM6 0xc24 ++#define REG_TX_AGC_A_OFDM54_OFDM24 0xc28 ++#define REG_TX_AGC_A_MCS3_MCS0 0xc2c ++#define REG_TX_AGC_A_MCS7_MCS4 0xc30 ++#define REG_TX_AGC_A_MCS11_MCS8 0xc34 ++#define REG_TX_AGC_A_MCS15_MCS12 0xc38 ++#define REG_TX_AGC_A_NSS1_INDEX3_NSS1_INDEX0 0xc3c ++#define REG_TX_AGC_A_NSS1_INDEX7_NSS1_INDEX4 0xc40 ++#define REG_TX_AGC_A_NSS2_INDEX1_NSS1_INDEX8 0xc44 ++#define REG_TX_AGC_A_NSS2_INDEX5_NSS2_INDEX2 0xc48 ++#define REG_TX_AGC_A_NSS2_INDEX9_NSS2_INDEX6 0xc4c ++#define REG_RXIGI_A 0x0c50 ++#define REG_TX_PWR_TRAINING_A 0x0c54 ++#define REG_CK_MONHA 0x0c5c ++#define REG_AFE_PWR1_A 0x0c60 ++#define REG_AFE_PWR2_A 0x0c64 ++#define REG_RX_WAIT_CCA_TX_CCK_RFON_A 0x0c68 ++#define REG_OFDM0_XA_TX_IQ_IMBALANCE 0x0c80 ++#define REG_OFDM0_A_TX_AFE 0x0c84 ++#define REG_OFDM0_XB_TX_IQ_IMBALANCE 0x0c88 ++#define REG_TSSI_TRK_SW 0x0c8c ++#define REG_LSSI_WRITE_A 0x0c90 ++#define REG_PREDISTA 0x0c90 ++#define REG_TXAGCIDX 0x0c94 ++ ++#define REG_RFE_PINMUX_A 0x0cb0 ++#define REG_RFE_INV_A 0x0cb4 + #define REG_RFE_CTRL8 0x0cb4 + #define BIT_MASK_RFE_SEL89 GENMASK(7, 0) ++#define PTA_CTRL_PIN 0x66 ++#define DPDT_CTRL_PIN 0x77 ++#define RFE_INV_MASK 0x3ff00000 ++#define REG_RFECTL_A 0x0cb8 + #define REG_RFE_INV8 0x0cbd + #define BIT_MASK_RFE_INV89 GENMASK(1, 0) + #define REG_RFE_INV16 0x0cbe + #define BIT_RFE_BUF_EN BIT(3) + ++#define REG_IQK_DPD_CFG 0x0cc4 ++#define REG_CFG_PMPD 0x0cc8 ++#define REG_IQC_Y 0x0ccc ++#define REG_IQC_X 0x0cd4 ++#define REG_INTPO_SETA 0x0ce8 ++ ++#define REG_IQKA_END 0x0d00 ++#define REG_PI_READ_A 0x0d04 ++#define REG_SI_READ_A 0x0d08 ++#define REG_IQKB_END 0x0d40 ++#define REG_PI_READ_B 0x0d44 ++#define REG_SI_READ_B 0x0d48 ++ ++#define REG_3WIRE_SWB 0x0e00 ++#define REG_RX_IQC_AB_B 0x0e10 ++#define REG_TXSCALE_B 0x0e1c ++#define REG_TX_AGC_B_CCK_11_CCK_1 0xe20 ++#define REG_TX_AGC_B_OFDM18_OFDM6 0xe24 ++#define REG_TX_AGC_B_OFDM54_OFDM24 0xe28 ++#define REG_TX_AGC_B_MCS3_MCS0 0xe2c ++#define REG_TX_AGC_B_MCS7_MCS4 0xe30 ++#define REG_TX_AGC_B_MCS11_MCS8 0xe34 ++#define REG_TX_AGC_B_MCS15_MCS12 0xe38 ++#define REG_TX_AGC_B_NSS1_INDEX3_NSS1_INDEX0 0xe3c ++#define REG_TX_AGC_B_NSS1_INDEX7_NSS1_INDEX4 0xe40 ++#define REG_TX_AGC_B_NSS2_INDEX1_NSS1_INDEX8 0xe44 ++#define REG_TX_AGC_B_NSS2_INDEX5_NSS2_INDEX2 0xe48 ++#define REG_TX_AGC_B_NSS2_INDEX9_NSS2_INDEX6 0xe4c ++#define REG_RXIGI_B 0x0e50 ++#define REG_TX_PWR_TRAINING_B 0x0e54 ++#define REG_CK_MONHB 0x0e5c ++#define REG_AFE_PWR1_B 0x0e60 ++#define REG_AFE_PWR2_B 0x0e64 ++#define REG_RX_WAIT_CCA_TX_CCK_RFON_B 0x0e68 ++#define REG_TXTONEB 0x0e80 ++#define REG_RXTONEB 0x0e84 ++#define REG_TXPITMB 0x0e88 ++#define REG_RXPITMB 0x0e8c ++#define REG_LSSI_WRITE_B 0x0e90 ++#define REG_PREDISTB 0x0e90 ++#define REG_INIDLYB 0x0e94 ++#define REG_RFE_PINMUX_B 0x0eb0 ++#define REG_RFE_INV_B 0x0eb4 ++#define REG_RFECTL_B 0x0eb8 ++#define REG_BPBDB 0x0ec4 ++#define REG_PHYTXONB 0x0ec8 ++#define REG_IQKYB 0x0ecc ++#define REG_IQKXB 0x0ed4 ++#define REG_INTPO_SETB 0x0ee8 ++ ++#define REG_CRC_CCK 0x0f04 ++#define REG_CCA_OFDM 0x0f08 ++#define REG_CRC_VHT 0x0f0c ++#define REG_CRC_HT 0x0f10 ++#define REG_CRC_OFDM 0x0f14 ++#define REG_FA_OFDM 0x0f48 ++#define REG_CCA_CCK 0x0fcc ++ + #define REG_ANAPARSW_MAC_0 0x1010 + #define BIT_CF_L_V2 GENMASK(29, 28) + +@@ -709,6 +869,10 @@ + + #define REG_IGN_GNTBT4 0x4160 + ++#define REG_USB_MOD 0xf008 ++#define REG_USB3_RXITV 0xf050 ++#define REG_USB_HRPWM 0xfe58 ++ + #define RF_MODE 0x00 + #define RF_MODOPT 0x01 + #define RF_WLINT 0x01 +@@ -716,7 +880,13 @@ + #define RF_DTXLOK 0x08 + #define RF_CFGCH 0x18 + #define BIT_BAND GENMASK(18, 16) ++#define RF18_BAND_MASK (BIT(16) | BIT(9) | BIT(8)) ++#define RF18_CHANNEL_MASK (MASKBYTE0) ++#define RF18_RFSI_MASK (BIT(18) | BIT(17)) + #define RF_RCK 0x1d ++#define RF_MODE_TABLE_ADDR 0x30 ++#define RF_MODE_TABLE_DATA0 0x31 ++#define RF_MODE_TABLE_DATA1 0x32 + #define RF_LUTWA 0x33 + #define RF_LUTWD1 0x3e + #define RF_LUTWD0 0x3f +@@ -725,10 +895,14 @@ + #define RF_T_METER 0x42 + #define RF_BSPAD 0x54 + #define RF_GAINTX 0x56 ++#define RF_TXMOD 0x58 + #define RF_TXATANK 0x64 ++#define RF_TXA_PREPAD 0x65 + #define RF_TRXIQ 0x66 + #define RF_RXIQGEN 0x8d ++#define RF_RXBB2 0x8f + #define RF_SYN_PFD 0xb0 ++#define RF_LCK 0xb4 + #define RF_XTALX2 0xb8 + #define RF_SYN_CTRL 0xbb + #define RF_MALSEL 0xbe +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h +@@ -214,19 +214,10 @@ extern const struct rtw_chip_info rtw882 + #define BIT_FEN_EN BIT(26) + #define REG_INIRTS_RATE_SEL 0x0480 + #define REG_HTSTFWT 0x800 +-#define REG_RXPSEL 0x808 +-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +-#define REG_TXPSEL 0x80c + #define REG_RXCCAMSK 0x814 +-#define REG_CCASEL 0x82c +-#define REG_PDMFTH 0x830 +-#define REG_CCA2ND 0x838 + #define REG_L1WT 0x83c + #define REG_L1PKWT 0x840 + #define REG_MRC 0x850 +-#define REG_CLKTRK 0x860 +-#define REG_ADCCLK 0x8ac +-#define REG_ADC160 0x8c4 + #define REG_ADC40 0x8c8 + #define REG_CHFIR 0x8f0 + #define REG_CDDTXP 0x93c +@@ -234,14 +225,11 @@ extern const struct rtw_chip_info rtw882 + #define REG_ACBB0 0x948 + #define REG_ACBBRXFIR 0x94c + #define REG_ACGG2TBL 0x958 +-#define REG_FAS 0x9a4 +-#define REG_RXSB 0xa00 + #define REG_ADCINI 0xa04 + #define REG_PWRTH 0xa08 + #define REG_CCA_FLTR 0xa20 + #define REG_TXSF2 0xa24 + #define REG_TXSF6 0xa28 +-#define REG_FA_CCK 0xa5c + #define REG_RXDESC 0xa2c + #define REG_ENTXCCK 0xa80 + #define BTG_LNA 0xfc84 +@@ -252,12 +240,8 @@ extern const struct rtw_chip_info rtw882 + #define REG_PWRTH2 0xaa8 + #define REG_CSRATIO 0xaaa + #define REG_TXFILTER 0xaac +-#define REG_CNTRST 0xb58 + #define REG_AGCTR_A 0xc08 +-#define REG_TXSCALE_A 0xc1c + #define REG_TXDFIR 0xc20 +-#define REG_RXIGI_A 0xc50 +-#define REG_TXAGCIDX 0xc94 + #define REG_TRSW 0xca0 + #define REG_RFESEL0 0xcb0 + #define REG_RFESEL8 0xcb4 +@@ -269,14 +253,6 @@ extern const struct rtw_chip_info rtw882 + #define B_WLA_SWITCH BIT(23) + #define REG_RFEINV 0xcbc + #define REG_AGCTR_B 0xe08 +-#define REG_RXIGI_B 0xe50 +-#define REG_CRC_CCK 0xf04 +-#define REG_CRC_OFDM 0xf14 +-#define REG_CRC_HT 0xf10 +-#define REG_CRC_VHT 0xf0c +-#define REG_CCA_OFDM 0xf08 +-#define REG_FA_OFDM 0xf48 +-#define REG_CCA_CCK 0xfcc + #define REG_DMEM_CTRL 0x1080 + #define BIT_WL_RST BIT(16) + #define REG_ANTWT 0x1904 +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.h ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.h +@@ -151,21 +151,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define RTW8822B_EDCCA_MAX 0x7f + #define RTW8822B_EDCCA_SRC_DEF 1 + #define REG_HTSTFWT 0x800 +-#define REG_RXPSEL 0x808 +-#define BIT_RX_PSEL_RST (BIT(28) | BIT(29)) +-#define REG_TXPSEL 0x80c + #define REG_RXCCAMSK 0x814 +-#define REG_CCASEL 0x82c +-#define REG_PDMFTH 0x830 +-#define REG_CCA2ND 0x838 + #define REG_L1WT 0x83c + #define REG_L1PKWT 0x840 + #define REG_MRC 0x850 +-#define REG_CLKTRK 0x860 + #define REG_EDCCA_POW_MA 0x8a0 + #define BIT_MA_LEVEL GENMASK(1, 0) +-#define REG_ADCCLK 0x8ac +-#define REG_ADC160 0x8c4 + #define REG_ADC40 0x8c8 + #define REG_EDCCA_DECISION 0x8dc + #define BIT_EDCCA_OPTION BIT(5) +@@ -176,7 +167,6 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define REG_ACBB0 0x948 + #define REG_ACBBRXFIR 0x94c + #define REG_ACGG2TBL 0x958 +-#define REG_RXSB 0xa00 + #define REG_ADCINI 0xa04 + #define REG_TXSF2 0xa24 + #define REG_TXSF6 0xa28 +@@ -184,14 +174,12 @@ _rtw_write32s_mask(struct rtw_dev *rtwde + #define REG_ENTXCCK 0xa80 + #define REG_AGCTR_A 0xc08 + #define REG_TXDFIR 0xc20 +-#define REG_RXIGI_A 0xc50 + #define REG_TRSW 0xca0 + #define REG_RFESEL0 0xcb0 + #define REG_RFESEL8 0xcb4 + #define REG_RFECTL 0xcb8 + #define REG_RFEINV 0xcbc + #define REG_AGCTR_B 0xe08 +-#define REG_RXIGI_B 0xe50 + #define REG_ANTWT 0x1904 + #define REG_IQKFAILMSK 0x1bf0 + diff --git a/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch b/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch new file mode 100644 index 00000000000000..279e8ba761d226 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/025-v6.13-wifi-rtw88-Dump-the-HW-features-only-for-some-chips.patch @@ -0,0 +1,93 @@ +From 87341ca1eac9a3bac23bd41f6e24f3c93b77452f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:02:05 +0300 +Subject: [PATCH] wifi: rtw88: Dump the HW features only for some chips + +RTL8821AU and RTL8812AU don't support this. They hit the "failed to read +hw feature report" error. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/8becd851-8760-4480-8e8c-c4869ce72507@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 3 +++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 7 files changed, 9 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1917,6 +1917,9 @@ static int rtw_dump_hw_feature(struct rt + u8 bw; + int i; + ++ if (!rtwdev->chip->hw_feature_report) ++ return 0; ++ + id = rtw_read8(rtwdev, REG_C2HEVT); + if (id != C2H_HW_FEATURE_REPORT) { + rtw_err(rtwdev, "failed to read hw feature report\n"); +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1200,6 +1200,7 @@ struct rtw_chip_info { + const struct rtw_fwcd_segs *fwcd_segs; + + u8 usb_tx_agg_desc_num; ++ bool hw_feature_report; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1960,6 +1960,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .max_power_index = 0x3f, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ ++ .hw_feature_report = true, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2131,6 +2131,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1968,6 +1968,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2509,6 +2509,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5329,6 +5329,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .page_size = TX_PAGE_SIZE, + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, ++ .hw_feature_report = true, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, diff --git a/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch b/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch new file mode 100644 index 00000000000000..0e97febb727031 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/026-v6.13-wifi-rtw88-Allow-different-C2H-RA-report-sizes.patch @@ -0,0 +1,175 @@ +From d9018f4373517d4560ce2ebf12684f77f5fbdad6 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:06:14 +0300 +Subject: [PATCH] wifi: rtw88: Allow different C2H RA report sizes + +The RTL8821AU and RTL8812AU have smaller RA report size, only 4 bytes. +Avoid the "invalid ra report c2h length" error. + +Also, use a struct and u8_get_bits() to access the RA report C2H. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/c3e73c3a-fb2f-4013-9f06-d5274211e282@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 21 +++++++++++++------ + drivers/net/wireless/realtek/rtw88/fw.h | 17 +++++++++++---- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + 8 files changed, 34 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -139,25 +139,30 @@ static u16 get_max_amsdu_len(u32 bit_rat + struct rtw_fw_iter_ra_data { + struct rtw_dev *rtwdev; + u8 *payload; ++ u8 length; + }; + + static void rtw_fw_ra_report_iter(void *data, struct ieee80211_sta *sta) + { + struct rtw_fw_iter_ra_data *ra_data = data; ++ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)ra_data->payload; + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; + u8 mac_id, rate, sgi, bw; + u8 mcs, nss; + u32 bit_rate; + +- mac_id = GET_RA_REPORT_MACID(ra_data->payload); ++ mac_id = ra_rpt->mac_id; + if (si->mac_id != mac_id) + return; + + si->ra_report.txrate.flags = 0; + +- rate = GET_RA_REPORT_RATE(ra_data->payload); +- sgi = GET_RA_REPORT_SGI(ra_data->payload); +- bw = GET_RA_REPORT_BW(ra_data->payload); ++ rate = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_RATE); ++ sgi = u8_get_bits(ra_rpt->rate_sgi, RTW_C2H_RA_RPT_SGI); ++ if (ra_data->length >= offsetofend(typeof(*ra_rpt), bw)) ++ bw = ra_rpt->bw; ++ else ++ bw = si->bw_mode; + + if (rate < DESC_RATEMCS0) { + si->ra_report.txrate.legacy = rtw_desc_to_bitrate(rate); +@@ -197,14 +202,18 @@ legacy: + static void rtw_fw_ra_report_handle(struct rtw_dev *rtwdev, u8 *payload, + u8 length) + { ++ struct rtw_c2h_ra_rpt *ra_rpt = (struct rtw_c2h_ra_rpt *)payload; + struct rtw_fw_iter_ra_data ra_data; + +- if (WARN(length < 7, "invalid ra report c2h length\n")) ++ if (WARN(length < rtwdev->chip->c2h_ra_report_size, ++ "invalid ra report c2h length %d\n", length)) + return; + +- rtwdev->dm_info.tx_rate = GET_RA_REPORT_RATE(payload); ++ rtwdev->dm_info.tx_rate = u8_get_bits(ra_rpt->rate_sgi, ++ RTW_C2H_RA_RPT_RATE); + ra_data.rtwdev = rtwdev; + ra_data.payload = payload; ++ ra_data.length = length; + rtw_iterate_stas_atomic(rtwdev, rtw_fw_ra_report_iter, &ra_data); + } + +--- a/drivers/net/wireless/realtek/rtw88/fw.h ++++ b/drivers/net/wireless/realtek/rtw88/fw.h +@@ -85,6 +85,19 @@ struct rtw_c2h_adaptivity { + u8 option; + } __packed; + ++struct rtw_c2h_ra_rpt { ++ u8 rate_sgi; ++ u8 mac_id; ++ u8 byte2; ++ u8 status; ++ u8 byte4; ++ u8 ra_ratio; ++ u8 bw; ++} __packed; ++ ++#define RTW_C2H_RA_RPT_RATE GENMASK(6, 0) ++#define RTW_C2H_RA_RPT_SGI BIT(7) ++ + struct rtw_h2c_register { + u32 w0; + u32 w1; +@@ -364,10 +377,6 @@ struct rtw_fw_hdr_legacy { + #define GET_CHAN_SWITCH_CENTRAL_CH(c2h_payload) (c2h_payload[2]) + #define GET_CHAN_SWITCH_ID(c2h_payload) (c2h_payload[3]) + #define GET_CHAN_SWITCH_STATUS(c2h_payload) (c2h_payload[4]) +-#define GET_RA_REPORT_RATE(c2h_payload) (c2h_payload[0] & 0x7f) +-#define GET_RA_REPORT_SGI(c2h_payload) ((c2h_payload[0] & 0x80) >> 7) +-#define GET_RA_REPORT_BW(c2h_payload) (c2h_payload[6]) +-#define GET_RA_REPORT_MACID(c2h_payload) (c2h_payload[1]) + + #define GET_BCN_FILTER_NOTIFY_TYPE(c2h_payload) (c2h_payload[1] & 0xf) + #define GET_BCN_FILTER_NOTIFY_EVENT(c2h_payload) (c2h_payload[1] & 0x10) +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1201,6 +1201,7 @@ struct rtw_chip_info { + + u8 usb_tx_agg_desc_num; + bool hw_feature_report; ++ u8 c2h_ra_report_size; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1961,6 +1961,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2132,6 +2132,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .dig_min = 0x20, + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1969,6 +1969,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2510,6 +2510,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .dig_min = 0x1c, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5330,6 +5330,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .dig_min = 0x20, + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, ++ .c2h_ra_report_size = 7, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, diff --git a/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch b/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch new file mode 100644 index 00000000000000..aec2e6aaecf6a7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/027-v6.13-wifi-rtw88-Extend-the-init-table-parsing-for-RTL8812.patch @@ -0,0 +1,165 @@ +From 95a772e30b60e7954d03f3372268722475aa303f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:08:24 +0300 +Subject: [PATCH] wifi: rtw88: Extend the init table parsing for RTL8812AU + +The chips supported so far only use the first condition, and so the +parsing code ignores the second condition. RTL8812AU's init tables use +the second condition also. Make the parsing code check it. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/1bee6b74-6eab-44a3-9f40-794ca006c72d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 15 ++++++ + drivers/net/wireless/realtek/rtw88/phy.c | 62 ++++++++++++++++++++--- + 2 files changed, 69 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1835,6 +1835,20 @@ struct rtw_phy_cond { + #define BRANCH_ENDIF 3 + }; + ++struct rtw_phy_cond2 { ++#ifdef __LITTLE_ENDIAN ++ u8 type_glna; ++ u8 type_gpa; ++ u8 type_alna; ++ u8 type_apa; ++#else ++ u8 type_apa; ++ u8 type_alna; ++ u8 type_gpa; ++ u8 type_glna; ++#endif ++}; ++ + struct rtw_fifo_conf { + /* tx fifo information */ + u16 rsvd_boundary; +@@ -1916,6 +1930,7 @@ struct rtw_hal { + u8 oem_id; + u8 pkg_type; + struct rtw_phy_cond phy_cond; ++ struct rtw_phy_cond2 phy_cond2; + bool rfe_btg; + + u8 ps_mode; +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -18,7 +18,10 @@ struct phy_cfg_pair { + }; + + union phy_table_tile { +- struct rtw_phy_cond cond; ++ struct { ++ struct rtw_phy_cond cond; ++ struct rtw_phy_cond2 cond2; ++ } __packed; + struct phy_cfg_pair cfg; + }; + +@@ -1041,7 +1044,8 @@ void rtw_phy_setup_phy_cond(struct rtw_d + { + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_efuse *efuse = &rtwdev->efuse; +- struct rtw_phy_cond cond = {0}; ++ struct rtw_phy_cond cond = {}; ++ struct rtw_phy_cond2 cond2 = {}; + + cond.cut = hal->cut_version ? hal->cut_version : 15; + cond.pkg = pkg ? pkg : 15; +@@ -1061,15 +1065,34 @@ void rtw_phy_setup_phy_cond(struct rtw_d + break; + } + ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || ++ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { ++ cond.rfe = 0; ++ cond.rfe |= efuse->ext_lna_2g; ++ cond.rfe |= efuse->ext_pa_2g << 1; ++ cond.rfe |= efuse->ext_lna_5g << 2; ++ cond.rfe |= efuse->ext_pa_5g << 3; ++ cond.rfe |= efuse->btcoex << 4; ++ ++ cond2.type_alna = efuse->alna_type; ++ cond2.type_glna = efuse->glna_type; ++ cond2.type_apa = efuse->apa_type; ++ cond2.type_gpa = efuse->gpa_type; ++ } ++ + hal->phy_cond = cond; ++ hal->phy_cond2 = cond2; + +- rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x\n", *((u32 *)&hal->phy_cond)); ++ rtw_dbg(rtwdev, RTW_DBG_PHY, "phy cond=0x%08x cond2=0x%08x\n", ++ *((u32 *)&hal->phy_cond), *((u32 *)&hal->phy_cond2)); + } + +-static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond) ++static bool check_positive(struct rtw_dev *rtwdev, struct rtw_phy_cond cond, ++ struct rtw_phy_cond2 cond2) + { + struct rtw_hal *hal = &rtwdev->hal; + struct rtw_phy_cond drv_cond = hal->phy_cond; ++ struct rtw_phy_cond2 drv_cond2 = hal->phy_cond2; + + if (cond.cut && cond.cut != drv_cond.cut) + return false; +@@ -1080,8 +1103,29 @@ static bool check_positive(struct rtw_de + if (cond.intf && cond.intf != drv_cond.intf) + return false; + +- if (cond.rfe != drv_cond.rfe) +- return false; ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A || ++ rtwdev->chip->id == RTW_CHIP_TYPE_8821A) { ++ if (!(cond.rfe & 0x0f)) ++ return true; ++ ++ if ((cond.rfe & drv_cond.rfe) != cond.rfe) ++ return false; ++ ++ if ((cond.rfe & BIT(0)) && cond2.type_glna != drv_cond2.type_glna) ++ return false; ++ ++ if ((cond.rfe & BIT(1)) && cond2.type_gpa != drv_cond2.type_gpa) ++ return false; ++ ++ if ((cond.rfe & BIT(2)) && cond2.type_alna != drv_cond2.type_alna) ++ return false; ++ ++ if ((cond.rfe & BIT(3)) && cond2.type_apa != drv_cond2.type_apa) ++ return false; ++ } else { ++ if (cond.rfe != drv_cond.rfe) ++ return false; ++ } + + return true; + } +@@ -1090,7 +1134,8 @@ void rtw_parse_tbl_phy_cond(struct rtw_d + { + const union phy_table_tile *p = tbl->data; + const union phy_table_tile *end = p + tbl->size / 2; +- struct rtw_phy_cond pos_cond = {0}; ++ struct rtw_phy_cond pos_cond = {}; ++ struct rtw_phy_cond2 pos_cond2 = {}; + bool is_matched = true, is_skipped = false; + + BUILD_BUG_ON(sizeof(union phy_table_tile) != sizeof(struct phy_cfg_pair)); +@@ -1109,11 +1154,12 @@ void rtw_parse_tbl_phy_cond(struct rtw_d + case BRANCH_ELIF: + default: + pos_cond = p->cond; ++ pos_cond2 = p->cond2; + break; + } + } else if (p->cond.neg) { + if (!is_skipped) { +- if (check_positive(rtwdev, pos_cond)) { ++ if (check_positive(rtwdev, pos_cond, pos_cond2)) { + is_matched = true; + is_skipped = true; + } else { diff --git a/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch b/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch new file mode 100644 index 00000000000000..5486fb2d25e099 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/028-v6.13-wifi-rtw88-Allow-rtw_chip_info.ltecoex_addr-to-be-NU.patch @@ -0,0 +1,58 @@ +From 7c5bbeba7c36575a3a57ef4be775b2f3fb68c3f9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:09:04 +0300 +Subject: [PATCH] wifi: rtw88: Allow rtw_chip_info.ltecoex_addr to be NULL + +RTL8821A doesn't have this. Trying to use it results in error messages, +so don't try if ltecoex_addr is NULL. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/d1004817-1760-41d1-9136-3d799757c444@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -950,12 +950,18 @@ static void rtw_coex_coex_ctrl_owner(str + + static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0xc000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0c00, state); + } + + static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state) + { ++ if (!rtwdev->chip->ltecoex_addr) ++ return; ++ + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x3000, state); + rtw_coex_write_indirect_reg(rtwdev, LTE_COEX_CTRL, 0x0300, state); + } +@@ -3904,7 +3910,7 @@ void rtw_coex_display_coex_info(struct r + u8 sys_lte; + u16 score_board_WB, score_board_BW; + u32 wl_reg_6c0, wl_reg_6c4, wl_reg_6c8, wl_reg_778, wl_reg_6cc; +- u32 lte_coex, bt_coex; ++ u32 lte_coex = 0, bt_coex = 0; + int i; + + score_board_BW = rtw_coex_read_scbd(rtwdev); +@@ -3916,8 +3922,10 @@ void rtw_coex_display_coex_info(struct r + wl_reg_778 = rtw_read8(rtwdev, REG_BT_STAT_CTRL); + + sys_lte = rtw_read8(rtwdev, 0x73); +- lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); +- bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ if (rtwdev->chip->ltecoex_addr) { ++ lte_coex = rtw_coex_read_indirect_reg(rtwdev, 0x38); ++ bt_coex = rtw_coex_read_indirect_reg(rtwdev, 0x54); ++ } + + if (!coex_stat->wl_under_ips && + (!coex_stat->wl_under_lps || coex_stat->wl_force_lps_ctrl) && diff --git a/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch b/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch new file mode 100644 index 00000000000000..10464b80cd0339 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/029-v6.13-wifi-rtw88-Let-each-driver-control-the-power-on-off-.patch @@ -0,0 +1,272 @@ +From fbb5e1b3637a720c83c91a7b1476ab0429bfc747 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:09:47 +0300 +Subject: [PATCH] wifi: rtw88: Let each driver control the power on/off process + +RTL8821AU and RTL8812AU have to do some things differently, so let +them have full control. + +The other chips use the same functions as before. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/98ab839f-9100-44ae-9551-9af743a4aa3a@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 3 +++ + drivers/net/wireless/realtek/rtw88/mac.c | 11 +++++++---- + drivers/net/wireless/realtek/rtw88/mac.h | 3 +++ + drivers/net/wireless/realtek/rtw88/main.c | 13 ++++++++----- + drivers/net/wireless/realtek/rtw88/main.h | 5 +++++ + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 2 ++ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 2 ++ + 10 files changed, 36 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -2753,16 +2753,19 @@ void rtw_coex_power_on_setting(struct rt + rtw_write8(rtwdev, 0xff1a, 0x0); + rtw_coex_set_gnt_debug(rtwdev); + } ++EXPORT_SYMBOL(rtw_coex_power_on_setting); + + void rtw_coex_power_off_setting(struct rtw_dev *rtwdev) + { + rtw_write16(rtwdev, REG_WIFI_BT_INFO, BIT_BT_INT_EN); + } ++EXPORT_SYMBOL(rtw_coex_power_off_setting); + + void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only) + { + __rtw_coex_init_hw_config(rtwdev, wifi_only); + } ++EXPORT_SYMBOL(rtw_coex_init_hw_config); + + void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type) + { +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -227,8 +227,8 @@ static int rtw_sub_pwr_seq_parser(struct + return 0; + } + +-static int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, +- const struct rtw_pwr_seq_cmd * const *cmd_seq) ++int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd * const *cmd_seq) + { + u8 cut_mask; + u8 intf_mask; +@@ -267,6 +267,7 @@ static int rtw_pwr_seq_parser(struct rtw + + return 0; + } ++EXPORT_SYMBOL(rtw_pwr_seq_parser); + + static int rtw_mac_power_switch(struct rtw_dev *rtwdev, bool pwr_on) + { +@@ -994,6 +995,7 @@ int rtw_download_firmware(struct rtw_dev + + return 0; + } ++EXPORT_SYMBOL(rtw_download_firmware); + + static u32 get_priority_queues(struct rtw_dev *rtwdev, u32 queues) + { +@@ -1127,7 +1129,7 @@ static int txdma_queue_mapping(struct rt + return 0; + } + +-static int set_trx_fifo_info(struct rtw_dev *rtwdev) ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fifo_conf *fifo = &rtwdev->fifo; +@@ -1179,6 +1181,7 @@ static int set_trx_fifo_info(struct rtw_ + + return 0; + } ++EXPORT_SYMBOL(rtw_set_trx_fifo_info); + + static int __priority_queue_cfg(struct rtw_dev *rtwdev, + const struct rtw_page_table *pg_tbl, +@@ -1256,7 +1259,7 @@ static int priority_queue_cfg(struct rtw + u16 pubq_num; + int ret; + +- ret = set_trx_fifo_info(rtwdev); ++ ret = rtw_set_trx_fifo_info(rtwdev); + if (ret) + return ret; + +--- a/drivers/net/wireless/realtek/rtw88/mac.h ++++ b/drivers/net/wireless/realtek/rtw88/mac.h +@@ -30,11 +30,14 @@ + + void rtw_set_channel_mac(struct rtw_dev *rtwdev, u8 channel, u8 bw, + u8 primary_ch_idx); ++int rtw_pwr_seq_parser(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd * const *cmd_seq); + int rtw_mac_power_on(struct rtw_dev *rtwdev); + void rtw_mac_power_off(struct rtw_dev *rtwdev); + int rtw_download_firmware(struct rtw_dev *rtwdev, struct rtw_fw_state *fw); + int rtw_mac_init(struct rtw_dev *rtwdev); + void rtw_mac_flush_queues(struct rtw_dev *rtwdev, u32 queues, bool drop); ++int rtw_set_trx_fifo_info(struct rtw_dev *rtwdev); + int rtw_ddma_to_fw_fifo(struct rtw_dev *rtwdev, u32 ocp_src, u32 size); + + static inline void rtw_mac_flush_all_queues(struct rtw_dev *rtwdev, bool drop) +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -1309,7 +1309,7 @@ void rtw_update_sta_info(struct rtw_dev + rtw_fw_send_ra_info(rtwdev, si, reset_ra_mask); + } + +-static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; +@@ -1329,6 +1329,7 @@ static int rtw_wait_firmware_completion( + + return ret; + } ++EXPORT_SYMBOL(rtw_wait_firmware_completion); + + static enum rtw_lps_deep_mode rtw_update_lps_deep_mode(struct rtw_dev *rtwdev, + struct rtw_fw_state *fw) +@@ -1350,7 +1351,7 @@ static enum rtw_lps_deep_mode rtw_update + return LPS_DEEP_MODE_NONE; + } + +-static int rtw_power_on(struct rtw_dev *rtwdev) ++int rtw_power_on(struct rtw_dev *rtwdev) + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw = &rtwdev->fw; +@@ -1413,6 +1414,7 @@ err_off: + err: + return ret; + } ++EXPORT_SYMBOL(rtw_power_on); + + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start) + { +@@ -1485,7 +1487,7 @@ int rtw_core_start(struct rtw_dev *rtwde + { + int ret; + +- ret = rtw_power_on(rtwdev); ++ ret = rtwdev->chip->ops->power_on(rtwdev); + if (ret) + return ret; + +@@ -1505,12 +1507,13 @@ int rtw_core_start(struct rtw_dev *rtwde + return 0; + } + +-static void rtw_power_off(struct rtw_dev *rtwdev) ++void rtw_power_off(struct rtw_dev *rtwdev) + { + rtw_hci_stop(rtwdev); + rtw_coex_power_off_setting(rtwdev); + rtw_mac_power_off(rtwdev); + } ++EXPORT_SYMBOL(rtw_power_off); + + void rtw_core_stop(struct rtw_dev *rtwdev) + { +@@ -1535,7 +1538,7 @@ void rtw_core_stop(struct rtw_dev *rtwde + + mutex_lock(&rtwdev->mutex); + +- rtw_power_off(rtwdev); ++ rtwdev->chip->ops->power_off(rtwdev); + } + + static void rtw_init_ht_cap(struct rtw_dev *rtwdev, +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -843,6 +843,8 @@ struct rtw_regd { + }; + + struct rtw_chip_ops { ++ int (*power_on)(struct rtw_dev *rtwdev); ++ void (*power_off)(struct rtw_dev *rtwdev); + int (*mac_init)(struct rtw_dev *rtwdev); + int (*dump_fw_crash)(struct rtw_dev *rtwdev); + void (*shutdown)(struct rtw_dev *rtwdev); +@@ -2209,6 +2211,7 @@ void rtw_core_scan_start(struct rtw_dev + void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif, + bool hw_scan); + int rtw_core_start(struct rtw_dev *rtwdev); ++void rtw_power_off(struct rtw_dev *rtwdev); + void rtw_core_stop(struct rtw_dev *rtwdev); + int rtw_chip_info_setup(struct rtw_dev *rtwdev); + int rtw_core_init(struct rtw_dev *rtwdev); +@@ -2223,6 +2226,8 @@ int rtw_sta_add(struct rtw_dev *rtwdev, + void rtw_sta_remove(struct rtw_dev *rtwdev, struct ieee80211_sta *sta, + bool fw_exist); + void rtw_fw_recovery(struct rtw_dev *rtwdev); ++int rtw_wait_firmware_completion(struct rtw_dev *rtwdev); ++int rtw_power_on(struct rtw_dev *rtwdev); + void rtw_core_fw_scan_notify(struct rtw_dev *rtwdev, bool start); + int rtw_dump_fw(struct rtw_dev *rtwdev, const u32 ocp_src, u32 size, + u32 fwcd_item); +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1888,6 +1888,8 @@ static const struct coex_tdma_para tdma_ + }; + + static const struct rtw_chip_ops rtw8703b_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .mac_init = rtw8723x_mac_init, + .dump_fw_crash = NULL, + .shutdown = NULL, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -1390,6 +1390,8 @@ static void rtw8723d_pwr_track(struct rt + } + + static const struct rtw_chip_ops rtw8723d_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8723d_phy_set_param, + .read_efuse = rtw8723x_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1643,6 +1643,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8821c_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8821c_phy_set_param, + .read_efuse = rtw8821c_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2132,6 +2132,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8822b_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8822b_phy_set_param, + .read_efuse = rtw8822b_read_efuse, + .query_phy_status = query_phy_status, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4947,6 +4947,8 @@ static const struct rtw_prioq_addrs prio + }; + + static const struct rtw_chip_ops rtw8822c_ops = { ++ .power_on = rtw_power_on, ++ .power_off = rtw_power_off, + .phy_set_param = rtw8822c_phy_set_param, + .read_efuse = rtw8822c_read_efuse, + .query_phy_status = query_phy_status, diff --git a/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch new file mode 100644 index 00000000000000..153c04ee20fd60 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/030-v6.13-wifi-rtw88-Enable-data-rate-fallback-for-older-chips.patch @@ -0,0 +1,194 @@ +From c7706b1173c77185a2ef40c7d1811021566563f3 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:10:32 +0300 +Subject: [PATCH] wifi: rtw88: Enable data rate fallback for older chips + +RTL8811AU fails to perform the 4-way handshake when the AP is too far +because it transmits the EAPOL frames at MCS9 and when that doesn't +work it retries 48 times with the same rate, to no avail. + +Retrying 48 times with the same rate seems pointless. Set the +appropriate field in the TX descriptor to allow it to use lower rates +when retrying. + +Set it for RTL8723D and RTL8703B because they interpret this field the +same way as RTL8811A. + +The newer RTL8822C, RTL8822B, RTL8821C seem to interpret this field in +the TX descriptor differently, so leave it alone for those chips. + +Tested with RTL8811AU and RTL8723DU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/2b3e3e6f-541b-4a3b-8ca3-65b267e6a95a@gmail.com +--- + drivers/net/wireless/realtek/rtw88/fw.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 1 + + drivers/net/wireless/realtek/rtw88/pci.c | 2 +- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 1 + + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 1 + + drivers/net/wireless/realtek/rtw88/sdio.c | 2 +- + drivers/net/wireless/realtek/rtw88/tx.c | 6 +++++- + drivers/net/wireless/realtek/rtw88/tx.h | 4 +++- + drivers/net/wireless/realtek/rtw88/usb.c | 4 ++-- + 12 files changed, 19 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1290,7 +1290,7 @@ static void rtw_fill_rsvd_page_desc(stru + rtw_tx_rsvd_page_pkt_info_update(rtwdev, &pkt_info, skb, type); + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(&pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + + static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1204,6 +1204,7 @@ struct rtw_chip_info { + u8 usb_tx_agg_desc_num; + bool hw_feature_report; + u8 c2h_ra_report_size; ++ bool old_datarate_fb_limit; + + u8 default_1ss_tx_path; + +--- a/drivers/net/wireless/realtek/rtw88/pci.c ++++ b/drivers/net/wireless/realtek/rtw88/pci.c +@@ -824,7 +824,7 @@ static int rtw_pci_tx_write_data(struct + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, tx_pkt_desc_sz); + pkt_info->qsel = rtw_pci_get_tx_qsel(skb, queue); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + dma = dma_map_single(&rtwpci->pdev->dev, skb->data, skb->len, + DMA_TO_DEVICE); + if (dma_mapping_error(&rtwpci->pdev->dev, dma)) +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -1964,6 +1964,7 @@ const struct rtw_chip_info rtw8703b_hw_s + .usb_tx_agg_desc_num = 1, /* Not sure if this chip has USB interface */ + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + + .path_div_supported = false, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2135,6 +2135,7 @@ const struct rtw_chip_info rtw8723d_hw_s + .usb_tx_agg_desc_num = 1, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = true, + .ht_supported = true, + .vht_supported = false, + .lps_deep_mode_supported = 0, +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1972,6 +1972,7 @@ const struct rtw_chip_info rtw8821c_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2513,6 +2513,7 @@ const struct rtw_chip_info rtw8822b_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .ht_supported = true, + .vht_supported = true, + .lps_deep_mode_supported = BIT(LPS_DEEP_MODE_LCLK), +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -5333,6 +5333,7 @@ const struct rtw_chip_info rtw8822c_hw_s + .usb_tx_agg_desc_num = 3, + .hw_feature_report = true, + .c2h_ra_report_size = 7, ++ .old_datarate_fb_limit = false, + .default_1ss_tx_path = BB_PATH_A, + .path_div_supported = true, + .ht_supported = true, +--- a/drivers/net/wireless/realtek/rtw88/sdio.c ++++ b/drivers/net/wireless/realtek/rtw88/sdio.c +@@ -864,7 +864,7 @@ static void rtw_sdio_tx_skb_prepare(stru + + pkt_info->qsel = rtw_sdio_get_tx_qsel(rtwdev, skb, queue); + +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, pkt_desc); + } + +--- a/drivers/net/wireless/realtek/rtw88/tx.c ++++ b/drivers/net/wireless/realtek/rtw88/tx.c +@@ -32,7 +32,8 @@ void rtw_tx_stats(struct rtw_dev *rtwdev + } + } + +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) ++void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb) + { + struct rtw_tx_desc *tx_desc = (struct rtw_tx_desc *)skb->data; + bool more_data = false; +@@ -67,6 +68,9 @@ void rtw_tx_fill_tx_desc(struct rtw_tx_p + + tx_desc->w4 = le32_encode_bits(pkt_info->rate, RTW_TX_DESC_W4_DATARATE); + ++ if (rtwdev->chip->old_datarate_fb_limit) ++ tx_desc->w4 |= le32_encode_bits(0x1f, RTW_TX_DESC_W4_DATARATE_FB_LIMIT); ++ + tx_desc->w5 = le32_encode_bits(pkt_info->short_gi, RTW_TX_DESC_W5_DATA_SHORT) | + le32_encode_bits(pkt_info->bw, RTW_TX_DESC_W5_DATA_BW) | + le32_encode_bits(pkt_info->ldpc, RTW_TX_DESC_W5_DATA_LDPC) | +--- a/drivers/net/wireless/realtek/rtw88/tx.h ++++ b/drivers/net/wireless/realtek/rtw88/tx.h +@@ -44,6 +44,7 @@ struct rtw_tx_desc { + #define RTW_TX_DESC_W3_NAVUSEHDR BIT(15) + #define RTW_TX_DESC_W3_MAX_AGG_NUM GENMASK(21, 17) + #define RTW_TX_DESC_W4_DATARATE GENMASK(6, 0) ++#define RTW_TX_DESC_W4_DATARATE_FB_LIMIT GENMASK(12, 8) + #define RTW_TX_DESC_W4_RTSRATE GENMASK(28, 24) + #define RTW_TX_DESC_W5_DATA_SHORT BIT(4) + #define RTW_TX_DESC_W5_DATA_BW GENMASK(6, 5) +@@ -94,7 +95,8 @@ void rtw_tx_pkt_info_update(struct rtw_d + struct rtw_tx_pkt_info *pkt_info, + struct ieee80211_sta *sta, + struct sk_buff *skb); +-void rtw_tx_fill_tx_desc(struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); ++void rtw_tx_fill_tx_desc(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, struct sk_buff *skb); + void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn); + void rtw_tx_report_handle(struct rtw_dev *rtwdev, struct sk_buff *skb, int src); + void rtw_tx_rsvd_page_pkt_info_update(struct rtw_dev *rtwdev, +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -457,7 +457,7 @@ static int rtw_usb_write_data(struct rtw + skb_put_data(skb, buf, size); + skb_push(skb, chip->tx_pkt_desc_sz); + memset(skb->data, 0, chip->tx_pkt_desc_sz); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + + ret = rtw_usb_write_port(rtwdev, qsel, skb, +@@ -524,7 +524,7 @@ static int rtw_usb_tx_write(struct rtw_d + pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz); + memset(pkt_desc, 0, chip->tx_pkt_desc_sz); + ep = qsel_to_ep(rtwusb, pkt_info->qsel); +- rtw_tx_fill_tx_desc(pkt_info, skb); ++ rtw_tx_fill_tx_desc(rtwdev, pkt_info, skb); + rtw_tx_fill_txdesc_checksum(rtwdev, pkt_info, skb->data); + tx_data = rtw_usb_get_tx_data(skb); + tx_data->sn = pkt_info->sn; diff --git a/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch b/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch new file mode 100644 index 00000000000000..10fc773b47fe5c --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/031-v6.13-wifi-rtw88-Make-txagc_remnant_ofdm-an-array.patch @@ -0,0 +1,85 @@ +From abb0f19492ba6289ffba6ec1057c0426240958af Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:10:54 +0300 +Subject: [PATCH] wifi: rtw88: Make txagc_remnant_ofdm an array + +txagc_remnant_ofdm member of struct rtw_dm_info should be different for +each RF path, so make it an array of size RTW_RF_PATH_MAX (4). + +Until now all the chips using this had only one RF path, but RTL8812AU +has two, and RTL8814AU has four. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/68571ba9-e504-4b2d-bfa1-62f468753649@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + drivers/net/wireless/realtek/rtw88/phy.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 4 ++-- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 4 ++-- + 4 files changed, 7 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1715,7 +1715,7 @@ struct rtw_dm_info { + bool pwr_trk_init_trigger; + struct ewma_thermal avg_thermal[RTW_RF_PATH_MAX]; + s8 txagc_remnant_cck; +- s8 txagc_remnant_ofdm; ++ s8 txagc_remnant_ofdm[RTW_RF_PATH_MAX]; + u8 rx_cck_agc_report_type; + + /* backup dack results for each path and I/Q */ +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2169,8 +2169,8 @@ void rtw_get_tx_power_params(struct rtw_ + + *limit = rtw_phy_get_tx_power_limit(rtwdev, band, bw, path, + rate, ch, regd); +- *remnant = (rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : +- dm_info->txagc_remnant_ofdm); ++ *remnant = rate <= DESC_RATE11M ? dm_info->txagc_remnant_cck : ++ dm_info->txagc_remnant_ofdm[path]; + *sar = rtw_phy_get_tx_power_sar(rtwdev, hal->sar_band, path, rate); + } + +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -637,7 +637,7 @@ static void rtw8703b_pwrtrack_init(struc + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8703b_phy_set_param(struct rtw_dev *rtwdev) +@@ -1589,7 +1589,7 @@ static void rtw8703b_pwrtrack_set_ofdm_p + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + /* Only path A is calibrated for rtl8703b */ + rtw8703b_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -79,7 +79,7 @@ static void rtw8723d_pwrtrack_init(struc + dm_info->pwr_trk_init_trigger = true; + dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; + dm_info->txagc_remnant_cck = 0; +- dm_info->txagc_remnant_ofdm = 0; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = 0; + } + + static void rtw8723d_phy_set_param(struct rtw_dev *rtwdev) +@@ -1265,7 +1265,7 @@ static void rtw8723d_pwrtrack_set_ofdm_p + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; + +- dm_info->txagc_remnant_ofdm = txagc_idx; ++ dm_info->txagc_remnant_ofdm[RF_PATH_A] = txagc_idx; + + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_A); + rtw8723d_set_iqk_matrix(rtwdev, swing_idx, RF_PATH_B); diff --git a/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch b/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch new file mode 100644 index 00000000000000..7d77e0e67173e7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/032-v6.13-wifi-rtw88-Support-TX-page-sizes-bigger-than-128.patch @@ -0,0 +1,115 @@ +From 82a617413e8545775ec03a1970809ac5f549ef32 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:12:06 +0300 +Subject: [PATCH] wifi: rtw88: Support TX page sizes bigger than 128 + +All the chips supported so far have a TX page size of 128 bytes. + +Change the type of the page_size member of struct rtw_chip_info from u8 +to u16 in order to support RTL8821AU (page size of 256 bytes) and +RTL8812AU (page size of 512 bytes). Also change the types of several +related variables and function parameters from u8 to u16. + +The TX page size is used, among other things, to construct the beacon, +null data, QOS null data, and PS poll templates which are uploaded to +the chip's reserved page. Each template needs to be aligned on a +multiple of the TX page size. Power saving can't work if the TX page +size is wrong. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/acdefbb1-3daf-4349-9e03-9472754d5f1e@gmail.com +--- + drivers/net/wireless/realtek/rtw88/debug.c | 2 +- + drivers/net/wireless/realtek/rtw88/fw.c | 21 +++++++++++---------- + drivers/net/wireless/realtek/rtw88/mac.c | 2 +- + drivers/net/wireless/realtek/rtw88/main.h | 2 +- + 4 files changed, 14 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/debug.c ++++ b/drivers/net/wireless/realtek/rtw88/debug.c +@@ -308,7 +308,7 @@ static int rtw_debugfs_get_rsvd_page(str + { + struct rtw_debugfs_priv *debugfs_priv = m->private; + struct rtw_dev *rtwdev = debugfs_priv->rtwdev; +- u8 page_size = rtwdev->chip->page_size; ++ u16 page_size = rtwdev->chip->page_size; + u32 buf_size = debugfs_priv->rsvd_page.page_num * page_size; + u32 offset = debugfs_priv->rsvd_page.page_offset * page_size; + u8 *buf; +--- a/drivers/net/wireless/realtek/rtw88/fw.c ++++ b/drivers/net/wireless/realtek/rtw88/fw.c +@@ -1293,13 +1293,13 @@ static void rtw_fill_rsvd_page_desc(stru + rtw_tx_fill_tx_desc(rtwdev, &pkt_info, skb); + } + +-static inline u8 rtw_len_to_page(unsigned int len, u8 page_size) ++static inline u8 rtw_len_to_page(unsigned int len, u16 page_size) + { + return DIV_ROUND_UP(len, page_size); + } + +-static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u8 page_size, +- u8 page_margin, u32 page, u8 *buf, ++static void rtw_rsvd_page_list_to_buf(struct rtw_dev *rtwdev, u16 page_size, ++ u16 page_margin, u32 page, u8 *buf, + struct rtw_rsvd_page *rsvd_pkt) + { + struct sk_buff *skb = rsvd_pkt->skb; +@@ -1601,13 +1601,13 @@ static int __rtw_build_rsvd_page_from_v + + static u8 *rtw_build_rsvd_page(struct rtw_dev *rtwdev, u32 *size) + { +- struct ieee80211_hw *hw = rtwdev->hw; + const struct rtw_chip_info *chip = rtwdev->chip; +- struct sk_buff *iter; ++ struct ieee80211_hw *hw = rtwdev->hw; + struct rtw_rsvd_page *rsvd_pkt; +- u32 page = 0; ++ struct sk_buff *iter; ++ u16 page_size, page_margin, tx_desc_sz; + u8 total_page = 0; +- u8 page_size, page_margin, tx_desc_sz; ++ u32 page = 0; + u8 *buf; + int ret; + +@@ -2013,12 +2013,13 @@ static int _rtw_hw_scan_update_probe_req + { + const struct rtw_chip_info *chip = rtwdev->chip; + struct sk_buff *skb, *tmp; +- u8 page_offset = 1, *buf, page_size = chip->page_size; + u16 pg_addr = rtwdev->fifo.rsvd_h2c_info_addr, loc; +- u16 buf_offset = page_size * page_offset; + u8 tx_desc_sz = chip->tx_pkt_desc_sz; +- u8 page_cnt, pages; ++ u16 page_size = chip->page_size; ++ u8 page_offset = 1, *buf; ++ u16 buf_offset = page_size * page_offset; + unsigned int pkt_len; ++ u8 page_cnt, pages; + int ret; + + if (rtw_fw_feature_ext_check(&rtwdev->fw, FW_FEATURE_EXT_OLD_PAGE_NUM)) +--- a/drivers/net/wireless/realtek/rtw88/mac.c ++++ b/drivers/net/wireless/realtek/rtw88/mac.c +@@ -1138,7 +1138,7 @@ int rtw_set_trx_fifo_info(struct rtw_dev + + /* config rsvd page num */ + fifo->rsvd_drv_pg_num = chip->rsvd_drv_pg_num; +- fifo->txff_pg_num = chip->txff_size >> 7; ++ fifo->txff_pg_num = chip->txff_size / chip->page_size; + if (rtw_chip_wcpu_11n(rtwdev)) + fifo->rsvd_pg_num = fifo->rsvd_drv_pg_num; + else +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1187,7 +1187,7 @@ struct rtw_chip_info { + u32 fw_rxff_size; + u16 rsvd_drv_pg_num; + u8 band; +- u8 page_size; ++ u16 page_size; + u8 csi_buf_pg_num; + u8 dig_max; + u8 dig_min; diff --git a/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch b/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch new file mode 100644 index 00000000000000..cda3e7a56e0079 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/033-v6.13-wifi-rtw88-Move-pwr_track_tbl-to-struct-rtw_rfe_def.patch @@ -0,0 +1,297 @@ +From 67d915604e6993ff627ac001983a2de63ff71b13 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:12:39 +0300 +Subject: [PATCH] wifi: rtw88: Move pwr_track_tbl to struct rtw_rfe_def + +RTL8812AU uses one set of TX power tracking tables for RFE 3, and +another set for everything else. + +Move pwr_track_tbl from struct rtw_chip_info to struct rtw_rfe_def in +order to load the right set of tables for each RFE (RF front end) type. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/904d0ab1-c046-40cd-a3a3-d4fdcf663c9d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.h | 8 ++++--- + drivers/net/wireless/realtek/rtw88/phy.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8703b.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723d.c | 12 +++++----- + drivers/net/wireless/realtek/rtw88/rtw8723x.c | 3 ++- + drivers/net/wireless/realtek/rtw88/rtw8821c.c | 17 +++++++------- + drivers/net/wireless/realtek/rtw88/rtw8822b.c | 15 ++++++------ + drivers/net/wireless/realtek/rtw88/rtw8822c.c | 23 +++++++++---------- + 8 files changed, 47 insertions(+), 46 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1099,17 +1099,20 @@ enum rtw_rfe_fem { + struct rtw_rfe_def { + const struct rtw_table *phy_pg_tbl; + const struct rtw_table *txpwr_lmt_tbl; ++ const struct rtw_pwr_track_tbl *pwr_track_tbl; + const struct rtw_table *agc_btg_tbl; + }; + +-#define RTW_DEF_RFE(chip, bb_pg, pwrlmt) { \ ++#define RTW_DEF_RFE(chip, bb_pg, pwrlmt, track) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + } + +-#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, btg) { \ ++#define RTW_DEF_RFE_EXT(chip, bb_pg, pwrlmt, track, btg) { \ + .phy_pg_tbl = &rtw ## chip ## _bb_pg_type ## bb_pg ## _tbl, \ + .txpwr_lmt_tbl = &rtw ## chip ## _txpwr_lmt_type ## pwrlmt ## _tbl, \ ++ .pwr_track_tbl = &rtw ## chip ## _pwr_track_type ## track ## _tbl, \ + .agc_btg_tbl = &rtw ## chip ## _agc_btg_type ## btg ## _tbl, \ + } + +@@ -1243,7 +1246,6 @@ struct rtw_chip_info { + u16 dpd_ratemask; + u8 iqk_threshold; + u8 lck_threshold; +- const struct rtw_pwr_track_tbl *pwr_track_tbl; + + u8 bfer_su_max_num; + u8 bfer_mu_max_num; +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -2384,7 +2384,8 @@ void rtw_phy_init_tx_power(struct rtw_de + void rtw_phy_config_swing_table(struct rtw_dev *rtwdev, + struct rtw_swing_table *swing_table) + { +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + u8 channel = rtwdev->hal.current_channel; + + if (IS_CH_2G_BAND(channel)) { +--- a/drivers/net/wireless/realtek/rtw88/rtw8703b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8703b.c +@@ -493,11 +493,6 @@ static const struct rtw_pwr_seq_cmd * co + NULL + }; + +-static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl,}, +-}; +- + static const struct rtw_page_table page_table_8703b[] = { + {12, 2, 2, 0, 1}, + {12, 2, 2, 0, 1}, +@@ -1818,6 +1813,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_xtal_p = rtw8703b_pwrtrk_xtal_p, + }; + ++static const struct rtw_rfe_def rtw8703b_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8703b_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8703b_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, }, ++}; ++ + /* Shared-Antenna Coex Table */ + static const struct coex_table_para table_sant_8703b[] = { + {0xffffffff, 0xffffffff}, /* case-0 */ +@@ -1997,7 +1998,6 @@ const struct rtw_chip_info rtw8703b_hw_s + .rfe_defs_size = ARRAY_SIZE(rtw8703b_rfe_defs), + + .iqk_threshold = 8, +- .pwr_track_tbl = &rtw8703b_rtw_pwr_track_tbl, + + /* WOWLAN firmware exists, but not implemented yet */ + .wow_fw_name = "rtw88/rtw8703b_wow_fw.bin", +--- a/drivers/net/wireless/realtek/rtw88/rtw8723d.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723d.c +@@ -2020,11 +2020,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen1_para = ARRAY_SIZE(pcie_gen1_param_8723d), + }; + +-static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { +- [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, +- .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl,}, +-}; +- + static const u8 rtw8723d_pwrtrk_2gb_n[] = { + 0, 0, 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10 +@@ -2088,6 +2083,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_xtal_n = rtw8723d_pwrtrk_xtal_n, + }; + ++static const struct rtw_rfe_def rtw8723d_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8723d_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8723d_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, }, ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8723d[] = { + {0x948, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0x67, BIT(7), RTW_REG_DOMAIN_MAC8}, +@@ -2159,7 +2160,6 @@ const struct rtw_chip_info rtw8723d_hw_s + .rfe_defs = rtw8723d_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8723d_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8723d_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, + .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, +--- a/drivers/net/wireless/realtek/rtw88/rtw8723x.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8723x.c +@@ -595,7 +595,8 @@ void __rtw8723x_pwrtrack_set_xtal(struct + u8 delta) + { + struct rtw_dm_info *dm_info = &rtwdev->dm_info; +- const struct rtw_pwr_track_tbl *tbl = rtwdev->chip->pwr_track_tbl; ++ const struct rtw_rfe_def *rfe_def = rtw_get_rfe_def(rtwdev); ++ const struct rtw_pwr_track_tbl *tbl = rfe_def->pwr_track_tbl; + const s8 *pwrtrk_xtal; + s8 xtal_cap; + +--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.c +@@ -1581,13 +1581,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8821c), + }; + +-static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8821c, 0, 0), +- [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 2), +- [6] = RTW_DEF_RFE(8821c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8821c_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + }; +@@ -1899,7 +1892,7 @@ static const u8 rtw8821c_pwrtrk_2g_cck_a + 5, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9 + }; + +-static const struct rtw_pwr_track_tbl rtw8821c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8821c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[0] = rtw8821c_pwrtrk_5gb_n[0], + .pwrtrk_5gb_n[1] = rtw8821c_pwrtrk_5gb_n[1], + .pwrtrk_5gb_n[2] = rtw8821c_pwrtrk_5gb_n[2], +@@ -1922,6 +1915,13 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8821c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8821c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8821c, 0, 0, 0), ++ [2] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [4] = RTW_DEF_RFE_EXT(8821c, 0, 0, 0, 2), ++ [6] = RTW_DEF_RFE(8821c, 0, 0, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8821c[] = { + {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -1994,7 +1994,6 @@ const struct rtw_chip_info rtw8821c_hw_s + .rfe_defs = rtw8821c_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8821c_rfe_defs), + .rx_ldpc = false, +- .pwr_track_tbl = &rtw8821c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c +@@ -2072,12 +2072,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822b), + }; + +-static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { +- [2] = RTW_DEF_RFE(8822b, 2, 2), +- [3] = RTW_DEF_RFE(8822b, 3, 0), +- [5] = RTW_DEF_RFE(8822b, 5, 5), +-}; +- + static const struct rtw_hw_reg rtw8822b_dig[] = { + [0] = { .addr = 0xc50, .mask = 0x7f }, + [1] = { .addr = 0xe50, .mask = 0x7f }, +@@ -2432,7 +2426,7 @@ static const u8 rtw8822b_pwrtrk_2g_cck_a + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15 + }; + +-static const struct rtw_pwr_track_tbl rtw8822b_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822b_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822b_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -2455,6 +2449,12 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822b_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822b_rfe_defs[] = { ++ [2] = RTW_DEF_RFE(8822b, 2, 2, 0), ++ [3] = RTW_DEF_RFE(8822b, 3, 0, 0), ++ [5] = RTW_DEF_RFE(8822b, 5, 5, 0), ++}; ++ + static const struct rtw_reg_domain coex_info_hw_regs_8822b[] = { + {0xcb0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, + {0xcb4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, +@@ -2535,7 +2535,6 @@ const struct rtw_chip_info rtw8822b_hw_s + .rf_tbl = {&rtw8822b_rf_a_tbl, &rtw8822b_rf_b_tbl}, + .rfe_defs = rtw8822b_rfe_defs, + .rfe_defs_size = ARRAY_SIZE(rtw8822b_rfe_defs), +- .pwr_track_tbl = &rtw8822b_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .bfer_su_max_num = 2, + .bfer_mu_max_num = 1, +--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c +@@ -4883,16 +4883,6 @@ static const struct rtw_intf_phy_para_ta + .n_gen2_para = ARRAY_SIZE(pcie_gen2_param_8822c), + }; + +-static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { +- [0] = RTW_DEF_RFE(8822c, 0, 0), +- [1] = RTW_DEF_RFE(8822c, 0, 0), +- [2] = RTW_DEF_RFE(8822c, 0, 0), +- [3] = RTW_DEF_RFE(8822c, 0, 0), +- [4] = RTW_DEF_RFE(8822c, 0, 0), +- [5] = RTW_DEF_RFE(8822c, 0, 5), +- [6] = RTW_DEF_RFE(8822c, 0, 0), +-}; +- + static const struct rtw_hw_reg rtw8822c_dig[] = { + [0] = { .addr = 0x1d70, .mask = 0x7f }, + [1] = { .addr = 0x1d70, .mask = 0x7f00 }, +@@ -5238,7 +5228,7 @@ static const u8 rtw8822c_pwrtrk_2g_cck_a + 18, 18, 19, 20, 21, 22, 23, 24, 24, 25 + }; + +-static const struct rtw_pwr_track_tbl rtw8822c_rtw_pwr_track_tbl = { ++static const struct rtw_pwr_track_tbl rtw8822c_pwr_track_type0_tbl = { + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_1] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_1], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_2] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_2], + .pwrtrk_5gb_n[RTW_PWR_TRK_5G_3] = rtw8822c_pwrtrk_5gb_n[RTW_PWR_TRK_5G_3], +@@ -5261,6 +5251,16 @@ static const struct rtw_pwr_track_tbl rt + .pwrtrk_2g_ccka_p = rtw8822c_pwrtrk_2g_cck_a_p, + }; + ++static const struct rtw_rfe_def rtw8822c_rfe_defs[] = { ++ [0] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [1] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [2] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [3] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [4] = RTW_DEF_RFE(8822c, 0, 0, 0), ++ [5] = RTW_DEF_RFE(8822c, 0, 5, 0), ++ [6] = RTW_DEF_RFE(8822c, 0, 0, 0), ++}; ++ + static const struct rtw_hw_reg_offset rtw8822c_edcca_th[] = { + [EDCCA_TH_L2H_IDX] = { + {.addr = 0x84c, .mask = MASKBYTE2}, .offset = 0x80 +@@ -5360,7 +5360,6 @@ const struct rtw_chip_info rtw8822c_hw_s + .rfe_defs_size = ARRAY_SIZE(rtw8822c_rfe_defs), + .en_dis_dpd = true, + .dpd_ratemask = DIS_DPD_RATEALL, +- .pwr_track_tbl = &rtw8822c_rtw_pwr_track_tbl, + .iqk_threshold = 8, + .lck_threshold = 8, + .bfer_su_max_num = 2, diff --git a/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch b/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch new file mode 100644 index 00000000000000..7c6e13586080fc --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/034-v6.13-wifi-rtw88-usb-Set-pkt_info.ls-for-the-reserved-page.patch @@ -0,0 +1,27 @@ +From 85bf3041a0ea40a60b5295749268e179f056546a Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:13:10 +0300 +Subject: [PATCH] wifi: rtw88: usb: Set pkt_info.ls for the reserved page + +"ls" meaning "last segment". Without this RTL8812AU can't upload the +reserved page in USB 2 mode. (Somehow it's fine in USB 3 mode.) + +Also tested with RTL8822CU, RTL8812BU, RTL8811CU, RTL8723DU, RTL8811AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/e443f5d9-4b53-4f64-985c-64313ec80bef@gmail.com +--- + drivers/net/wireless/realtek/rtw88/usb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -477,6 +477,7 @@ static int rtw_usb_write_data_rsvd_page( + pkt_info.tx_pkt_size = size; + pkt_info.qsel = TX_DESC_QSEL_BEACON; + pkt_info.offset = chip->tx_pkt_desc_sz; ++ pkt_info.ls = true; + + return rtw_usb_write_data(rtwdev, &pkt_info, buf); + } diff --git a/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch b/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch new file mode 100644 index 00000000000000..de64f33e43e5b4 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/035-v6.13-wifi-rtw88-Detect-beacon-loss-with-chips-other-than-.patch @@ -0,0 +1,63 @@ +From 57289d30cd2ae315ab9b28213d63d1dbf8570cf3 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:13:45 +0300 +Subject: [PATCH] wifi: rtw88: Detect beacon loss with chips other than 8822c + +The driver is supposed to avoid entering LPS (power saving) when there +is beacon loss, but only RTL8822C detects the beacon loss (because it +has beacon filtering in the firmware). + +Detect beacon loss with the other chips by checking if we received less +than half the expected number of beacons in the last 2-second interval. + +This gets rid of the occasional "failed to get tx report from firmware" +warnings with RTL8821AU. It may also avoid some disconnections. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/f52b2fcf-bf94-48bc-89bd-e55ebc3a2f2d@gmail.com +--- + drivers/net/wireless/realtek/rtw88/main.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -202,6 +202,21 @@ static void rtw_vif_watch_dog_iter(void + rtwvif->stats.rx_cnt = 0; + } + ++static void rtw_sw_beacon_loss_check(struct rtw_dev *rtwdev, ++ struct rtw_vif *rtwvif, int received_beacons) ++{ ++ int watchdog_delay = 2000000 / 1024; /* TU */ ++ int beacon_int, expected_beacons; ++ ++ if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER) || !rtwvif) ++ return; ++ ++ beacon_int = rtwvif_to_vif(rtwvif)->bss_conf.beacon_int; ++ expected_beacons = DIV_ROUND_UP(watchdog_delay, beacon_int); ++ ++ rtwdev->beacon_loss = received_beacons < expected_beacons / 2; ++} ++ + /* process TX/RX statistics periodically for hardware, + * the information helps hardware to enhance performance + */ +@@ -212,6 +227,7 @@ static void rtw_watch_dog_work(struct wo + struct rtw_traffic_stats *stats = &rtwdev->stats; + struct rtw_watch_dog_iter_data data = {}; + bool busy_traffic = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags); ++ int received_beacons = rtwdev->dm_info.cur_pkt_count.num_bcn_pkt; + u32 tx_unicast_mbps, rx_unicast_mbps; + bool ps_active; + +@@ -270,6 +286,8 @@ static void rtw_watch_dog_work(struct wo + */ + rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); + ++ rtw_sw_beacon_loss_check(rtwdev, data.rtwvif, received_beacons); ++ + /* fw supports only one station associated to enter lps, if there are + * more than two stations associated to the AP, then we can not enter + * lps, because fw does not handle the overlapped beacon interval diff --git a/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch b/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch new file mode 100644 index 00000000000000..b2fb04fd31c325 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/036-v6.13-wifi-rtw88-coex-Support-chips-without-a-scoreboard.patch @@ -0,0 +1,66 @@ +From b19840afc05121293ae59f017cb9924814eb5d77 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:14:12 +0300 +Subject: [PATCH] wifi: rtw88: coex: Support chips without a scoreboard + +All the chips currently supported have a "scoreboard": the chip keeps +track of certain things related to bluetooth, for example, whether +bluetooth is active. The information can be read from register 0xaa. + +RTL8821AU doesn't have this. Implement bluetooth activity detection in +rtw_coex_monitor_bt_enable() based on the bluetooth TX/RX counters. + +This is mostly important for RTL8811AU, the version of RTL8821AU without +bluetooth. Without this change, the driver thinks bluetooth is active +and the wifi speeds are low. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/5058f23d-2086-42cd-82ad-eef31a348467@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 18 ++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/main.h | 1 + + 2 files changed, 19 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -494,11 +494,29 @@ static void rtw_coex_monitor_bt_enable(s + struct rtw_coex_stat *coex_stat = &coex->stat; + struct rtw_coex_dm *coex_dm = &coex->dm; + bool bt_disabled = false; ++ bool bt_active = true; + u16 score_board; + + if (chip->scbd_support) { + score_board = rtw_coex_read_scbd(rtwdev); + bt_disabled = !(score_board & COEX_SCBD_ONOFF); ++ } else { ++ if (coex_stat->hi_pri_tx == 0 && coex_stat->hi_pri_rx == 0 && ++ coex_stat->lo_pri_tx == 0 && coex_stat->lo_pri_rx == 0) ++ bt_active = false; ++ ++ if (coex_stat->hi_pri_tx == 0xffff && coex_stat->hi_pri_rx == 0xffff && ++ coex_stat->lo_pri_tx == 0xffff && coex_stat->lo_pri_rx == 0xffff) ++ bt_active = false; ++ ++ if (bt_active) { ++ coex_stat->bt_disable_cnt = 0; ++ bt_disabled = false; ++ } else { ++ coex_stat->bt_disable_cnt++; ++ if (coex_stat->bt_disable_cnt >= 10) ++ bt_disabled = true; ++ } + } + + if (coex_stat->bt_disabled != bt_disabled) { +--- a/drivers/net/wireless/realtek/rtw88/main.h ++++ b/drivers/net/wireless/realtek/rtw88/main.h +@@ -1494,6 +1494,7 @@ struct rtw_coex_stat { + u8 bt_hid_slot; + u8 bt_a2dp_bitpool; + u8 bt_iqk_state; ++ u8 bt_disable_cnt; + + u16 wl_beacon_interval; + u8 wl_noisy_level; diff --git a/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch b/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch new file mode 100644 index 00000000000000..e0e840f0fadfeb --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/037-v6.13-wifi-rtw88-8821a-Regularly-ask-for-BT-info-updates.patch @@ -0,0 +1,67 @@ +From bfcee5ee924fc5f706d20f5dc31586ca47912304 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:14:45 +0300 +Subject: [PATCH] wifi: rtw88: 8821a: Regularly ask for BT info updates + +The RTL8821AU firmware sends C2H_BT_INFO by itself when bluetooth +headphones are connected, but not when they are disconnected. This leads +to the coexistence code still using the A2DP algorithm long after the +headphones are disconnected, which means the wifi speeds are much lower +than they should be. Work around this by asking for updates every two +seconds if the chip is RTL8821AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/358acdd2-6aae-46c1-9c66-fcce4e700b96@gmail.com +--- + drivers/net/wireless/realtek/rtw88/coex.c | 2 +- + drivers/net/wireless/realtek/rtw88/coex.h | 11 +++++++++++ + drivers/net/wireless/realtek/rtw88/main.c | 1 + + 3 files changed, 13 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/coex.c ++++ b/drivers/net/wireless/realtek/rtw88/coex.c +@@ -446,7 +446,7 @@ static void rtw_coex_check_rfk(struct rt + } + } + +-static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev) + { + struct rtw_coex *coex = &rtwdev->coex; + struct rtw_coex_stat *coex_stat = &coex->stat; +--- a/drivers/net/wireless/realtek/rtw88/coex.h ++++ b/drivers/net/wireless/realtek/rtw88/coex.h +@@ -384,6 +384,7 @@ u32 rtw_coex_read_indirect_reg(struct rt + void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr, + u32 mask, u32 val); + void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set); ++void rtw_coex_query_bt_info(struct rtw_dev *rtwdev); + + void rtw_coex_bt_relink_work(struct work_struct *work); + void rtw_coex_bt_reenable_work(struct work_struct *work); +@@ -419,4 +420,14 @@ static inline bool rtw_coex_disabled(str + return coex_stat->bt_disabled; + } + ++static inline void rtw_coex_active_query_bt_info(struct rtw_dev *rtwdev) ++{ ++ /* The RTL8821AU firmware doesn't send C2H_BT_INFO by itself ++ * when bluetooth headphones are disconnected, so we have to ++ * ask for it regularly. ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A && rtwdev->efuse.btcoex) ++ rtw_coex_query_bt_info(rtwdev); ++} ++ + #endif +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -274,6 +274,7 @@ static void rtw_watch_dog_work(struct wo + rtw_leave_lps(rtwdev); + rtw_coex_wl_status_check(rtwdev); + rtw_coex_query_bt_hid_list(rtwdev); ++ rtw_coex_active_query_bt_info(rtwdev); + + rtw_phy_dynamic_mechanism(rtwdev); + diff --git a/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch b/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch new file mode 100644 index 00000000000000..f862f80460df36 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/038-v6.13-wifi-rtw88-8812a-Mitigate-beacon-loss.patch @@ -0,0 +1,37 @@ +From f9e0189cbc2d6447dde392944c769546cdf48140 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 23 Oct 2024 17:15:13 +0300 +Subject: [PATCH] wifi: rtw88: 8812a: Mitigate beacon loss + +The RTL8812AU has a reception problem, maybe only in the 5 GHz band. +Sometimes, in some positions, it stops receiving anything even though +the distance to the AP is only ~3 meters and there are no obstacles. +Moving it a few centimeters fixes it. + +Switch the initial gain to maximum coverage when there is beacon loss. +This only helps sometimes. This is similar to what the official driver +does. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/203f5043-4fe1-4f35-8b8f-d3b6f44e1fd9@gmail.com +--- + drivers/net/wireless/realtek/rtw88/phy.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/phy.c ++++ b/drivers/net/wireless/realtek/rtw88/phy.c +@@ -530,6 +530,13 @@ static void rtw_phy_dig(struct rtw_dev * + */ + rtw_phy_dig_recorder(dm_info, cur_igi, fa_cnt); + ++ /* Mitigate beacon loss and connectivity issues, mainly (only?) ++ * in the 5 GHz band ++ */ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A && rtwdev->beacon_loss && ++ linked && dm_info->total_fa_cnt < DIG_PERF_FA_TH_EXTRA_HIGH) ++ cur_igi = DIG_CVRG_MIN; ++ + if (cur_igi != pre_igi) + rtw_phy_dig_write(rtwdev, cur_igi); + } diff --git a/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch b/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch new file mode 100644 index 00000000000000..59a04b4d16b579 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/039-v6.13-wifi-rtw88-Add-rtw8812a_table.-c-h.patch @@ -0,0 +1,2862 @@ +From 528f902ecc0eb8fb766bde519421255729623dd8 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:24:33 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8812a_table.{c,h} + +These contain various arrays for initialising RTL8812AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/086f476c-e832-4867-963c-a64a63252fd6@gmail.com +--- + .../wireless/realtek/rtw88/rtw8812a_table.c | 2812 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8812a_table.h | 26 + + 2 files changed, 2838 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a_table.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.c +@@ -0,0 +1,2812 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8812a_table.h" ++ ++static const u32 rtw8812a_mac[] = { ++ 0x010, 0x0000000C, ++ 0x80000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x011, 0x00000066, ++ 0xA0000000, 0x00000000, ++ 0x011, 0x0000005A, ++ 0xB0000000, 0x00000000, ++ 0x025, 0x0000000F, ++ 0x072, 0x00000000, ++ 0x420, 0x00000080, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000000, ++ 0x432, 0x00000000, ++ 0x433, 0x00000001, ++ 0x434, 0x00000002, ++ 0x435, 0x00000003, ++ 0x436, 0x00000005, ++ 0x437, 0x00000007, ++ 0x438, 0x00000000, ++ 0x439, 0x00000000, ++ 0x43A, 0x00000000, ++ 0x43B, 0x00000001, ++ 0x43C, 0x00000002, ++ 0x43D, 0x00000003, ++ 0x43E, 0x00000005, ++ 0x43F, 0x00000007, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000010, ++ 0x445, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x45B, 0x00000080, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x000000FF, ++ 0x4C9, 0x00000008, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x604, 0x00000009, ++ 0x605, 0x00000030, ++ 0x607, 0x00000003, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000080, ++ 0x642, 0x00000040, ++ 0x643, 0x00000000, ++ 0x652, 0x000000C8, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++ 0x718, 0x00000040, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8812a_agc[] = { ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC000001, ++ 0x81C, 0xFB020001, ++ 0x81C, 0xFA040001, ++ 0x81C, 0xF9060001, ++ 0x81C, 0xF8080001, ++ 0x81C, 0xF70A0001, ++ 0x81C, 0xF60C0001, ++ 0x81C, 0xF50E0001, ++ 0x81C, 0xF4100001, ++ 0x81C, 0xF3120001, ++ 0x81C, 0xF2140001, ++ 0x81C, 0xF1160001, ++ 0x81C, 0xF0180001, ++ 0x81C, 0xEF1A0001, ++ 0x81C, 0xEE1C0001, ++ 0x81C, 0xED1E0001, ++ 0x81C, 0xEC200001, ++ 0x81C, 0xEB220001, ++ 0x81C, 0xEA240001, ++ 0x81C, 0xCD260001, ++ 0x81C, 0xCC280001, ++ 0x81C, 0xCB2A0001, ++ 0x81C, 0xCA2C0001, ++ 0x81C, 0xC92E0001, ++ 0x81C, 0xC8300001, ++ 0x81C, 0xA6320001, ++ 0x81C, 0xA5340001, ++ 0x81C, 0xA4360001, ++ 0x81C, 0xA3380001, ++ 0x81C, 0xA23A0001, ++ 0x81C, 0x883C0001, ++ 0x81C, 0x873E0001, ++ 0x81C, 0x86400001, ++ 0x81C, 0x85420001, ++ 0x81C, 0x84440001, ++ 0x81C, 0x83460001, ++ 0x81C, 0x82480001, ++ 0x81C, 0x814A0001, ++ 0x81C, 0x484C0001, ++ 0x81C, 0x474E0001, ++ 0x81C, 0x46500001, ++ 0x81C, 0x45520001, ++ 0x81C, 0x44540001, ++ 0x81C, 0x43560001, ++ 0x81C, 0x42580001, ++ 0x81C, 0x415A0001, ++ 0x81C, 0x255C0001, ++ 0x81C, 0x245E0001, ++ 0x81C, 0x23600001, ++ 0x81C, 0x22620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x216C0001, ++ 0x81C, 0x216E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x81C, 0xF9000001, ++ 0x81C, 0xF8020001, ++ 0x81C, 0xF7040001, ++ 0x81C, 0xF6060001, ++ 0x81C, 0xF5080001, ++ 0x81C, 0xF40A0001, ++ 0x81C, 0xF30C0001, ++ 0x81C, 0xF20E0001, ++ 0x81C, 0xF1100001, ++ 0x81C, 0xF0120001, ++ 0x81C, 0xEF140001, ++ 0x81C, 0xEE160001, ++ 0x81C, 0xED180001, ++ 0x81C, 0xEC1A0001, ++ 0x81C, 0xEB1C0001, ++ 0x81C, 0xEA1E0001, ++ 0x81C, 0xCD200001, ++ 0x81C, 0xCC220001, ++ 0x81C, 0xCB240001, ++ 0x81C, 0xCA260001, ++ 0x81C, 0xC9280001, ++ 0x81C, 0xC82A0001, ++ 0x81C, 0xC72C0001, ++ 0x81C, 0xC62E0001, ++ 0x81C, 0xA5300001, ++ 0x81C, 0xA4320001, ++ 0x81C, 0xA3340001, ++ 0x81C, 0xA2360001, ++ 0x81C, 0x88380001, ++ 0x81C, 0x873A0001, ++ 0x81C, 0x863C0001, ++ 0x81C, 0x853E0001, ++ 0x81C, 0x84400001, ++ 0x81C, 0x83420001, ++ 0x81C, 0x82440001, ++ 0x81C, 0x81460001, ++ 0x81C, 0x48480001, ++ 0x81C, 0x474A0001, ++ 0x81C, 0x464C0001, ++ 0x81C, 0x454E0001, ++ 0x81C, 0x44500001, ++ 0x81C, 0x43520001, ++ 0x81C, 0x42540001, ++ 0x81C, 0x41560001, ++ 0x81C, 0x25580001, ++ 0x81C, 0x245A0001, ++ 0x81C, 0x235C0001, ++ 0x81C, 0x225E0001, ++ 0x81C, 0x21600001, ++ 0x81C, 0x21620001, ++ 0x81C, 0x21640001, ++ 0x81C, 0x21660001, ++ 0x81C, 0x21680001, ++ 0x81C, 0x216A0001, ++ 0x81C, 0x236C0001, ++ 0x81C, 0x226E0001, ++ 0x81C, 0x21700001, ++ 0x81C, 0x21720001, ++ 0x81C, 0x21740001, ++ 0x81C, 0x21760001, ++ 0x81C, 0x21780001, ++ 0x81C, 0x217A0001, ++ 0x81C, 0x217C0001, ++ 0x81C, 0x217E0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000001, ++ 0x81C, 0xFF020001, ++ 0x81C, 0xFF040001, ++ 0x81C, 0xFF060001, ++ 0x81C, 0xFF080001, ++ 0x81C, 0xFE0A0001, ++ 0x81C, 0xFD0C0001, ++ 0x81C, 0xFC0E0001, ++ 0x81C, 0xFB100001, ++ 0x81C, 0xFA120001, ++ 0x81C, 0xF9140001, ++ 0x81C, 0xF8160001, ++ 0x81C, 0xF7180001, ++ 0x81C, 0xF61A0001, ++ 0x81C, 0xF51C0001, ++ 0x81C, 0xF41E0001, ++ 0x81C, 0xF3200001, ++ 0x81C, 0xF2220001, ++ 0x81C, 0xF1240001, ++ 0x81C, 0xF0260001, ++ 0x81C, 0xEF280001, ++ 0x81C, 0xEE2A0001, ++ 0x81C, 0xED2C0001, ++ 0x81C, 0xEC2E0001, ++ 0x81C, 0xEB300001, ++ 0x81C, 0xEA320001, ++ 0x81C, 0xE9340001, ++ 0x81C, 0xE8360001, ++ 0x81C, 0xE7380001, ++ 0x81C, 0xE63A0001, ++ 0x81C, 0xE53C0001, ++ 0x81C, 0xC73E0001, ++ 0x81C, 0xC6400001, ++ 0x81C, 0xC5420001, ++ 0x81C, 0xC4440001, ++ 0x81C, 0xC3460001, ++ 0x81C, 0xC2480001, ++ 0x81C, 0xC14A0001, ++ 0x81C, 0xA74C0001, ++ 0x81C, 0xA64E0001, ++ 0x81C, 0xA5500001, ++ 0x81C, 0xA4520001, ++ 0x81C, 0xA3540001, ++ 0x81C, 0xA2560001, ++ 0x81C, 0xA1580001, ++ 0x81C, 0x675A0001, ++ 0x81C, 0x665C0001, ++ 0x81C, 0x655E0001, ++ 0x81C, 0x64600001, ++ 0x81C, 0x63620001, ++ 0x81C, 0x48640001, ++ 0x81C, 0x47660001, ++ 0x81C, 0x46680001, ++ 0x81C, 0x456A0001, ++ 0x81C, 0x446C0001, ++ 0x81C, 0x436E0001, ++ 0x81C, 0x42700001, ++ 0x81C, 0x41720001, ++ 0x81C, 0x41740001, ++ 0x81C, 0x41760001, ++ 0x81C, 0x41780001, ++ 0x81C, 0x417A0001, ++ 0x81C, 0x417C0001, ++ 0x81C, 0x417E0001, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFC800001, ++ 0x81C, 0xFB820001, ++ 0x81C, 0xFA840001, ++ 0x81C, 0xF9860001, ++ 0x81C, 0xF8880001, ++ 0x81C, 0xF78A0001, ++ 0x81C, 0xF68C0001, ++ 0x81C, 0xF58E0001, ++ 0x81C, 0xF4900001, ++ 0x81C, 0xF3920001, ++ 0x81C, 0xF2940001, ++ 0x81C, 0xF1960001, ++ 0x81C, 0xF0980001, ++ 0x81C, 0xEF9A0001, ++ 0x81C, 0xEE9C0001, ++ 0x81C, 0xED9E0001, ++ 0x81C, 0xECA00001, ++ 0x81C, 0xEBA20001, ++ 0x81C, 0xEAA40001, ++ 0x81C, 0xE9A60001, ++ 0x81C, 0xE8A80001, ++ 0x81C, 0xE7AA0001, ++ 0x81C, 0xE6AC0001, ++ 0x81C, 0xE5AE0001, ++ 0x81C, 0xE4B00001, ++ 0x81C, 0xE3B20001, ++ 0x81C, 0xA8B40001, ++ 0x81C, 0xA7B60001, ++ 0x81C, 0xA6B80001, ++ 0x81C, 0xA5BA0001, ++ 0x81C, 0xA4BC0001, ++ 0x81C, 0xA3BE0001, ++ 0x81C, 0xA2C00001, ++ 0x81C, 0xA1C20001, ++ 0x81C, 0x68C40001, ++ 0x81C, 0x67C60001, ++ 0x81C, 0x66C80001, ++ 0x81C, 0x65CA0001, ++ 0x81C, 0x64CC0001, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0x81C, 0x01E80001, ++ 0x81C, 0x01EA0001, ++ 0x81C, 0x01EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF800001, ++ 0x81C, 0xFF820001, ++ 0x81C, 0xFF840001, ++ 0x81C, 0xFE860001, ++ 0x81C, 0xFD880001, ++ 0x81C, 0xFC8A0001, ++ 0x81C, 0xFB8C0001, ++ 0x81C, 0xFA8E0001, ++ 0x81C, 0xF9900001, ++ 0x81C, 0xF8920001, ++ 0x81C, 0xF7940001, ++ 0x81C, 0xF6960001, ++ 0x81C, 0xF5980001, ++ 0x81C, 0xF49A0001, ++ 0x81C, 0xF39C0001, ++ 0x81C, 0xF29E0001, ++ 0x81C, 0xF1A00001, ++ 0x81C, 0xF0A20001, ++ 0x81C, 0xEFA40001, ++ 0x81C, 0xEEA60001, ++ 0x81C, 0xEDA80001, ++ 0x81C, 0xECAA0001, ++ 0x81C, 0xEBAC0001, ++ 0x81C, 0xEAAE0001, ++ 0x81C, 0xE9B00001, ++ 0x81C, 0xE8B20001, ++ 0x81C, 0xE7B40001, ++ 0x81C, 0xE6B60001, ++ 0x81C, 0xE5B80001, ++ 0x81C, 0xE4BA0001, ++ 0x81C, 0xE3BC0001, ++ 0x81C, 0xA8BE0001, ++ 0x81C, 0xA7C00001, ++ 0x81C, 0xA6C20001, ++ 0x81C, 0xA5C40001, ++ 0x81C, 0xA4C60001, ++ 0x81C, 0xA3C80001, ++ 0x81C, 0xA2CA0001, ++ 0x81C, 0xA1CC0001, ++ 0x81C, 0x68CE0001, ++ 0x81C, 0x67D00001, ++ 0x81C, 0x66D20001, ++ 0x81C, 0x65D40001, ++ 0x81C, 0x64D60001, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0x81C, 0x01F20001, ++ 0x81C, 0x01F40001, ++ 0x81C, 0x01F60001, ++ 0x81C, 0x01F80001, ++ 0x81C, 0x01FA0001, ++ 0x81C, 0x01FC0001, ++ 0x81C, 0x01FE0001, ++ 0xB0000000, 0x00000000, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++ 0xE50, 0x00000022, ++ 0xE50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_lb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x47CE0001, ++ 0x81C, 0x46D00001, ++ 0x81C, 0x45D20001, ++ 0x81C, 0x44D40001, ++ 0x81C, 0x43D60001, ++ 0x81C, 0x42D80001, ++ 0x81C, 0x08DA0001, ++ 0x81C, 0x07DC0001, ++ 0x81C, 0x06DE0001, ++ 0x81C, 0x05E00001, ++ 0x81C, 0x04E20001, ++ 0x81C, 0x03E40001, ++ 0x81C, 0x02E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x47D80001, ++ 0x81C, 0x46DA0001, ++ 0x81C, 0x45DC0001, ++ 0x81C, 0x44DE0001, ++ 0x81C, 0x43E00001, ++ 0x81C, 0x42E20001, ++ 0x81C, 0x08E40001, ++ 0x81C, 0x07E60001, ++ 0x81C, 0x06E80001, ++ 0x81C, 0x05EA0001, ++ 0x81C, 0x04EC0001, ++ 0x81C, 0x03EE0001, ++ 0x81C, 0x02F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_lb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_agc_diff_hb[] = { ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0x45CE0001, ++ 0x81C, 0x44D00001, ++ 0x81C, 0x43D20001, ++ 0x81C, 0x42D40001, ++ 0x81C, 0x08D60001, ++ 0x81C, 0x07D80001, ++ 0x81C, 0x06DA0001, ++ 0x81C, 0x05DC0001, ++ 0x81C, 0x04DE0001, ++ 0x81C, 0x03E00001, ++ 0x81C, 0x02E20001, ++ 0x81C, 0x01E40001, ++ 0x81C, 0x01E60001, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0x45D80001, ++ 0x81C, 0x44DA0001, ++ 0x81C, 0x43DC0001, ++ 0x81C, 0x42DE0001, ++ 0x81C, 0x08E00001, ++ 0x81C, 0x07E20001, ++ 0x81C, 0x06E40001, ++ 0x81C, 0x05E60001, ++ 0x81C, 0x04E80001, ++ 0x81C, 0x03EA0001, ++ 0x81C, 0x02EC0001, ++ 0x81C, 0x01EE0001, ++ 0x81C, 0x01F00001, ++ 0xB0000000, 0x00000000, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_agc_diff_hb, rtw_phy_cfg_agc); ++ ++static const u32 rtw8812a_bb[] = { ++ 0x800, 0x8020D010, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028233, ++ 0x80C, 0x12131113, ++ 0x810, 0x20101263, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002083DD, ++ 0x830, 0x2EAAEEB8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06C89B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x6210FF8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x338C2878, ++ 0x870, 0x03333333, ++ 0x874, 0x31602C2E, ++ 0x878, 0x00003152, ++ 0x87C, 0x000FC000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA202033E, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B0, 0x00000600, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x4CA520A3, ++ 0x8C0, 0x27F00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00012D69, ++ 0x8CC, 0x08248492, ++ 0x8D0, 0x0000B800, ++ 0x8DC, 0x00000000, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000701, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00080080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x00000000, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x000002D5, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF000C, ++ 0xA08, 0x8C838300, ++ 0xA0C, 0x2E7F000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1217, ++ 0xA28, 0x00000305, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x218075B2, ++ 0xA84, 0x001F8C80, ++ 0xB00, 0x03100000, ++ 0xB04, 0x0000B000, ++ 0xB08, 0xAE0201EB, ++ 0xB0C, 0x01003207, ++ 0xB10, 0x00009807, ++ 0xB14, 0x01000000, ++ 0xB18, 0x00000002, ++ 0xB1C, 0x00000002, ++ 0xB20, 0x0000001F, ++ 0xB24, 0x03020100, ++ 0xB28, 0x07060504, ++ 0xB2C, 0x0B0A0908, ++ 0xB30, 0x0F0E0D0C, ++ 0xB34, 0x13121110, ++ 0xB38, 0x17161514, ++ 0xB3C, 0x0000003A, ++ 0xB40, 0x00000000, ++ 0xB44, 0x00000000, ++ 0xB48, 0x13000032, ++ 0xB4C, 0x48080000, ++ 0xB50, 0x00000000, ++ 0xB54, 0x00000000, ++ 0xB58, 0x00000000, ++ 0xB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x12121212, ++ 0xC24, 0x12121212, ++ 0xC28, 0x12121212, ++ 0xC2C, 0x12121212, ++ 0xC30, 0x12121212, ++ 0xC34, 0x12121212, ++ 0xC38, 0x12121212, ++ 0xC3C, 0x12121212, ++ 0xC40, 0x12121212, ++ 0xC44, 0x12121212, ++ 0xC48, 0x12121212, ++ 0xC4C, 0x12121212, ++ 0xC50, 0x00000020, ++ 0xC54, 0x0008121C, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000004, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000000, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0xC68, 0x59791979, ++ 0xA0000000, 0x00000000, ++ 0xC68, 0x59799979, ++ 0xB0000000, 0x00000000, ++ 0xC6C, 0x59795979, ++ 0xC70, 0x19795979, ++ 0xC74, 0x19795979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77547777, ++ 0xCB4, 0x00000077, ++ 0xCB8, 0x00508242, ++ 0xE00, 0x00000007, ++ 0xE04, 0x00042020, ++ 0xE08, 0x80410231, ++ 0xE0C, 0x00000000, ++ 0xE10, 0x00000100, ++ 0xE14, 0x01000000, ++ 0xE1C, 0x40000003, ++ 0xE20, 0x12121212, ++ 0xE24, 0x12121212, ++ 0xE28, 0x12121212, ++ 0xE2C, 0x12121212, ++ 0xE30, 0x12121212, ++ 0xE34, 0x12121212, ++ 0xE38, 0x12121212, ++ 0xE3C, 0x12121212, ++ 0xE40, 0x12121212, ++ 0xE44, 0x12121212, ++ 0xE48, 0x12121212, ++ 0xE4C, 0x12121212, ++ 0xE50, 0x00000020, ++ 0xE54, 0x0008121C, ++ 0xE58, 0x30000C1C, ++ 0xE5C, 0x00000058, ++ 0xE60, 0x34344443, ++ 0xE64, 0x07003333, ++ 0xE68, 0x59791979, ++ 0xE6C, 0x59795979, ++ 0xE70, 0x19795979, ++ 0xE74, 0x19795979, ++ 0xE78, 0x19791979, ++ 0xE7C, 0x19791979, ++ 0xE80, 0x19791979, ++ 0xE84, 0x19791979, ++ 0xE94, 0x0100005C, ++ 0xE98, 0x00000000, ++ 0xE9C, 0x00000000, ++ 0xEA0, 0x00000029, ++ 0xEA4, 0x08040201, ++ 0xEA8, 0x80402010, ++ 0xEB0, 0x77547777, ++ 0xEB4, 0x00000077, ++ 0xEB8, 0x00508242, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8812a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34363840, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x30323638, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34363840, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x30323638, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x42424444, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x30323640, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x28303236, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x38404242, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x26283034, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x40424444, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x28303236, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x42422426, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x30343840, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22242628, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x42424444, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x30323640, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x28303236, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x38404242, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x26283034, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x40424444, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x28303236, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x42422426, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x30343840, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22242628, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8812a_bb_pg_rfe3[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x34343434, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x28303232, }, ++ { 0, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c38, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x28303232, }, ++ { 0, 0, 0, 0x00000c44, 0xffffffff, 0x32322426, }, ++ { 0, 0, 1, 0x00000c48, 0xffffffff, 0x32323232, }, ++ { 0, 0, 1, 0x00000c4c, 0xffffffff, 0x24262830, }, ++ { 0, 1, 0, 0x00000e20, 0xffffffff, 0x34343434, }, ++ { 0, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e30, 0xffffffff, 0x28303232, }, ++ { 0, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e38, 0xffffffff, 0x26283032, }, ++ { 0, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 0, 1, 0, 0x00000e40, 0xffffffff, 0x28303232, }, ++ { 0, 1, 0, 0x00000e44, 0xffffffff, 0x32322426, }, ++ { 0, 1, 1, 0x00000e48, 0xffffffff, 0x32323232, }, ++ { 0, 1, 1, 0x00000e4c, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x28303232, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 1, 0x00000c34, 0xffffffff, 0x32323232, }, ++ { 1, 0, 1, 0x00000c38, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32323232, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0xffffffff, 0x32322222, }, ++ { 1, 0, 1, 0x00000c48, 0xffffffff, 0x28303232, }, ++ { 1, 0, 1, 0x00000c4c, 0xffffffff, 0x22222426, }, ++ { 1, 1, 0, 0x00000e24, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e28, 0xffffffff, 0x28303232, }, ++ { 1, 1, 0, 0x00000e2c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e30, 0xffffffff, 0x24262830, }, ++ { 1, 1, 1, 0x00000e34, 0xffffffff, 0x32323232, }, ++ { 1, 1, 1, 0x00000e38, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e3c, 0xffffffff, 0x32323232, }, ++ { 1, 1, 0, 0x00000e40, 0xffffffff, 0x24262830, }, ++ { 1, 1, 0, 0x00000e44, 0xffffffff, 0x32322222, }, ++ { 1, 1, 1, 0x00000e48, 0xffffffff, 0x28303232, }, ++ { 1, 1, 1, 0x00000e4c, 0xffffffff, 0x22222426, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8812a_bb_pg_rfe3); ++ ++static const u32 rtw8812a_rf_a[] = { ++ 0x000, 0x00010000, ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x01E, 0x00080000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x0B1, 0x0001FC1A, ++ 0x0B3, 0x000F0810, ++ 0x0B4, 0x0001A78D, ++ 0x0BA, 0x00086180, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000192, ++ 0x035, 0x00008192, ++ 0x035, 0x00010192, ++ 0x036, 0x00000024, ++ 0x036, 0x00008024, ++ 0x036, 0x00010024, ++ 0x036, 0x00018024, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C21, ++ 0x052, 0x000006D9, ++ 0x053, 0x000FC649, ++ 0x054, 0x0000017E, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x0004604D, ++ 0x034, 0x0004504A, ++ 0x034, 0x00044047, ++ 0x034, 0x00043044, ++ 0x034, 0x00042007, ++ 0x034, 0x00041004, ++ 0x034, 0x00040001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B4, ++ 0x034, 0x000290B1, ++ 0x034, 0x00028072, ++ 0x034, 0x0002706F, ++ 0x034, 0x0002604F, ++ 0x034, 0x0002504C, ++ 0x034, 0x00024049, ++ 0x034, 0x00023046, ++ 0x034, 0x00022009, ++ 0x034, 0x00021006, ++ 0x034, 0x00020003, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001D4, ++ 0x035, 0x000081D4, ++ 0x035, 0x000101D4, ++ 0x035, 0x000201B4, ++ 0x035, 0x000281B4, ++ 0x035, 0x000301B4, ++ 0x035, 0x000401B4, ++ 0x035, 0x000481B4, ++ 0x035, 0x000501B4, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00004BFB, ++ 0x036, 0x0000CBFB, ++ 0x036, 0x00014BFB, ++ 0x036, 0x0001CBFB, ++ 0x036, 0x00024F4B, ++ 0x036, 0x0002CF4B, ++ 0x036, 0x00034F4B, ++ 0x036, 0x0003CF4B, ++ 0x036, 0x00044F4B, ++ 0x036, 0x0004CF4B, ++ 0x036, 0x00054F4B, ++ 0x036, 0x0005CF4B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002CC, ++ 0x03C, 0x00000522, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x01F, 0x00000064, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000FDD43, ++ 0x062, 0x00038F4B, ++ 0x063, 0x00032117, ++ 0x064, 0x000194AC, ++ 0x065, 0x000931D2, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++ 0x01C, 0x000739D2, ++ 0x0B4, 0x0001E78D, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x0B4, 0x0001A78D, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_a, A); ++ ++static const u32 rtw8812a_rf_b[] = { ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x089, 0x00000080, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x086, 0x00014B3A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00014B38, ++ 0xB0000000, 0x00000000, ++ 0x80000004, 0x00000000, 0x40000000, 0x00000000, ++ 0x08B, 0x00080180, ++ 0xA0000000, 0x00000000, ++ 0x08B, 0x00087180, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x80000001, 0x00000000, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0x90000001, 0x00000005, 0x40000000, 0x00000000, ++ 0x03B, 0x0003F218, ++ 0x03B, 0x00030A58, ++ 0x03B, 0x0002FA58, ++ 0x03B, 0x00022590, ++ 0x03B, 0x0001FA50, ++ 0x03B, 0x00010248, ++ 0x03B, 0x00008240, ++ 0xA0000000, 0x00000000, ++ 0x03B, 0x00038A58, ++ 0x03B, 0x00037A58, ++ 0x03B, 0x0002A590, ++ 0x03B, 0x00027A50, ++ 0x03B, 0x00018248, ++ 0x03B, 0x00010240, ++ 0x03B, 0x00008240, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x80000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A4EE, ++ 0x034, 0x00009076, ++ 0x034, 0x00008073, ++ 0x034, 0x00007070, ++ 0x034, 0x0000606D, ++ 0x034, 0x0000506A, ++ 0x034, 0x00004049, ++ 0x034, 0x00003046, ++ 0x034, 0x00002028, ++ 0x034, 0x00001025, ++ 0x034, 0x00000022, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF4, ++ 0x034, 0x00009DF1, ++ 0x034, 0x00008DEE, ++ 0x034, 0x00007DEB, ++ 0x034, 0x00006DE8, ++ 0x034, 0x00005DE5, ++ 0x034, 0x00004DE2, ++ 0x034, 0x00003CE6, ++ 0x034, 0x000024E7, ++ 0x034, 0x000014E4, ++ 0x034, 0x000004E1, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000192, ++ 0x035, 0x00008192, ++ 0x035, 0x00010192, ++ 0x036, 0x00000024, ++ 0x036, 0x00008024, ++ 0x036, 0x00010024, ++ 0x036, 0x00018024, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C21, ++ 0x052, 0x000006D9, ++ 0x053, 0x000FC649, ++ 0x054, 0x0000017E, ++ 0x0EF, 0x00000002, ++ 0x008, 0x00008400, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0003A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0003202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0002B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00023070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0001B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00012085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0000A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00002080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x0007A02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x0007202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x0006B064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x00063070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0005B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00052085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0004A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00042080, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000080, ++ 0x03B, 0x000BA02C, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000400, ++ 0x03B, 0x000B202C, ++ 0x03C, 0x00010000, ++ 0x03A, 0x000000A0, ++ 0x03B, 0x000AB064, ++ 0x03C, 0x00004000, ++ 0x03A, 0x000000D8, ++ 0x03B, 0x000A3070, ++ 0x03C, 0x00004000, ++ 0x03A, 0x00000468, ++ 0x03B, 0x0009B870, ++ 0x03C, 0x00010000, ++ 0x03A, 0x00000098, ++ 0x03B, 0x00092085, ++ 0x03C, 0x000E4000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x0008A080, ++ 0x03C, 0x000F0000, ++ 0x03A, 0x00000418, ++ 0x03B, 0x00082080, ++ 0x03C, 0x00010000, ++ 0x0EF, 0x00001100, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B2, ++ 0x034, 0x000490AF, ++ 0x034, 0x00048070, ++ 0x034, 0x0004706D, ++ 0x034, 0x00046050, ++ 0x034, 0x0004504D, ++ 0x034, 0x0004404A, ++ 0x034, 0x00043047, ++ 0x034, 0x0004200A, ++ 0x034, 0x00041007, ++ 0x034, 0x00040004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0B1, ++ 0x034, 0x000490AE, ++ 0x034, 0x0004806F, ++ 0x034, 0x0004706C, ++ 0x034, 0x0004604C, ++ 0x034, 0x00045049, ++ 0x034, 0x00044046, ++ 0x034, 0x00043043, ++ 0x034, 0x00042006, ++ 0x034, 0x00041003, ++ 0x034, 0x00040000, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045DE6, ++ 0x034, 0x00044DE3, ++ 0x034, 0x000438C8, ++ 0x034, 0x000428C5, ++ 0x034, 0x000418C2, ++ 0x034, 0x000408C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B2, ++ 0x034, 0x000290AF, ++ 0x034, 0x00028070, ++ 0x034, 0x0002706D, ++ 0x034, 0x00026050, ++ 0x034, 0x0002504D, ++ 0x034, 0x0002404A, ++ 0x034, 0x00023047, ++ 0x034, 0x0002200A, ++ 0x034, 0x00021007, ++ 0x034, 0x00020004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0B3, ++ 0x034, 0x000290B0, ++ 0x034, 0x00028071, ++ 0x034, 0x0002706E, ++ 0x034, 0x0002604E, ++ 0x034, 0x0002504B, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022008, ++ 0x034, 0x00021005, ++ 0x034, 0x00020002, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF5, ++ 0x034, 0x00029DF2, ++ 0x034, 0x00028DEF, ++ 0x034, 0x00027DEC, ++ 0x034, 0x00026DE9, ++ 0x034, 0x00025DE6, ++ 0x034, 0x00024DE3, ++ 0x034, 0x000238C8, ++ 0x034, 0x000228C5, ++ 0x034, 0x000218C2, ++ 0x034, 0x000208C0, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B2, ++ 0x034, 0x000090AF, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x00006050, ++ 0x034, 0x0000504D, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x0000200A, ++ 0x034, 0x00001007, ++ 0x034, 0x00000004, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0B3, ++ 0x034, 0x000090B0, ++ 0x034, 0x00008070, ++ 0x034, 0x0000706D, ++ 0x034, 0x0000604D, ++ 0x034, 0x0000504A, ++ 0x034, 0x00004047, ++ 0x034, 0x00003044, ++ 0x034, 0x00002007, ++ 0x034, 0x00001004, ++ 0x034, 0x00000001, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000AFF7, ++ 0x034, 0x00009DF7, ++ 0x034, 0x00008DF4, ++ 0x034, 0x00007DF1, ++ 0x034, 0x00006DEE, ++ 0x034, 0x00005DEB, ++ 0x034, 0x00004DE8, ++ 0x034, 0x000038CC, ++ 0x034, 0x000028C9, ++ 0x034, 0x000018C6, ++ 0x034, 0x000008C3, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x000001C5, ++ 0x035, 0x000081C5, ++ 0x035, 0x000101C5, ++ 0x035, 0x00020174, ++ 0x035, 0x00028174, ++ 0x035, 0x00030174, ++ 0x035, 0x00040185, ++ 0x035, 0x00048185, ++ 0x035, 0x00050185, ++ 0x0EF, 0x00000000, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x035, 0x00000188, ++ 0x035, 0x00008147, ++ 0x035, 0x00010147, ++ 0x035, 0x000201D7, ++ 0x035, 0x000281D7, ++ 0x035, 0x000301D7, ++ 0x035, 0x000401D8, ++ 0x035, 0x000481D8, ++ 0x035, 0x000501D8, ++ 0x0EF, 0x00000000, ++ 0xB0000000, 0x00000000, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00005B8B, ++ 0x036, 0x0000DB8B, ++ 0x036, 0x00015B8B, ++ 0x036, 0x0001DB8B, ++ 0x036, 0x000262DB, ++ 0x036, 0x0002E2DB, ++ 0x036, 0x000362DB, ++ 0x036, 0x0003E2DB, ++ 0x036, 0x0004553B, ++ 0x036, 0x0004D53B, ++ 0x036, 0x0005553B, ++ 0x036, 0x0005D53B, ++ 0xA0000000, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x036, 0x00084EB4, ++ 0x036, 0x0008CC35, ++ 0x036, 0x00094C35, ++ 0x036, 0x0009CC35, ++ 0x036, 0x000A4C35, ++ 0x036, 0x000ACC35, ++ 0x036, 0x000B4C35, ++ 0x036, 0x000BCC35, ++ 0x036, 0x000C4C34, ++ 0x036, 0x000CCC35, ++ 0x036, 0x000D4C35, ++ 0x036, 0x000DCC35, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000002DC, ++ 0x03C, 0x00000524, ++ 0x03C, 0x00000902, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x000002A8, ++ 0x03C, 0x000005A2, ++ 0x03C, 0x00000880, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x0DF, 0x00000080, ++ 0x80000008, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0x90000008, 0x05000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D2, ++ 0x90000002, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAC43, ++ 0x062, 0x00038F47, ++ 0x063, 0x00031157, ++ 0x064, 0x0001C4AC, ++ 0x065, 0x000931D1, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000E5D53, ++ 0x062, 0x00038FCD, ++ 0x063, 0x000114EB, ++ 0x064, 0x000196AC, ++ 0x065, 0x000911D7, ++ 0xB0000000, 0x00000000, ++ 0x008, 0x00008400, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8812a_rf_b, B); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8812a_txpwr_lmt[] = { ++ { 0, 0, 0, 0, 1, 36, }, ++ { 2, 0, 0, 0, 1, 32, }, ++ { 1, 0, 0, 0, 1, 32, }, ++ { 0, 0, 0, 0, 2, 36, }, ++ { 2, 0, 0, 0, 2, 32, }, ++ { 1, 0, 0, 0, 2, 32, }, ++ { 0, 0, 0, 0, 3, 36, }, ++ { 2, 0, 0, 0, 3, 32, }, ++ { 1, 0, 0, 0, 3, 32, }, ++ { 0, 0, 0, 0, 4, 36, }, ++ { 2, 0, 0, 0, 4, 32, }, ++ { 1, 0, 0, 0, 4, 32, }, ++ { 0, 0, 0, 0, 5, 36, }, ++ { 2, 0, 0, 0, 5, 32, }, ++ { 1, 0, 0, 0, 5, 32, }, ++ { 0, 0, 0, 0, 6, 36, }, ++ { 2, 0, 0, 0, 6, 32, }, ++ { 1, 0, 0, 0, 6, 32, }, ++ { 0, 0, 0, 0, 7, 36, }, ++ { 2, 0, 0, 0, 7, 32, }, ++ { 1, 0, 0, 0, 7, 32, }, ++ { 0, 0, 0, 0, 8, 36, }, ++ { 2, 0, 0, 0, 8, 32, }, ++ { 1, 0, 0, 0, 8, 32, }, ++ { 0, 0, 0, 0, 9, 36, }, ++ { 2, 0, 0, 0, 9, 32, }, ++ { 1, 0, 0, 0, 9, 32, }, ++ { 0, 0, 0, 0, 10, 36, }, ++ { 2, 0, 0, 0, 10, 32, }, ++ { 1, 0, 0, 0, 10, 32, }, ++ { 0, 0, 0, 0, 11, 36, }, ++ { 2, 0, 0, 0, 11, 32, }, ++ { 1, 0, 0, 0, 11, 32, }, ++ { 0, 0, 0, 0, 12, 63, }, ++ { 2, 0, 0, 0, 12, 32, }, ++ { 1, 0, 0, 0, 12, 32, }, ++ { 0, 0, 0, 0, 13, 63, }, ++ { 2, 0, 0, 0, 13, 32, }, ++ { 1, 0, 0, 0, 13, 32, }, ++ { 0, 0, 0, 0, 14, 63, }, ++ { 2, 0, 0, 0, 14, 63, }, ++ { 1, 0, 0, 0, 14, 32, }, ++ { 0, 0, 0, 1, 1, 34, }, ++ { 2, 0, 0, 1, 1, 32, }, ++ { 1, 0, 0, 1, 1, 32, }, ++ { 0, 0, 0, 1, 2, 36, }, ++ { 2, 0, 0, 1, 2, 32, }, ++ { 1, 0, 0, 1, 2, 32, }, ++ { 0, 0, 0, 1, 3, 36, }, ++ { 2, 0, 0, 1, 3, 32, }, ++ { 1, 0, 0, 1, 3, 32, }, ++ { 0, 0, 0, 1, 4, 36, }, ++ { 2, 0, 0, 1, 4, 32, }, ++ { 1, 0, 0, 1, 4, 32, }, ++ { 0, 0, 0, 1, 5, 36, }, ++ { 2, 0, 0, 1, 5, 32, }, ++ { 1, 0, 0, 1, 5, 32, }, ++ { 0, 0, 0, 1, 6, 36, }, ++ { 2, 0, 0, 1, 6, 32, }, ++ { 1, 0, 0, 1, 6, 32, }, ++ { 0, 0, 0, 1, 7, 36, }, ++ { 2, 0, 0, 1, 7, 32, }, ++ { 1, 0, 0, 1, 7, 32, }, ++ { 0, 0, 0, 1, 8, 36, }, ++ { 2, 0, 0, 1, 8, 32, }, ++ { 1, 0, 0, 1, 8, 32, }, ++ { 0, 0, 0, 1, 9, 36, }, ++ { 2, 0, 0, 1, 9, 32, }, ++ { 1, 0, 0, 1, 9, 32, }, ++ { 0, 0, 0, 1, 10, 36, }, ++ { 2, 0, 0, 1, 10, 32, }, ++ { 1, 0, 0, 1, 10, 32, }, ++ { 0, 0, 0, 1, 11, 32, }, ++ { 2, 0, 0, 1, 11, 32, }, ++ { 1, 0, 0, 1, 11, 32, }, ++ { 0, 0, 0, 1, 12, 63, }, ++ { 2, 0, 0, 1, 12, 32, }, ++ { 1, 0, 0, 1, 12, 32, }, ++ { 0, 0, 0, 1, 13, 63, }, ++ { 2, 0, 0, 1, 13, 32, }, ++ { 1, 0, 0, 1, 13, 32, }, ++ { 0, 0, 0, 1, 14, 63, }, ++ { 2, 0, 0, 1, 14, 63, }, ++ { 1, 0, 0, 1, 14, 63, }, ++ { 0, 0, 0, 2, 1, 34, }, ++ { 2, 0, 0, 2, 1, 32, }, ++ { 1, 0, 0, 2, 1, 32, }, ++ { 0, 0, 0, 2, 2, 36, }, ++ { 2, 0, 0, 2, 2, 32, }, ++ { 1, 0, 0, 2, 2, 32, }, ++ { 0, 0, 0, 2, 3, 36, }, ++ { 2, 0, 0, 2, 3, 32, }, ++ { 1, 0, 0, 2, 3, 32, }, ++ { 0, 0, 0, 2, 4, 36, }, ++ { 2, 0, 0, 2, 4, 32, }, ++ { 1, 0, 0, 2, 4, 32, }, ++ { 0, 0, 0, 2, 5, 36, }, ++ { 2, 0, 0, 2, 5, 32, }, ++ { 1, 0, 0, 2, 5, 32, }, ++ { 0, 0, 0, 2, 6, 36, }, ++ { 2, 0, 0, 2, 6, 32, }, ++ { 1, 0, 0, 2, 6, 32, }, ++ { 0, 0, 0, 2, 7, 36, }, ++ { 2, 0, 0, 2, 7, 32, }, ++ { 1, 0, 0, 2, 7, 32, }, ++ { 0, 0, 0, 2, 8, 36, }, ++ { 2, 0, 0, 2, 8, 32, }, ++ { 1, 0, 0, 2, 8, 32, }, ++ { 0, 0, 0, 2, 9, 36, }, ++ { 2, 0, 0, 2, 9, 32, }, ++ { 1, 0, 0, 2, 9, 32, }, ++ { 0, 0, 0, 2, 10, 36, }, ++ { 2, 0, 0, 2, 10, 32, }, ++ { 1, 0, 0, 2, 10, 32, }, ++ { 0, 0, 0, 2, 11, 32, }, ++ { 2, 0, 0, 2, 11, 32, }, ++ { 1, 0, 0, 2, 11, 32, }, ++ { 0, 0, 0, 2, 12, 63, }, ++ { 2, 0, 0, 2, 12, 32, }, ++ { 1, 0, 0, 2, 12, 32, }, ++ { 0, 0, 0, 2, 13, 63, }, ++ { 2, 0, 0, 2, 13, 32, }, ++ { 1, 0, 0, 2, 13, 32, }, ++ { 0, 0, 0, 2, 14, 63, }, ++ { 2, 0, 0, 2, 14, 63, }, ++ { 1, 0, 0, 2, 14, 63, }, ++ { 0, 0, 0, 3, 1, 32, }, ++ { 2, 0, 0, 3, 1, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 34, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 34, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 34, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 34, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 34, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 34, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 34, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 34, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 34, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 14, 63, }, ++ { 0, 0, 1, 2, 1, 63, }, ++ { 2, 0, 1, 2, 1, 63, }, ++ { 1, 0, 1, 2, 1, 63, }, ++ { 0, 0, 1, 2, 2, 63, }, ++ { 2, 0, 1, 2, 2, 63, }, ++ { 1, 0, 1, 2, 2, 63, }, ++ { 0, 0, 1, 2, 3, 32, }, ++ { 2, 0, 1, 2, 3, 32, }, ++ { 1, 0, 1, 2, 3, 32, }, ++ { 0, 0, 1, 2, 4, 36, }, ++ { 2, 0, 1, 2, 4, 32, }, ++ { 1, 0, 1, 2, 4, 32, }, ++ { 0, 0, 1, 2, 5, 36, }, ++ { 2, 0, 1, 2, 5, 32, }, ++ { 1, 0, 1, 2, 5, 32, }, ++ { 0, 0, 1, 2, 6, 36, }, ++ { 2, 0, 1, 2, 6, 32, }, ++ { 1, 0, 1, 2, 6, 32, }, ++ { 0, 0, 1, 2, 7, 36, }, ++ { 2, 0, 1, 2, 7, 32, }, ++ { 1, 0, 1, 2, 7, 32, }, ++ { 0, 0, 1, 2, 8, 36, }, ++ { 2, 0, 1, 2, 8, 32, }, ++ { 1, 0, 1, 2, 8, 32, }, ++ { 0, 0, 1, 2, 9, 36, }, ++ { 2, 0, 1, 2, 9, 32, }, ++ { 1, 0, 1, 2, 9, 32, }, ++ { 0, 0, 1, 2, 10, 36, }, ++ { 2, 0, 1, 2, 10, 32, }, ++ { 1, 0, 1, 2, 10, 32, }, ++ { 0, 0, 1, 2, 11, 32, }, ++ { 2, 0, 1, 2, 11, 32, }, ++ { 1, 0, 1, 2, 11, 32, }, ++ { 0, 0, 1, 2, 12, 63, }, ++ { 2, 0, 1, 2, 12, 32, }, ++ { 1, 0, 1, 2, 12, 32, }, ++ { 0, 0, 1, 2, 13, 63, }, ++ { 2, 0, 1, 2, 13, 32, }, ++ { 1, 0, 1, 2, 13, 32, }, ++ { 0, 0, 1, 2, 14, 63, }, ++ { 2, 0, 1, 2, 14, 63, }, ++ { 1, 0, 1, 2, 14, 63, }, ++ { 0, 0, 1, 3, 1, 63, }, ++ { 2, 0, 1, 3, 1, 63, }, ++ { 1, 0, 1, 3, 1, 63, }, ++ { 0, 0, 1, 3, 2, 63, }, ++ { 2, 0, 1, 3, 2, 63, }, ++ { 1, 0, 1, 3, 2, 63, }, ++ { 0, 0, 1, 3, 3, 30, }, ++ { 2, 0, 1, 3, 3, 30, }, ++ { 1, 0, 1, 3, 3, 30, }, ++ { 0, 0, 1, 3, 4, 34, }, ++ { 2, 0, 1, 3, 4, 30, }, ++ { 1, 0, 1, 3, 4, 30, }, ++ { 0, 0, 1, 3, 5, 34, }, ++ { 2, 0, 1, 3, 5, 30, }, ++ { 1, 0, 1, 3, 5, 30, }, ++ { 0, 0, 1, 3, 6, 34, }, ++ { 2, 0, 1, 3, 6, 30, }, ++ { 1, 0, 1, 3, 6, 30, }, ++ { 0, 0, 1, 3, 7, 34, }, ++ { 2, 0, 1, 3, 7, 30, }, ++ { 1, 0, 1, 3, 7, 30, }, ++ { 0, 0, 1, 3, 8, 34, }, ++ { 2, 0, 1, 3, 8, 30, }, ++ { 1, 0, 1, 3, 8, 30, }, ++ { 0, 0, 1, 3, 9, 34, }, ++ { 2, 0, 1, 3, 9, 30, }, ++ { 1, 0, 1, 3, 9, 30, }, ++ { 0, 0, 1, 3, 10, 34, }, ++ { 2, 0, 1, 3, 10, 30, }, ++ { 1, 0, 1, 3, 10, 30, }, ++ { 0, 0, 1, 3, 11, 30, }, ++ { 2, 0, 1, 3, 11, 30, }, ++ { 1, 0, 1, 3, 11, 30, }, ++ { 0, 0, 1, 3, 12, 63, }, ++ { 2, 0, 1, 3, 12, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 14, 63, }, ++ { 0, 1, 0, 1, 36, 30, }, ++ { 2, 1, 0, 1, 36, 32, }, ++ { 1, 1, 0, 1, 36, 32, }, ++ { 0, 1, 0, 1, 40, 30, }, ++ { 2, 1, 0, 1, 40, 32, }, ++ { 1, 1, 0, 1, 40, 32, }, ++ { 0, 1, 0, 1, 44, 30, }, ++ { 2, 1, 0, 1, 44, 32, }, ++ { 1, 1, 0, 1, 44, 32, }, ++ { 0, 1, 0, 1, 48, 30, }, ++ { 2, 1, 0, 1, 48, 32, }, ++ { 1, 1, 0, 1, 48, 32, }, ++ { 0, 1, 0, 1, 52, 36, }, ++ { 2, 1, 0, 1, 52, 32, }, ++ { 1, 1, 0, 1, 52, 32, }, ++ { 0, 1, 0, 1, 56, 34, }, ++ { 2, 1, 0, 1, 56, 32, }, ++ { 1, 1, 0, 1, 56, 32, }, ++ { 0, 1, 0, 1, 60, 32, }, ++ { 2, 1, 0, 1, 60, 32, }, ++ { 1, 1, 0, 1, 60, 32, }, ++ { 0, 1, 0, 1, 64, 28, }, ++ { 2, 1, 0, 1, 64, 32, }, ++ { 1, 1, 0, 1, 64, 32, }, ++ { 0, 1, 0, 1, 100, 30, }, ++ { 2, 1, 0, 1, 100, 32, }, ++ { 1, 1, 0, 1, 100, 32, }, ++ { 0, 1, 0, 1, 104, 30, }, ++ { 2, 1, 0, 1, 104, 32, }, ++ { 1, 1, 0, 1, 104, 32, }, ++ { 0, 1, 0, 1, 108, 32, }, ++ { 2, 1, 0, 1, 108, 32, }, ++ { 1, 1, 0, 1, 108, 32, }, ++ { 0, 1, 0, 1, 112, 34, }, ++ { 2, 1, 0, 1, 112, 32, }, ++ { 1, 1, 0, 1, 112, 32, }, ++ { 0, 1, 0, 1, 116, 34, }, ++ { 2, 1, 0, 1, 116, 32, }, ++ { 1, 1, 0, 1, 116, 32, }, ++ { 0, 1, 0, 1, 120, 36, }, ++ { 2, 1, 0, 1, 120, 32, }, ++ { 1, 1, 0, 1, 120, 32, }, ++ { 0, 1, 0, 1, 124, 34, }, ++ { 2, 1, 0, 1, 124, 32, }, ++ { 1, 1, 0, 1, 124, 32, }, ++ { 0, 1, 0, 1, 128, 32, }, ++ { 2, 1, 0, 1, 128, 32, }, ++ { 1, 1, 0, 1, 128, 32, }, ++ { 0, 1, 0, 1, 132, 30, }, ++ { 2, 1, 0, 1, 132, 32, }, ++ { 1, 1, 0, 1, 132, 32, }, ++ { 0, 1, 0, 1, 136, 30, }, ++ { 2, 1, 0, 1, 136, 32, }, ++ { 1, 1, 0, 1, 136, 32, }, ++ { 0, 1, 0, 1, 140, 28, }, ++ { 2, 1, 0, 1, 140, 32, }, ++ { 1, 1, 0, 1, 140, 32, }, ++ { 0, 1, 0, 1, 149, 36, }, ++ { 2, 1, 0, 1, 149, 32, }, ++ { 1, 1, 0, 1, 149, 63, }, ++ { 0, 1, 0, 1, 153, 36, }, ++ { 2, 1, 0, 1, 153, 32, }, ++ { 1, 1, 0, 1, 153, 63, }, ++ { 0, 1, 0, 1, 157, 36, }, ++ { 2, 1, 0, 1, 157, 32, }, ++ { 1, 1, 0, 1, 157, 63, }, ++ { 0, 1, 0, 1, 161, 36, }, ++ { 2, 1, 0, 1, 161, 32, }, ++ { 1, 1, 0, 1, 161, 63, }, ++ { 0, 1, 0, 1, 165, 36, }, ++ { 2, 1, 0, 1, 165, 32, }, ++ { 1, 1, 0, 1, 165, 63, }, ++ { 0, 1, 0, 2, 36, 30, }, ++ { 2, 1, 0, 2, 36, 32, }, ++ { 1, 1, 0, 2, 36, 32, }, ++ { 0, 1, 0, 2, 40, 30, }, ++ { 2, 1, 0, 2, 40, 32, }, ++ { 1, 1, 0, 2, 40, 32, }, ++ { 0, 1, 0, 2, 44, 30, }, ++ { 2, 1, 0, 2, 44, 32, }, ++ { 1, 1, 0, 2, 44, 32, }, ++ { 0, 1, 0, 2, 48, 30, }, ++ { 2, 1, 0, 2, 48, 32, }, ++ { 1, 1, 0, 2, 48, 32, }, ++ { 0, 1, 0, 2, 52, 36, }, ++ { 2, 1, 0, 2, 52, 32, }, ++ { 1, 1, 0, 2, 52, 32, }, ++ { 0, 1, 0, 2, 56, 34, }, ++ { 2, 1, 0, 2, 56, 32, }, ++ { 1, 1, 0, 2, 56, 32, }, ++ { 0, 1, 0, 2, 60, 32, }, ++ { 2, 1, 0, 2, 60, 32, }, ++ { 1, 1, 0, 2, 60, 32, }, ++ { 0, 1, 0, 2, 64, 28, }, ++ { 2, 1, 0, 2, 64, 32, }, ++ { 1, 1, 0, 2, 64, 32, }, ++ { 0, 1, 0, 2, 100, 30, }, ++ { 2, 1, 0, 2, 100, 32, }, ++ { 1, 1, 0, 2, 100, 32, }, ++ { 0, 1, 0, 2, 104, 30, }, ++ { 2, 1, 0, 2, 104, 32, }, ++ { 1, 1, 0, 2, 104, 32, }, ++ { 0, 1, 0, 2, 108, 32, }, ++ { 2, 1, 0, 2, 108, 32, }, ++ { 1, 1, 0, 2, 108, 32, }, ++ { 0, 1, 0, 2, 112, 34, }, ++ { 2, 1, 0, 2, 112, 32, }, ++ { 1, 1, 0, 2, 112, 32, }, ++ { 0, 1, 0, 2, 116, 34, }, ++ { 2, 1, 0, 2, 116, 32, }, ++ { 1, 1, 0, 2, 116, 32, }, ++ { 0, 1, 0, 2, 120, 36, }, ++ { 2, 1, 0, 2, 120, 32, }, ++ { 1, 1, 0, 2, 120, 32, }, ++ { 0, 1, 0, 2, 124, 34, }, ++ { 2, 1, 0, 2, 124, 32, }, ++ { 1, 1, 0, 2, 124, 32, }, ++ { 0, 1, 0, 2, 128, 32, }, ++ { 2, 1, 0, 2, 128, 32, }, ++ { 1, 1, 0, 2, 128, 32, }, ++ { 0, 1, 0, 2, 132, 30, }, ++ { 2, 1, 0, 2, 132, 32, }, ++ { 1, 1, 0, 2, 132, 32, }, ++ { 0, 1, 0, 2, 136, 30, }, ++ { 2, 1, 0, 2, 136, 32, }, ++ { 1, 1, 0, 2, 136, 32, }, ++ { 0, 1, 0, 2, 140, 28, }, ++ { 2, 1, 0, 2, 140, 32, }, ++ { 1, 1, 0, 2, 140, 32, }, ++ { 0, 1, 0, 2, 149, 36, }, ++ { 2, 1, 0, 2, 149, 32, }, ++ { 1, 1, 0, 2, 149, 63, }, ++ { 0, 1, 0, 2, 153, 36, }, ++ { 2, 1, 0, 2, 153, 32, }, ++ { 1, 1, 0, 2, 153, 63, }, ++ { 0, 1, 0, 2, 157, 36, }, ++ { 2, 1, 0, 2, 157, 32, }, ++ { 1, 1, 0, 2, 157, 63, }, ++ { 0, 1, 0, 2, 161, 36, }, ++ { 2, 1, 0, 2, 161, 32, }, ++ { 1, 1, 0, 2, 161, 63, }, ++ { 0, 1, 0, 2, 165, 36, }, ++ { 2, 1, 0, 2, 165, 32, }, ++ { 1, 1, 0, 2, 165, 63, }, ++ { 0, 1, 0, 3, 36, 28, }, ++ { 2, 1, 0, 3, 36, 30, }, ++ { 1, 1, 0, 3, 36, 30, }, ++ { 0, 1, 0, 3, 40, 28, }, ++ { 2, 1, 0, 3, 40, 30, }, ++ { 1, 1, 0, 3, 40, 30, }, ++ { 0, 1, 0, 3, 44, 28, }, ++ { 2, 1, 0, 3, 44, 30, }, ++ { 1, 1, 0, 3, 44, 30, }, ++ { 0, 1, 0, 3, 48, 28, }, ++ { 2, 1, 0, 3, 48, 30, }, ++ { 1, 1, 0, 3, 48, 30, }, ++ { 0, 1, 0, 3, 52, 34, }, ++ { 2, 1, 0, 3, 52, 30, }, ++ { 1, 1, 0, 3, 52, 30, }, ++ { 0, 1, 0, 3, 56, 32, }, ++ { 2, 1, 0, 3, 56, 30, }, ++ { 1, 1, 0, 3, 56, 30, }, ++ { 0, 1, 0, 3, 60, 30, }, ++ { 2, 1, 0, 3, 60, 30, }, ++ { 1, 1, 0, 3, 60, 30, }, ++ { 0, 1, 0, 3, 64, 26, }, ++ { 2, 1, 0, 3, 64, 30, }, ++ { 1, 1, 0, 3, 64, 30, }, ++ { 0, 1, 0, 3, 100, 28, }, ++ { 2, 1, 0, 3, 100, 30, }, ++ { 1, 1, 0, 3, 100, 30, }, ++ { 0, 1, 0, 3, 104, 28, }, ++ { 2, 1, 0, 3, 104, 30, }, ++ { 1, 1, 0, 3, 104, 30, }, ++ { 0, 1, 0, 3, 108, 30, }, ++ { 2, 1, 0, 3, 108, 30, }, ++ { 1, 1, 0, 3, 108, 30, }, ++ { 0, 1, 0, 3, 112, 32, }, ++ { 2, 1, 0, 3, 112, 30, }, ++ { 1, 1, 0, 3, 112, 30, }, ++ { 0, 1, 0, 3, 116, 32, }, ++ { 2, 1, 0, 3, 116, 30, }, ++ { 1, 1, 0, 3, 116, 30, }, ++ { 0, 1, 0, 3, 120, 34, }, ++ { 2, 1, 0, 3, 120, 30, }, ++ { 1, 1, 0, 3, 120, 30, }, ++ { 0, 1, 0, 3, 124, 32, }, ++ { 2, 1, 0, 3, 124, 30, }, ++ { 1, 1, 0, 3, 124, 30, }, ++ { 0, 1, 0, 3, 128, 30, }, ++ { 2, 1, 0, 3, 128, 30, }, ++ { 1, 1, 0, 3, 128, 30, }, ++ { 0, 1, 0, 3, 132, 28, }, ++ { 2, 1, 0, 3, 132, 30, }, ++ { 1, 1, 0, 3, 132, 30, }, ++ { 0, 1, 0, 3, 136, 28, }, ++ { 2, 1, 0, 3, 136, 30, }, ++ { 1, 1, 0, 3, 136, 30, }, ++ { 0, 1, 0, 3, 140, 26, }, ++ { 2, 1, 0, 3, 140, 30, }, ++ { 1, 1, 0, 3, 140, 30, }, ++ { 0, 1, 0, 3, 149, 34, }, ++ { 2, 1, 0, 3, 149, 30, }, ++ { 1, 1, 0, 3, 149, 63, }, ++ { 0, 1, 0, 3, 153, 34, }, ++ { 2, 1, 0, 3, 153, 30, }, ++ { 1, 1, 0, 3, 153, 63, }, ++ { 0, 1, 0, 3, 157, 34, }, ++ { 2, 1, 0, 3, 157, 30, }, ++ { 1, 1, 0, 3, 157, 63, }, ++ { 0, 1, 0, 3, 161, 34, }, ++ { 2, 1, 0, 3, 161, 30, }, ++ { 1, 1, 0, 3, 161, 63, }, ++ { 0, 1, 0, 3, 165, 34, }, ++ { 2, 1, 0, 3, 165, 30, }, ++ { 1, 1, 0, 3, 165, 63, }, ++ { 0, 1, 1, 2, 38, 30, }, ++ { 2, 1, 1, 2, 38, 32, }, ++ { 1, 1, 1, 2, 38, 32, }, ++ { 0, 1, 1, 2, 46, 30, }, ++ { 2, 1, 1, 2, 46, 32, }, ++ { 1, 1, 1, 2, 46, 32, }, ++ { 0, 1, 1, 2, 54, 32, }, ++ { 2, 1, 1, 2, 54, 32, }, ++ { 1, 1, 1, 2, 54, 32, }, ++ { 0, 1, 1, 2, 62, 32, }, ++ { 2, 1, 1, 2, 62, 32, }, ++ { 1, 1, 1, 2, 62, 32, }, ++ { 0, 1, 1, 2, 102, 28, }, ++ { 2, 1, 1, 2, 102, 32, }, ++ { 1, 1, 1, 2, 102, 32, }, ++ { 0, 1, 1, 2, 110, 32, }, ++ { 2, 1, 1, 2, 110, 32, }, ++ { 1, 1, 1, 2, 110, 32, }, ++ { 0, 1, 1, 2, 118, 36, }, ++ { 2, 1, 1, 2, 118, 32, }, ++ { 1, 1, 1, 2, 118, 32, }, ++ { 0, 1, 1, 2, 126, 34, }, ++ { 2, 1, 1, 2, 126, 32, }, ++ { 1, 1, 1, 2, 126, 32, }, ++ { 0, 1, 1, 2, 134, 32, }, ++ { 2, 1, 1, 2, 134, 32, }, ++ { 1, 1, 1, 2, 134, 32, }, ++ { 0, 1, 1, 2, 151, 36, }, ++ { 2, 1, 1, 2, 151, 32, }, ++ { 1, 1, 1, 2, 151, 63, }, ++ { 0, 1, 1, 2, 159, 36, }, ++ { 2, 1, 1, 2, 159, 32, }, ++ { 1, 1, 1, 2, 159, 63, }, ++ { 0, 1, 1, 3, 38, 28, }, ++ { 2, 1, 1, 3, 38, 30, }, ++ { 1, 1, 1, 3, 38, 30, }, ++ { 0, 1, 1, 3, 46, 28, }, ++ { 2, 1, 1, 3, 46, 30, }, ++ { 1, 1, 1, 3, 46, 30, }, ++ { 0, 1, 1, 3, 54, 30, }, ++ { 2, 1, 1, 3, 54, 30, }, ++ { 1, 1, 1, 3, 54, 30, }, ++ { 0, 1, 1, 3, 62, 30, }, ++ { 2, 1, 1, 3, 62, 30, }, ++ { 1, 1, 1, 3, 62, 30, }, ++ { 0, 1, 1, 3, 102, 26, }, ++ { 2, 1, 1, 3, 102, 30, }, ++ { 1, 1, 1, 3, 102, 30, }, ++ { 0, 1, 1, 3, 110, 30, }, ++ { 2, 1, 1, 3, 110, 30, }, ++ { 1, 1, 1, 3, 110, 30, }, ++ { 0, 1, 1, 3, 118, 34, }, ++ { 2, 1, 1, 3, 118, 30, }, ++ { 1, 1, 1, 3, 118, 30, }, ++ { 0, 1, 1, 3, 126, 32, }, ++ { 2, 1, 1, 3, 126, 30, }, ++ { 1, 1, 1, 3, 126, 30, }, ++ { 0, 1, 1, 3, 134, 30, }, ++ { 2, 1, 1, 3, 134, 30, }, ++ { 1, 1, 1, 3, 134, 30, }, ++ { 0, 1, 1, 3, 151, 34, }, ++ { 2, 1, 1, 3, 151, 30, }, ++ { 1, 1, 1, 3, 151, 63, }, ++ { 0, 1, 1, 3, 159, 34, }, ++ { 2, 1, 1, 3, 159, 30, }, ++ { 1, 1, 1, 3, 159, 63, }, ++ { 0, 1, 2, 4, 42, 30, }, ++ { 2, 1, 2, 4, 42, 32, }, ++ { 1, 1, 2, 4, 42, 32, }, ++ { 0, 1, 2, 4, 58, 28, }, ++ { 2, 1, 2, 4, 58, 32, }, ++ { 1, 1, 2, 4, 58, 32, }, ++ { 0, 1, 2, 4, 106, 30, }, ++ { 2, 1, 2, 4, 106, 32, }, ++ { 1, 1, 2, 4, 106, 32, }, ++ { 0, 1, 2, 4, 122, 34, }, ++ { 2, 1, 2, 4, 122, 32, }, ++ { 1, 1, 2, 4, 122, 32, }, ++ { 0, 1, 2, 4, 155, 36, }, ++ { 2, 1, 2, 4, 155, 32, }, ++ { 1, 1, 2, 4, 155, 63, }, ++ { 0, 1, 2, 5, 42, 28, }, ++ { 2, 1, 2, 5, 42, 30, }, ++ { 1, 1, 2, 5, 42, 30, }, ++ { 0, 1, 2, 5, 58, 26, }, ++ { 2, 1, 2, 5, 58, 30, }, ++ { 1, 1, 2, 5, 58, 30, }, ++ { 0, 1, 2, 5, 106, 28, }, ++ { 2, 1, 2, 5, 106, 30, }, ++ { 1, 1, 2, 5, 106, 30, }, ++ { 0, 1, 2, 5, 122, 32, }, ++ { 2, 1, 2, 5, 122, 30, }, ++ { 1, 1, 2, 5, 122, 30, }, ++ { 0, 1, 2, 5, 155, 34, }, ++ { 2, 1, 2, 5, 155, 30, }, ++ { 1, 1, 2, 5, 155, 63, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8812a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8812a[] = { ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, 0}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, 0}, ++ {0x0046, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0043, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0x0003, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8812a[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(0), 0}, ++ {0x0024, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0028, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_lps_8812a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x7F}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x0c00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0e00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8812a[] = { ++ {0x0c00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0e00, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x04}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x2A}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8812a[] = { ++ {0x0003, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), 0}, ++ {0x0080, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x05}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xcc}, ++ {0x0042, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xF0, 0xEC}, ++ {0x0043, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x07}, ++ {0x0045, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0046, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xff}, ++ {0x0047, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x0014, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x80, BIT(7)}, ++ {0x0015, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, BIT(0)}, ++ {0x0012, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x01, 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x10, BIT(4)}, ++ {0x0008, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0x02, 0}, ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x001f, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0076, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3), BIT(3)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[] = { ++ trans_carddis_to_cardemu_8812a, ++ trans_cardemu_to_act_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[] = { ++ trans_act_to_lps_8812a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[] = { ++ trans_act_to_cardemu_8812a, ++ trans_cardemu_to_carddis_8812a, ++ NULL ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 4, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 14, 14, 14, 14}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 10, 11, 11, 12, 12, 13, ++ 13, 14, 14, 15, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 15, 15, 15, 15}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2ga_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, ++ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 10, 10, 10 ++}; ++ ++static const u8 rtw8812a_pwrtrk_2g_cck_a_p[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_2g_cck_a_p, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 12, 14, 13, 13, 14, 14, 14, 15, 15}, ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 14, 15, 15, 16, 16}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 10, 10, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, ++ 13, 14, 15, 16, 16, 17, 17, 18, 18}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, ++ 12, 13, 13, 14, 15, 16, 16, 17, 17}, ++ {0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 13, ++ 13, 14, 14, 15, 15, 16, 17, 18, 18}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++ {0, 1, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 11, 11, 11, 11, ++ 11, 11, 11, 11, 11, 11, 11, 11, 11}, ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2gb_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2ga_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, ++ 7, 7, 8, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_b_p[] = { ++ 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 3, 4, 5, 6, 6, 6, 7, 7, 8, 8, 9, ++ 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 15, 15 ++}; ++ ++static const u8 rtw8812a_pwrtrk_rfe3_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8812a_pwrtrk_rfe3_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8812a_pwrtrk_rfe3_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8812a_pwrtrk_rfe3_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8812a_pwrtrk_rfe3_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8812a_pwrtrk_rfe3_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8812a_pwrtrk_rfe3_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8812a_pwrtrk_rfe3_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8812a_pwrtrk_rfe3_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8812a_pwrtrk_rfe3_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8812a_pwrtrk_rfe3_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8812a_pwrtrk_rfe3_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8812a_pwrtrk_rfe3_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8812a_pwrtrk_rfe3_2gb_n, ++ .pwrtrk_2gb_p = rtw8812a_pwrtrk_rfe3_2gb_p, ++ .pwrtrk_2ga_n = rtw8812a_pwrtrk_rfe3_2ga_n, ++ .pwrtrk_2ga_p = rtw8812a_pwrtrk_rfe3_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8812a_pwrtrk_rfe3_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8812a_pwrtrk_rfe3_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8812a_pwrtrk_rfe3_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8812a_pwrtrk_rfe3_2g_cck_a_p, ++}; +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a_table.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8812A_TABLE_H__ ++#define __RTW8812A_TABLE_H__ ++ ++extern const struct rtw_table rtw8812a_mac_tbl; ++extern const struct rtw_table rtw8812a_agc_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_lb_tbl; ++extern const struct rtw_table rtw8812a_agc_diff_hb_tbl; ++extern const struct rtw_table rtw8812a_bb_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_tbl; ++extern const struct rtw_table rtw8812a_bb_pg_rfe3_tbl; ++extern const struct rtw_table rtw8812a_rf_a_tbl; ++extern const struct rtw_table rtw8812a_rf_b_tbl; ++extern const struct rtw_table rtw8812a_txpwr_lmt_tbl; ++ ++extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8812a[]; ++extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8812a[]; ++extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8812a[]; ++ ++extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_tbl; ++extern const struct rtw_pwr_track_tbl rtw8812a_rtw_pwr_track_rfe3_tbl; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch b/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch new file mode 100644 index 00000000000000..e8ceaba61ea06e --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/040-v6.13-wifi-rtw88-Add-rtw8821a_table.-c-h.patch @@ -0,0 +1,2395 @@ +From 4b81da5cd2b4c7231272216639bacecc818d8b51 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:25:16 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821a_table.{c,h} + +These contain various arrays for initialising RTL8821AU. Also TX power +limits. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/087c7260-fcc3-4e22-886b-ac477cad9198@gmail.com +--- + .../wireless/realtek/rtw88/rtw8821a_table.c | 2350 +++++++++++++++++ + .../wireless/realtek/rtw88/rtw8821a_table.h | 21 + + 2 files changed, 2371 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a_table.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.c +@@ -0,0 +1,2350 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "phy.h" ++#include "rtw8821a_table.h" ++ ++static const u32 rtw8821a_mac[] = { ++ 0x421, 0x0000000F, ++ 0x428, 0x0000000A, ++ 0x429, 0x00000010, ++ 0x430, 0x00000000, ++ 0x431, 0x00000000, ++ 0x432, 0x00000000, ++ 0x433, 0x00000001, ++ 0x434, 0x00000004, ++ 0x435, 0x00000005, ++ 0x436, 0x00000007, ++ 0x437, 0x00000008, ++ 0x43C, 0x00000004, ++ 0x43D, 0x00000005, ++ 0x43E, 0x00000007, ++ 0x43F, 0x00000008, ++ 0x440, 0x0000005D, ++ 0x441, 0x00000001, ++ 0x442, 0x00000000, ++ 0x444, 0x00000010, ++ 0x445, 0x00000000, ++ 0x446, 0x00000000, ++ 0x447, 0x00000000, ++ 0x448, 0x00000000, ++ 0x449, 0x000000F0, ++ 0x44A, 0x0000000F, ++ 0x44B, 0x0000003E, ++ 0x44C, 0x00000010, ++ 0x44D, 0x00000000, ++ 0x44E, 0x00000000, ++ 0x44F, 0x00000000, ++ 0x450, 0x00000000, ++ 0x451, 0x000000F0, ++ 0x452, 0x0000000F, ++ 0x453, 0x00000000, ++ 0x456, 0x0000005E, ++ 0x460, 0x00000066, ++ 0x461, 0x00000066, ++ 0x4C8, 0x0000003F, ++ 0x4C9, 0x000000FF, ++ 0x4CC, 0x000000FF, ++ 0x4CD, 0x000000FF, ++ 0x4CE, 0x00000001, ++ 0x500, 0x00000026, ++ 0x501, 0x000000A2, ++ 0x502, 0x0000002F, ++ 0x503, 0x00000000, ++ 0x504, 0x00000028, ++ 0x505, 0x000000A3, ++ 0x506, 0x0000005E, ++ 0x507, 0x00000000, ++ 0x508, 0x0000002B, ++ 0x509, 0x000000A4, ++ 0x50A, 0x0000005E, ++ 0x50B, 0x00000000, ++ 0x50C, 0x0000004F, ++ 0x50D, 0x000000A4, ++ 0x50E, 0x00000000, ++ 0x50F, 0x00000000, ++ 0x512, 0x0000001C, ++ 0x514, 0x0000000A, ++ 0x516, 0x0000000A, ++ 0x525, 0x0000004F, ++ 0x550, 0x00000010, ++ 0x551, 0x00000010, ++ 0x559, 0x00000002, ++ 0x55C, 0x00000050, ++ 0x55D, 0x000000FF, ++ 0x605, 0x00000030, ++ 0x607, 0x00000007, ++ 0x608, 0x0000000E, ++ 0x609, 0x0000002A, ++ 0x620, 0x000000FF, ++ 0x621, 0x000000FF, ++ 0x622, 0x000000FF, ++ 0x623, 0x000000FF, ++ 0x624, 0x000000FF, ++ 0x625, 0x000000FF, ++ 0x626, 0x000000FF, ++ 0x627, 0x000000FF, ++ 0x638, 0x00000050, ++ 0x63C, 0x0000000A, ++ 0x63D, 0x0000000A, ++ 0x63E, 0x0000000E, ++ 0x63F, 0x0000000E, ++ 0x640, 0x00000040, ++ 0x642, 0x00000040, ++ 0x643, 0x00000000, ++ 0x652, 0x000000C8, ++ 0x66E, 0x00000005, ++ 0x700, 0x00000021, ++ 0x701, 0x00000043, ++ 0x702, 0x00000065, ++ 0x703, 0x00000087, ++ 0x708, 0x00000021, ++ 0x709, 0x00000043, ++ 0x70A, 0x00000065, ++ 0x70B, 0x00000087, ++ 0x718, 0x00000040, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_mac, rtw_phy_cfg_mac); ++ ++static const u32 rtw8821a_agc[] = { ++ 0x81C, 0xBF000001, ++ 0x81C, 0xBF020001, ++ 0x81C, 0xBF040001, ++ 0x81C, 0xBF060001, ++ 0x81C, 0xBE080001, ++ 0x81C, 0xBD0A0001, ++ 0x81C, 0xBC0C0001, ++ 0x81C, 0xBA0E0001, ++ 0x81C, 0xB9100001, ++ 0x81C, 0xB8120001, ++ 0x81C, 0xB7140001, ++ 0x81C, 0xB6160001, ++ 0x81C, 0xB5180001, ++ 0x81C, 0xB41A0001, ++ 0x81C, 0xB31C0001, ++ 0x81C, 0xB21E0001, ++ 0x81C, 0xB1200001, ++ 0x81C, 0xB0220001, ++ 0x81C, 0xAF240001, ++ 0x81C, 0xAE260001, ++ 0x81C, 0xAD280001, ++ 0x81C, 0xAC2A0001, ++ 0x81C, 0xAB2C0001, ++ 0x81C, 0xAA2E0001, ++ 0x81C, 0xA9300001, ++ 0x81C, 0xA8320001, ++ 0x81C, 0xA7340001, ++ 0x81C, 0xA6360001, ++ 0x81C, 0xA5380001, ++ 0x81C, 0xA43A0001, ++ 0x81C, 0x683C0001, ++ 0x81C, 0x673E0001, ++ 0x81C, 0x66400001, ++ 0x81C, 0x65420001, ++ 0x81C, 0x64440001, ++ 0x81C, 0x63460001, ++ 0x81C, 0x62480001, ++ 0x81C, 0x614A0001, ++ 0x81C, 0x474C0001, ++ 0x81C, 0x464E0001, ++ 0x81C, 0x45500001, ++ 0x81C, 0x44520001, ++ 0x81C, 0x43540001, ++ 0x81C, 0x42560001, ++ 0x81C, 0x41580001, ++ 0x81C, 0x285A0001, ++ 0x81C, 0x275C0001, ++ 0x81C, 0x265E0001, ++ 0x81C, 0x25600001, ++ 0x81C, 0x24620001, ++ 0x81C, 0x0A640001, ++ 0x81C, 0x09660001, ++ 0x81C, 0x08680001, ++ 0x81C, 0x076A0001, ++ 0x81C, 0x066C0001, ++ 0x81C, 0x056E0001, ++ 0x81C, 0x04700001, ++ 0x81C, 0x03720001, ++ 0x81C, 0x02740001, ++ 0x81C, 0x01760001, ++ 0x81C, 0x01780001, ++ 0x81C, 0x017A0001, ++ 0x81C, 0x017C0001, ++ 0x81C, 0x017E0001, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x81C, 0xFB000101, ++ 0x81C, 0xFA020101, ++ 0x81C, 0xF9040101, ++ 0x81C, 0xF8060101, ++ 0x81C, 0xF7080101, ++ 0x81C, 0xF60A0101, ++ 0x81C, 0xF50C0101, ++ 0x81C, 0xF40E0101, ++ 0x81C, 0xF3100101, ++ 0x81C, 0xF2120101, ++ 0x81C, 0xF1140101, ++ 0x81C, 0xF0160101, ++ 0x81C, 0xEF180101, ++ 0x81C, 0xEE1A0101, ++ 0x81C, 0xED1C0101, ++ 0x81C, 0xEC1E0101, ++ 0x81C, 0xEB200101, ++ 0x81C, 0xEA220101, ++ 0x81C, 0xE9240101, ++ 0x81C, 0xE8260101, ++ 0x81C, 0xE7280101, ++ 0x81C, 0xE62A0101, ++ 0x81C, 0xE52C0101, ++ 0x81C, 0xE42E0101, ++ 0x81C, 0xE3300101, ++ 0x81C, 0xA5320101, ++ 0x81C, 0xA4340101, ++ 0x81C, 0xA3360101, ++ 0x81C, 0x87380101, ++ 0x81C, 0x863A0101, ++ 0x81C, 0x853C0101, ++ 0x81C, 0x843E0101, ++ 0x81C, 0x69400101, ++ 0x81C, 0x68420101, ++ 0x81C, 0x67440101, ++ 0x81C, 0x66460101, ++ 0x81C, 0x49480101, ++ 0x81C, 0x484A0101, ++ 0x81C, 0x474C0101, ++ 0x81C, 0x2A4E0101, ++ 0x81C, 0x29500101, ++ 0x81C, 0x28520101, ++ 0x81C, 0x27540101, ++ 0x81C, 0x26560101, ++ 0x81C, 0x25580101, ++ 0x81C, 0x245A0101, ++ 0x81C, 0x235C0101, ++ 0x81C, 0x055E0101, ++ 0x81C, 0x04600101, ++ 0x81C, 0x03620101, ++ 0x81C, 0x02640101, ++ 0x81C, 0x01660101, ++ 0x81C, 0x01680101, ++ 0x81C, 0x016A0101, ++ 0x81C, 0x016C0101, ++ 0x81C, 0x016E0101, ++ 0x81C, 0x01700101, ++ 0x81C, 0x01720101, ++ 0xA0000000, 0x00000000, ++ 0x81C, 0xFF000101, ++ 0x81C, 0xFF020101, ++ 0x81C, 0xFE040101, ++ 0x81C, 0xFD060101, ++ 0x81C, 0xFC080101, ++ 0x81C, 0xFD0A0101, ++ 0x81C, 0xFC0C0101, ++ 0x81C, 0xFB0E0101, ++ 0x81C, 0xFA100101, ++ 0x81C, 0xF9120101, ++ 0x81C, 0xF8140101, ++ 0x81C, 0xF7160101, ++ 0x81C, 0xF6180101, ++ 0x81C, 0xF51A0101, ++ 0x81C, 0xF41C0101, ++ 0x81C, 0xF31E0101, ++ 0x81C, 0xF2200101, ++ 0x81C, 0xF1220101, ++ 0x81C, 0xF0240101, ++ 0x81C, 0xEF260101, ++ 0x81C, 0xEE280101, ++ 0x81C, 0xED2A0101, ++ 0x81C, 0xEC2C0101, ++ 0x81C, 0xEB2E0101, ++ 0x81C, 0xEA300101, ++ 0x81C, 0xE9320101, ++ 0x81C, 0xE8340101, ++ 0x81C, 0xE7360101, ++ 0x81C, 0xE6380101, ++ 0x81C, 0xE53A0101, ++ 0x81C, 0xE43C0101, ++ 0x81C, 0xE33E0101, ++ 0x81C, 0xA5400101, ++ 0x81C, 0xA4420101, ++ 0x81C, 0xA3440101, ++ 0x81C, 0x87460101, ++ 0x81C, 0x86480101, ++ 0x81C, 0x854A0101, ++ 0x81C, 0x844C0101, ++ 0x81C, 0x694E0101, ++ 0x81C, 0x68500101, ++ 0x81C, 0x67520101, ++ 0x81C, 0x66540101, ++ 0x81C, 0x49560101, ++ 0x81C, 0x48580101, ++ 0x81C, 0x475A0101, ++ 0x81C, 0x2A5C0101, ++ 0x81C, 0x295E0101, ++ 0x81C, 0x28600101, ++ 0x81C, 0x27620101, ++ 0x81C, 0x26640101, ++ 0x81C, 0x25660101, ++ 0x81C, 0x24680101, ++ 0x81C, 0x236A0101, ++ 0x81C, 0x056C0101, ++ 0x81C, 0x046E0101, ++ 0x81C, 0x03700101, ++ 0x81C, 0x02720101, ++ 0xB0000000, 0x00000000, ++ 0x81C, 0x01740101, ++ 0x81C, 0x01760101, ++ 0x81C, 0x01780101, ++ 0x81C, 0x017A0101, ++ 0x81C, 0x017C0101, ++ 0x81C, 0x017E0101, ++ 0xC50, 0x00000022, ++ 0xC50, 0x00000020, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_agc, rtw_phy_cfg_agc); ++ ++static const u32 rtw8821a_bb[] = { ++ 0x800, 0x0020D090, ++ 0x804, 0x080112E0, ++ 0x808, 0x0E028211, ++ 0x80C, 0x92131111, ++ 0x810, 0x20101261, ++ 0x814, 0x020C3D10, ++ 0x818, 0x03A00385, ++ 0x820, 0x00000000, ++ 0x824, 0x00030FE0, ++ 0x828, 0x00000000, ++ 0x82C, 0x002081DD, ++ 0x830, 0x2AAAEEC8, ++ 0x834, 0x0037A706, ++ 0x838, 0x06489B44, ++ 0x83C, 0x0000095B, ++ 0x840, 0xC0000001, ++ 0x844, 0x40003CDE, ++ 0x848, 0x62103F8B, ++ 0x84C, 0x6CFDFFB8, ++ 0x850, 0x28874706, ++ 0x854, 0x0001520C, ++ 0x858, 0x8060E000, ++ 0x85C, 0x74210168, ++ 0x860, 0x6929C321, ++ 0x864, 0x79727432, ++ 0x868, 0x8CA7A314, ++ 0x86C, 0x888C2878, ++ 0x870, 0x08888888, ++ 0x874, 0x31612C2E, ++ 0x878, 0x00000152, ++ 0x87C, 0x000FD000, ++ 0x8A0, 0x00000013, ++ 0x8A4, 0x7F7F7F7F, ++ 0x8A8, 0xA2000338, ++ 0x8AC, 0x0FF0FA0A, ++ 0x8B4, 0x000FC080, ++ 0x8B8, 0x6C10D7FF, ++ 0x8BC, 0x0CA52090, ++ 0x8C0, 0x1BF00020, ++ 0x8C4, 0x00000000, ++ 0x8C8, 0x00013169, ++ 0x8CC, 0x08248492, ++ 0x8D4, 0x940008A0, ++ 0x8D8, 0x290B5612, ++ 0x8F8, 0x400002C0, ++ 0x8FC, 0x00000000, ++ 0x900, 0x00000700, ++ 0x90C, 0x00000000, ++ 0x910, 0x0000FC00, ++ 0x914, 0x00000404, ++ 0x918, 0x1C1028C0, ++ 0x91C, 0x64B11A1C, ++ 0x920, 0xE0767233, ++ 0x924, 0x055AA500, ++ 0x928, 0x00000004, ++ 0x92C, 0xFFFE0000, ++ 0x930, 0xFFFFFFFE, ++ 0x934, 0x001FFFFF, ++ 0x960, 0x00000000, ++ 0x964, 0x00000000, ++ 0x968, 0x00000000, ++ 0x96C, 0x00000000, ++ 0x970, 0x801FFFFF, ++ 0x974, 0x000003FF, ++ 0x978, 0x00000000, ++ 0x97C, 0x00000000, ++ 0x980, 0x00000000, ++ 0x984, 0x00000000, ++ 0x988, 0x00000000, ++ 0x990, 0x27100000, ++ 0x994, 0xFFFF0100, ++ 0x998, 0xFFFFFF5C, ++ 0x99C, 0xFFFFFFFF, ++ 0x9A0, 0x000000FF, ++ 0x9A4, 0x00480080, ++ 0x9A8, 0x00000000, ++ 0x9AC, 0x00000000, ++ 0x9B0, 0x81081008, ++ 0x9B4, 0x01081008, ++ 0x9B8, 0x01081008, ++ 0x9BC, 0x01081008, ++ 0x9D0, 0x00000000, ++ 0x9D4, 0x00000000, ++ 0x9D8, 0x00000000, ++ 0x9DC, 0x00000000, ++ 0x9E0, 0x00005D00, ++ 0x9E4, 0x00000003, ++ 0x9E8, 0x00000001, ++ 0xA00, 0x00D047C8, ++ 0xA04, 0x01FF800C, ++ 0xA08, 0x8C8A8300, ++ 0xA0C, 0x2E68000F, ++ 0xA10, 0x9500BB78, ++ 0xA14, 0x11144028, ++ 0xA18, 0x00881117, ++ 0xA1C, 0x89140F00, ++ 0xA20, 0x1A1B0000, ++ 0xA24, 0x090E1317, ++ 0xA28, 0x00000204, ++ 0xA2C, 0x00900000, ++ 0xA70, 0x101FFF00, ++ 0xA74, 0x00000008, ++ 0xA78, 0x00000900, ++ 0xA7C, 0x225B0606, ++ 0xA80, 0x21805490, ++ 0xA84, 0x001F0000, ++ 0XB00, 0x03100040, ++ 0XB04, 0x0000B000, ++ 0XB08, 0xAE0201EB, ++ 0XB0C, 0x01003207, ++ 0XB10, 0x00009807, ++ 0XB14, 0x01000000, ++ 0XB18, 0x00000002, ++ 0XB1C, 0x00000002, ++ 0XB20, 0x0000001F, ++ 0XB24, 0x03020100, ++ 0XB28, 0x07060504, ++ 0XB2C, 0x0B0A0908, ++ 0XB30, 0x0F0E0D0C, ++ 0XB34, 0x13121110, ++ 0XB38, 0x17161514, ++ 0XB3C, 0x0000003A, ++ 0XB40, 0x00000000, ++ 0XB44, 0x00000000, ++ 0XB48, 0x13000032, ++ 0XB4C, 0x48080000, ++ 0XB50, 0x00000000, ++ 0XB54, 0x00000000, ++ 0XB58, 0x00000000, ++ 0XB5C, 0x00000000, ++ 0xC00, 0x00000007, ++ 0xC04, 0x00042020, ++ 0xC08, 0x80410231, ++ 0xC0C, 0x00000000, ++ 0xC10, 0x00000100, ++ 0xC14, 0x01000000, ++ 0xC1C, 0x40000003, ++ 0xC20, 0x2C2C2C2C, ++ 0xC24, 0x30303030, ++ 0xC28, 0x30303030, ++ 0xC2C, 0x2C2C2C2C, ++ 0xC30, 0x2C2C2C2C, ++ 0xC34, 0x2C2C2C2C, ++ 0xC38, 0x2C2C2C2C, ++ 0xC3C, 0x2A2A2A2A, ++ 0xC40, 0x2A2A2A2A, ++ 0xC44, 0x2A2A2A2A, ++ 0xC48, 0x2A2A2A2A, ++ 0xC4C, 0x2A2A2A2A, ++ 0xC50, 0x00000020, ++ 0xC54, 0x001C1208, ++ 0xC58, 0x30000C1C, ++ 0xC5C, 0x00000058, ++ 0xC60, 0x34344443, ++ 0xC64, 0x07003333, ++ 0xC68, 0x19791979, ++ 0xC6C, 0x19791979, ++ 0xC70, 0x19791979, ++ 0xC74, 0x19791979, ++ 0xC78, 0x19791979, ++ 0xC7C, 0x19791979, ++ 0xC80, 0x19791979, ++ 0xC84, 0x19791979, ++ 0xC94, 0x0100005C, ++ 0xC98, 0x00000000, ++ 0xC9C, 0x00000000, ++ 0xCA0, 0x00000029, ++ 0xCA4, 0x08040201, ++ 0xCA8, 0x80402010, ++ 0xCB0, 0x77775747, ++ 0xCB4, 0x10000077, ++ 0xCB8, 0x00508240, ++}; ++ ++RTW_DECL_TABLE_PHY_COND(rtw8821a_bb, rtw_phy_cfg_bb); ++ ++static const struct rtw_phy_pg_cfg_pair rtw8821a_bb_pg[] = { ++ { 0, 0, 0, 0x00000c20, 0xffffffff, 0x32343638, }, ++ { 0, 0, 0, 0x00000c24, 0xffffffff, 0x36363838, }, ++ { 0, 0, 0, 0x00000c28, 0xffffffff, 0x28303234, }, ++ { 0, 0, 0, 0x00000c2c, 0xffffffff, 0x34363838, }, ++ { 0, 0, 0, 0x00000c30, 0xffffffff, 0x26283032, }, ++ { 0, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 0, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 0, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++ { 1, 0, 0, 0x00000c24, 0xffffffff, 0x34343636, }, ++ { 1, 0, 0, 0x00000c28, 0xffffffff, 0x26283032, }, ++ { 1, 0, 0, 0x00000c2c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c30, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c3c, 0xffffffff, 0x32343636, }, ++ { 1, 0, 0, 0x00000c40, 0xffffffff, 0x24262830, }, ++ { 1, 0, 0, 0x00000c44, 0x0000ffff, 0x00002022, }, ++}; ++ ++RTW_DECL_TABLE_BB_PG(rtw8821a_bb_pg); ++ ++static const u32 rtw8821a_rf_a[] = { ++ 0x018, 0x0001712A, ++ 0x056, 0x00051CF2, ++ 0x066, 0x00040000, ++ 0x000, 0x00010000, ++ 0x01E, 0x00080000, ++ 0x082, 0x00000830, ++ 0x083, 0x00021800, ++ 0x084, 0x00028000, ++ 0x085, 0x00048000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x086, 0x0009483A, ++ 0xA0000000, 0x00000000, ++ 0x086, 0x00094838, ++ 0xB0000000, 0x00000000, ++ 0x087, 0x00044980, ++ 0x088, 0x00048000, ++ 0x089, 0x0000D480, ++ 0x08A, 0x00042240, ++ 0x08B, 0x000F0380, ++ 0x08C, 0x00090000, ++ 0x08D, 0x00022852, ++ 0x08E, 0x00065540, ++ 0x08F, 0x00088001, ++ 0x0EF, 0x00020000, ++ 0x03E, 0x00000380, ++ 0x03F, 0x00090018, ++ 0x03E, 0x00020380, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00040308, ++ 0x03F, 0x000A0018, ++ 0x03E, 0x00060018, ++ 0x03F, 0x000A0018, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x089, 0x00000080, ++ 0x08B, 0x00080180, ++ 0x0EF, 0x00001000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00038027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00030113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00028027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00027027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0001F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00017F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00008027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00078027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x00070113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x00068027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x00067027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0005F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00057F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00048027, ++ 0x03C, 0x000CA000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x00000244, ++ 0x03B, 0x000B0113, ++ 0x03C, 0x00082000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x000A8027, ++ 0x03C, 0x00082000, ++ 0x03A, 0x000000CC, ++ 0x03B, 0x000A7027, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000014C, ++ 0x03B, 0x0009F913, ++ 0x03C, 0x00042000, ++ 0x03A, 0x0000010C, ++ 0x03B, 0x00097F10, ++ 0x03C, 0x00012000, ++ 0x03A, 0x000000D0, ++ 0x03B, 0x00088027, ++ 0x03C, 0x000CA000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00001100, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004A0F3, ++ 0x034, 0x000490B1, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF5, ++ 0x034, 0x00049DF2, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0004ADF3, ++ 0x034, 0x00049DF0, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0004ADF7, ++ 0x034, 0x00049DF3, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000480AE, ++ 0x034, 0x000470AB, ++ 0x034, 0x0004608B, ++ 0x034, 0x00045069, ++ 0x034, 0x00044048, ++ 0x034, 0x00043045, ++ 0x034, 0x00042026, ++ 0x034, 0x00041023, ++ 0x034, 0x00040002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00048DED, ++ 0x034, 0x00047DEA, ++ 0x034, 0x00046DE7, ++ 0x034, 0x00045CE9, ++ 0x034, 0x00044CE6, ++ 0x034, 0x000438C6, ++ 0x034, 0x00042886, ++ 0x034, 0x00041486, ++ 0x034, 0x00040447, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00048DEF, ++ 0x034, 0x00047DEC, ++ 0x034, 0x00046DE9, ++ 0x034, 0x00045CCB, ++ 0x034, 0x0004488D, ++ 0x034, 0x0004348D, ++ 0x034, 0x0004248A, ++ 0x034, 0x0004108D, ++ 0x034, 0x0004008A, ++ 0xB0000000, 0x00000000, ++ 0x80000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002A0F3, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0002ADF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0002ADF7, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000290F0, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF1, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00029DF4, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00029DF2, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x000280AF, ++ 0x034, 0x000270AC, ++ 0x034, 0x0002608B, ++ 0x034, 0x00025069, ++ 0x034, 0x00024048, ++ 0x034, 0x00023045, ++ 0x034, 0x00022026, ++ 0x034, 0x00021023, ++ 0x034, 0x00020002, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00028DF1, ++ 0x034, 0x00027DEE, ++ 0x034, 0x00026DEB, ++ 0x034, 0x00025CEC, ++ 0x034, 0x00024CE9, ++ 0x034, 0x000238CA, ++ 0x034, 0x00022889, ++ 0x034, 0x00021489, ++ 0x034, 0x0002044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00028DEE, ++ 0x034, 0x00027DEB, ++ 0x034, 0x00026CCD, ++ 0x034, 0x00025CCA, ++ 0x034, 0x0002488C, ++ 0x034, 0x0002384C, ++ 0x034, 0x00022849, ++ 0x034, 0x00021449, ++ 0x034, 0x0002004D, ++ 0xB0000000, 0x00000000, ++ 0x8000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000A0D7, ++ 0x034, 0x000090D3, ++ 0x034, 0x000080B1, ++ 0x034, 0x000070AE, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x0000ADF7, ++ 0x034, 0x00009DF4, ++ 0x034, 0x00008DF1, ++ 0x034, 0x00007DEE, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x0000608D, ++ 0x034, 0x0000506B, ++ 0x034, 0x0000404A, ++ 0x034, 0x00003047, ++ 0x034, 0x00002044, ++ 0x034, 0x00001025, ++ 0x034, 0x00000004, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x034, 0x00006DEB, ++ 0x034, 0x00005CEC, ++ 0x034, 0x00004CE9, ++ 0x034, 0x000038CA, ++ 0x034, 0x00002889, ++ 0x034, 0x00001489, ++ 0x034, 0x0000044A, ++ 0xA0000000, 0x00000000, ++ 0x034, 0x00006DCD, ++ 0x034, 0x00005CCD, ++ 0x034, 0x00004CCA, ++ 0x034, 0x0000388C, ++ 0x034, 0x00002888, ++ 0x034, 0x00001488, ++ 0x034, 0x00000486, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000040, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000128, ++ 0x035, 0x00008128, ++ 0x035, 0x00010128, ++ 0x035, 0x000201C8, ++ 0x035, 0x000281C8, ++ 0x035, 0x000301C8, ++ 0x035, 0x000401C8, ++ 0x035, 0x000481C8, ++ 0x035, 0x000501C8, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x035, 0x00000187, ++ 0x035, 0x00008187, ++ 0x035, 0x00010187, ++ 0x035, 0x00020188, ++ 0x035, 0x00028188, ++ 0x035, 0x00030188, ++ 0x035, 0x00040188, ++ 0x035, 0x00048188, ++ 0x035, 0x00050188, ++ 0xA0000000, 0x00000000, ++ 0x035, 0x00000145, ++ 0x035, 0x00008145, ++ 0x035, 0x00010145, ++ 0x035, 0x00020196, ++ 0x035, 0x00028196, ++ 0x035, 0x00030196, ++ 0x035, 0x000401C7, ++ 0x035, 0x000481C7, ++ 0x035, 0x000501C7, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000010, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x000063B5, ++ 0x036, 0x0000E3B5, ++ 0x036, 0x000163B5, ++ 0x036, 0x0001E3B5, ++ 0x036, 0x000263B5, ++ 0x036, 0x0002E3B5, ++ 0x036, 0x000363B5, ++ 0x036, 0x0003E3B5, ++ 0x036, 0x000463B5, ++ 0x036, 0x0004E3B5, ++ 0x036, 0x000563B5, ++ 0x036, 0x0005E3B5, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x036, 0x00085733, ++ 0x036, 0x0008D733, ++ 0x036, 0x00095733, ++ 0x036, 0x0009D733, ++ 0x036, 0x000A64B4, ++ 0x036, 0x000AE4B4, ++ 0x036, 0x000B64B4, ++ 0x036, 0x000BE4B4, ++ 0x036, 0x000C64B4, ++ 0x036, 0x000CE4B4, ++ 0x036, 0x000D64B4, ++ 0x036, 0x000DE4B4, ++ 0xA0000000, 0x00000000, ++ 0x036, 0x000056B3, ++ 0x036, 0x0000D6B3, ++ 0x036, 0x000156B3, ++ 0x036, 0x0001D6B3, ++ 0x036, 0x00026634, ++ 0x036, 0x0002E634, ++ 0x036, 0x00036634, ++ 0x036, 0x0003E634, ++ 0x036, 0x000467B4, ++ 0x036, 0x0004E7B4, ++ 0x036, 0x000567B4, ++ 0x036, 0x0005E7B4, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000008, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001B6, ++ 0x03C, 0x00000492, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x000001C8, ++ 0x03C, 0x00000492, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x0000022A, ++ 0x03C, 0x00000594, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000820, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x03C, 0x00000800, ++ 0xA0000000, 0x00000000, ++ 0x03C, 0x00000900, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x018, 0x0001712A, ++ 0x0EF, 0x00000002, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x008, 0x0004E400, ++ 0xA0000000, 0x00000000, ++ 0x008, 0x00002000, ++ 0xB0000000, 0x00000000, ++ 0x0EF, 0x00000000, ++ 0x0DF, 0x000000C0, ++ 0x01F, 0x00000064, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x058, 0x000A7284, ++ 0x059, 0x000600EC, ++ 0xA0000000, 0x00000000, ++ 0x058, 0x00081184, ++ 0x059, 0x0006016C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000EFD83, ++ 0x062, 0x00093FCC, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x061, 0x000E8D73, ++ 0x062, 0x00093FC5, ++ 0xA0000000, 0x00000000, ++ 0x061, 0x000EAD53, ++ 0x062, 0x00093BC4, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110EB, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x063, 0x000110E9, ++ 0xA0000000, 0x00000000, ++ 0x063, 0x000714E9, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0x90000410, 0x00000000, 0x40000000, 0x00000000, ++ 0x064, 0x0001C27C, ++ 0xA0000000, 0x00000000, ++ 0x064, 0x0001C67C, ++ 0xB0000000, 0x00000000, ++ 0x80000111, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000110, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0x90000210, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0x9000020c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x9000040c, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093015, ++ 0x90000200, 0x00000000, 0x40000000, 0x00000000, ++ 0x065, 0x00093016, ++ 0xA0000000, 0x00000000, ++ 0x065, 0x00091016, ++ 0xB0000000, 0x00000000, ++ 0x018, 0x00000006, ++ 0x0EF, 0x00002000, ++ 0x03B, 0x0003824B, ++ 0x03B, 0x0003024B, ++ 0x03B, 0x0002844B, ++ 0x03B, 0x00020F4B, ++ 0x03B, 0x00018F4B, ++ 0x03B, 0x000104B2, ++ 0x03B, 0x00008049, ++ 0x03B, 0x00000148, ++ 0x03B, 0x0007824B, ++ 0x03B, 0x0007024B, ++ 0x03B, 0x0006824B, ++ 0x03B, 0x00060F4B, ++ 0x03B, 0x00058F4B, ++ 0x03B, 0x000504B2, ++ 0x03B, 0x00048049, ++ 0x03B, 0x00040148, ++ 0x0EF, 0x00000000, ++ 0x0EF, 0x00000100, ++ 0x034, 0x0000ADF3, ++ 0x034, 0x00009DF0, ++ 0x034, 0x00008D70, ++ 0x034, 0x00007D6D, ++ 0x034, 0x00006CEE, ++ 0x034, 0x00005CCC, ++ 0x034, 0x000044EC, ++ 0x034, 0x000034AC, ++ 0x034, 0x0000246D, ++ 0x034, 0x0000106F, ++ 0x034, 0x0000006C, ++ 0x0EF, 0x00000000, ++ 0x0ED, 0x00000010, ++ 0x044, 0x0000ADF2, ++ 0x044, 0x00009DEF, ++ 0x044, 0x00008DEC, ++ 0x044, 0x00007DE9, ++ 0x044, 0x00006CEC, ++ 0x044, 0x00005CE9, ++ 0x044, 0x000044EC, ++ 0x044, 0x000034E9, ++ 0x044, 0x0000246C, ++ 0x044, 0x00001469, ++ 0x044, 0x0000006C, ++ 0x0ED, 0x00000000, ++ 0x0ED, 0x00000001, ++ 0x040, 0x00038DA7, ++ 0x040, 0x000300C2, ++ 0x040, 0x000288E2, ++ 0x040, 0x000200B8, ++ 0x040, 0x000188A5, ++ 0x040, 0x00010FBC, ++ 0x040, 0x00008F71, ++ 0x040, 0x00000240, ++ 0x0ED, 0x00000000, ++ 0x0EF, 0x000020A2, ++ 0x0DF, 0x00000080, ++ 0x035, 0x00000120, ++ 0x035, 0x00008120, ++ 0x035, 0x00010120, ++ 0x036, 0x00000085, ++ 0x036, 0x00008085, ++ 0x036, 0x00010085, ++ 0x036, 0x00018085, ++ 0x0EF, 0x00000000, ++ 0x051, 0x00000C31, ++ 0x052, 0x00000622, ++ 0x053, 0x000FC70B, ++ 0x054, 0x0000017E, ++ 0x056, 0x00051DF3, ++ 0x051, 0x00000C01, ++ 0x052, 0x000006D6, ++ 0x053, 0x000FC649, ++ 0x070, 0x00049661, ++ 0x071, 0x0007843E, ++ 0x072, 0x00000382, ++ 0x074, 0x00051400, ++ 0x035, 0x00000160, ++ 0x035, 0x00008160, ++ 0x035, 0x00010160, ++ 0x036, 0x00000124, ++ 0x036, 0x00008124, ++ 0x036, 0x00010124, ++ 0x036, 0x00018124, ++ 0x0ED, 0x0000000C, ++ 0x045, 0x00000140, ++ 0x045, 0x00008140, ++ 0x045, 0x00010140, ++ 0x046, 0x00000124, ++ 0x046, 0x00008124, ++ 0x046, 0x00010124, ++ 0x046, 0x00018124, ++ 0x0DF, 0x00000088, ++ 0x0B3, 0x000F0E18, ++ 0x0B4, 0x0001214C, ++ 0x0B7, 0x0003000C, ++ 0x01C, 0x000539D2, ++ 0x0C4, 0x000AFE00, ++ 0x018, 0x0001F12A, ++ 0xFFE, 0x00000000, ++ 0xFFE, 0x00000000, ++ 0x018, 0x0001712A, ++}; ++ ++RTW_DECL_TABLE_RF_RADIO(rtw8821a_rf_a, A); ++ ++static const struct rtw_txpwr_lmt_cfg_pair rtw8821a_txpwr_lmt[] = { ++ { 0, 0, 0, 0, 1, 32, }, ++ { 2, 0, 0, 0, 1, 28, }, ++ { 1, 0, 0, 0, 1, 32, }, ++ { 0, 0, 0, 0, 2, 32, }, ++ { 2, 0, 0, 0, 2, 28, }, ++ { 1, 0, 0, 0, 2, 32, }, ++ { 0, 0, 0, 0, 3, 36, }, ++ { 2, 0, 0, 0, 3, 28, }, ++ { 1, 0, 0, 0, 3, 32, }, ++ { 0, 0, 0, 0, 4, 36, }, ++ { 2, 0, 0, 0, 4, 28, }, ++ { 1, 0, 0, 0, 4, 32, }, ++ { 0, 0, 0, 0, 5, 36, }, ++ { 2, 0, 0, 0, 5, 28, }, ++ { 1, 0, 0, 0, 5, 32, }, ++ { 0, 0, 0, 0, 6, 36, }, ++ { 2, 0, 0, 0, 6, 28, }, ++ { 1, 0, 0, 0, 6, 32, }, ++ { 0, 0, 0, 0, 7, 36, }, ++ { 2, 0, 0, 0, 7, 28, }, ++ { 1, 0, 0, 0, 7, 32, }, ++ { 0, 0, 0, 0, 8, 36, }, ++ { 2, 0, 0, 0, 8, 28, }, ++ { 1, 0, 0, 0, 8, 32, }, ++ { 0, 0, 0, 0, 9, 32, }, ++ { 2, 0, 0, 0, 9, 28, }, ++ { 1, 0, 0, 0, 9, 32, }, ++ { 0, 0, 0, 0, 10, 32, }, ++ { 2, 0, 0, 0, 10, 28, }, ++ { 1, 0, 0, 0, 10, 32, }, ++ { 0, 0, 0, 0, 11, 32, }, ++ { 2, 0, 0, 0, 11, 28, }, ++ { 1, 0, 0, 0, 11, 32, }, ++ { 0, 0, 0, 0, 12, 28, }, ++ { 2, 0, 0, 0, 12, 28, }, ++ { 1, 0, 0, 0, 12, 32, }, ++ { 0, 0, 0, 0, 13, 26, }, ++ { 2, 0, 0, 0, 13, 28, }, ++ { 1, 0, 0, 0, 13, 32, }, ++ { 0, 0, 0, 0, 14, 63, }, ++ { 2, 0, 0, 0, 14, 63, }, ++ { 1, 0, 0, 0, 14, 32, }, ++ { 0, 0, 0, 1, 1, 30, }, ++ { 2, 0, 0, 1, 1, 30, }, ++ { 1, 0, 0, 1, 1, 32, }, ++ { 0, 0, 0, 1, 2, 30, }, ++ { 2, 0, 0, 1, 2, 32, }, ++ { 1, 0, 0, 1, 2, 32, }, ++ { 0, 0, 0, 1, 3, 32, }, ++ { 2, 0, 0, 1, 3, 32, }, ++ { 1, 0, 0, 1, 3, 32, }, ++ { 0, 0, 0, 1, 4, 32, }, ++ { 2, 0, 0, 1, 4, 32, }, ++ { 1, 0, 0, 1, 4, 32, }, ++ { 0, 0, 0, 1, 5, 32, }, ++ { 2, 0, 0, 1, 5, 32, }, ++ { 1, 0, 0, 1, 5, 32, }, ++ { 0, 0, 0, 1, 6, 32, }, ++ { 2, 0, 0, 1, 6, 32, }, ++ { 1, 0, 0, 1, 6, 32, }, ++ { 0, 0, 0, 1, 7, 32, }, ++ { 2, 0, 0, 1, 7, 32, }, ++ { 1, 0, 0, 1, 7, 32, }, ++ { 0, 0, 0, 1, 8, 32, }, ++ { 2, 0, 0, 1, 8, 32, }, ++ { 1, 0, 0, 1, 8, 32, }, ++ { 0, 0, 0, 1, 9, 30, }, ++ { 2, 0, 0, 1, 9, 32, }, ++ { 1, 0, 0, 1, 9, 32, }, ++ { 0, 0, 0, 1, 10, 30, }, ++ { 2, 0, 0, 1, 10, 32, }, ++ { 1, 0, 0, 1, 10, 32, }, ++ { 0, 0, 0, 1, 11, 30, }, ++ { 2, 0, 0, 1, 11, 32, }, ++ { 1, 0, 0, 1, 11, 32, }, ++ { 0, 0, 0, 1, 12, 26, }, ++ { 2, 0, 0, 1, 12, 32, }, ++ { 1, 0, 0, 1, 12, 32, }, ++ { 0, 0, 0, 1, 13, 24, }, ++ { 2, 0, 0, 1, 13, 30, }, ++ { 1, 0, 0, 1, 13, 32, }, ++ { 0, 0, 0, 1, 14, 63, }, ++ { 2, 0, 0, 1, 14, 63, }, ++ { 1, 0, 0, 1, 14, 63, }, ++ { 0, 0, 0, 2, 1, 26, }, ++ { 2, 0, 0, 2, 1, 26, }, ++ { 1, 0, 0, 2, 1, 32, }, ++ { 0, 0, 0, 2, 2, 26, }, ++ { 2, 0, 0, 2, 2, 32, }, ++ { 1, 0, 0, 2, 2, 32, }, ++ { 0, 0, 0, 2, 3, 32, }, ++ { 2, 0, 0, 2, 3, 32, }, ++ { 1, 0, 0, 2, 3, 32, }, ++ { 0, 0, 0, 2, 4, 32, }, ++ { 2, 0, 0, 2, 4, 32, }, ++ { 1, 0, 0, 2, 4, 32, }, ++ { 0, 0, 0, 2, 5, 32, }, ++ { 2, 0, 0, 2, 5, 32, }, ++ { 1, 0, 0, 2, 5, 32, }, ++ { 0, 0, 0, 2, 6, 32, }, ++ { 2, 0, 0, 2, 6, 32, }, ++ { 1, 0, 0, 2, 6, 32, }, ++ { 0, 0, 0, 2, 7, 32, }, ++ { 2, 0, 0, 2, 7, 32, }, ++ { 1, 0, 0, 2, 7, 32, }, ++ { 0, 0, 0, 2, 8, 32, }, ++ { 2, 0, 0, 2, 8, 32, }, ++ { 1, 0, 0, 2, 8, 32, }, ++ { 0, 0, 0, 2, 9, 26, }, ++ { 2, 0, 0, 2, 9, 32, }, ++ { 1, 0, 0, 2, 9, 32, }, ++ { 0, 0, 0, 2, 10, 26, }, ++ { 2, 0, 0, 2, 10, 32, }, ++ { 1, 0, 0, 2, 10, 32, }, ++ { 0, 0, 0, 2, 11, 26, }, ++ { 2, 0, 0, 2, 11, 32, }, ++ { 1, 0, 0, 2, 11, 32, }, ++ { 0, 0, 0, 2, 12, 26, }, ++ { 2, 0, 0, 2, 12, 32, }, ++ { 1, 0, 0, 2, 12, 32, }, ++ { 0, 0, 0, 2, 13, 24, }, ++ { 2, 0, 0, 2, 13, 26, }, ++ { 1, 0, 0, 2, 13, 32, }, ++ { 0, 0, 0, 2, 14, 63, }, ++ { 2, 0, 0, 2, 14, 63, }, ++ { 1, 0, 0, 2, 14, 63, }, ++ { 0, 0, 0, 3, 1, 30, }, ++ { 2, 0, 0, 3, 1, 32, }, ++ { 1, 0, 0, 3, 1, 32, }, ++ { 0, 0, 0, 3, 2, 32, }, ++ { 2, 0, 0, 3, 2, 32, }, ++ { 1, 0, 0, 3, 2, 32, }, ++ { 0, 0, 0, 3, 3, 32, }, ++ { 2, 0, 0, 3, 3, 32, }, ++ { 1, 0, 0, 3, 3, 32, }, ++ { 0, 0, 0, 3, 4, 32, }, ++ { 2, 0, 0, 3, 4, 32, }, ++ { 1, 0, 0, 3, 4, 32, }, ++ { 0, 0, 0, 3, 5, 32, }, ++ { 2, 0, 0, 3, 5, 32, }, ++ { 1, 0, 0, 3, 5, 32, }, ++ { 0, 0, 0, 3, 6, 32, }, ++ { 2, 0, 0, 3, 6, 32, }, ++ { 1, 0, 0, 3, 6, 32, }, ++ { 0, 0, 0, 3, 7, 32, }, ++ { 2, 0, 0, 3, 7, 32, }, ++ { 1, 0, 0, 3, 7, 32, }, ++ { 0, 0, 0, 3, 8, 32, }, ++ { 2, 0, 0, 3, 8, 32, }, ++ { 1, 0, 0, 3, 8, 32, }, ++ { 0, 0, 0, 3, 9, 32, }, ++ { 2, 0, 0, 3, 9, 32, }, ++ { 1, 0, 0, 3, 9, 32, }, ++ { 0, 0, 0, 3, 10, 32, }, ++ { 2, 0, 0, 3, 10, 32, }, ++ { 1, 0, 0, 3, 10, 32, }, ++ { 0, 0, 0, 3, 11, 30, }, ++ { 2, 0, 0, 3, 11, 32, }, ++ { 1, 0, 0, 3, 11, 32, }, ++ { 0, 0, 0, 3, 12, 63, }, ++ { 2, 0, 0, 3, 12, 32, }, ++ { 1, 0, 0, 3, 12, 32, }, ++ { 0, 0, 0, 3, 13, 63, }, ++ { 2, 0, 0, 3, 13, 32, }, ++ { 1, 0, 0, 3, 13, 32, }, ++ { 0, 0, 0, 3, 14, 63, }, ++ { 2, 0, 0, 3, 14, 63, }, ++ { 1, 0, 0, 3, 14, 63, }, ++ { 0, 0, 1, 2, 1, 63, }, ++ { 2, 0, 1, 2, 1, 63, }, ++ { 1, 0, 1, 2, 1, 63, }, ++ { 0, 0, 1, 2, 2, 63, }, ++ { 2, 0, 1, 2, 2, 63, }, ++ { 1, 0, 1, 2, 2, 63, }, ++ { 0, 0, 1, 2, 3, 26, }, ++ { 2, 0, 1, 2, 3, 26, }, ++ { 1, 0, 1, 2, 3, 32, }, ++ { 0, 0, 1, 2, 4, 26, }, ++ { 2, 0, 1, 2, 4, 32, }, ++ { 1, 0, 1, 2, 4, 32, }, ++ { 0, 0, 1, 2, 5, 26, }, ++ { 2, 0, 1, 2, 5, 32, }, ++ { 1, 0, 1, 2, 5, 32, }, ++ { 0, 0, 1, 2, 6, 32, }, ++ { 2, 0, 1, 2, 6, 32, }, ++ { 1, 0, 1, 2, 6, 32, }, ++ { 0, 0, 1, 2, 7, 32, }, ++ { 2, 0, 1, 2, 7, 32, }, ++ { 1, 0, 1, 2, 7, 32, }, ++ { 0, 0, 1, 2, 8, 32, }, ++ { 2, 0, 1, 2, 8, 32, }, ++ { 1, 0, 1, 2, 8, 32, }, ++ { 0, 0, 1, 2, 9, 26, }, ++ { 2, 0, 1, 2, 9, 32, }, ++ { 1, 0, 1, 2, 9, 32, }, ++ { 0, 0, 1, 2, 10, 24, }, ++ { 2, 0, 1, 2, 10, 32, }, ++ { 1, 0, 1, 2, 10, 32, }, ++ { 0, 0, 1, 2, 11, 22, }, ++ { 2, 0, 1, 2, 11, 26, }, ++ { 1, 0, 1, 2, 11, 32, }, ++ { 0, 0, 1, 2, 12, 63, }, ++ { 2, 0, 1, 2, 12, 63, }, ++ { 1, 0, 1, 2, 12, 63, }, ++ { 0, 0, 1, 2, 13, 63, }, ++ { 2, 0, 1, 2, 13, 63, }, ++ { 1, 0, 1, 2, 13, 63, }, ++ { 0, 0, 1, 2, 14, 63, }, ++ { 2, 0, 1, 2, 14, 63, }, ++ { 1, 0, 1, 2, 14, 63, }, ++ { 0, 0, 1, 3, 1, 63, }, ++ { 2, 0, 1, 3, 1, 63, }, ++ { 1, 0, 1, 3, 1, 63, }, ++ { 0, 0, 1, 3, 2, 63, }, ++ { 2, 0, 1, 3, 2, 63, }, ++ { 1, 0, 1, 3, 2, 63, }, ++ { 0, 0, 1, 3, 3, 30, }, ++ { 2, 0, 1, 3, 3, 30, }, ++ { 1, 0, 1, 3, 3, 30, }, ++ { 0, 0, 1, 3, 4, 32, }, ++ { 2, 0, 1, 3, 4, 30, }, ++ { 1, 0, 1, 3, 4, 30, }, ++ { 0, 0, 1, 3, 5, 32, }, ++ { 2, 0, 1, 3, 5, 30, }, ++ { 1, 0, 1, 3, 5, 30, }, ++ { 0, 0, 1, 3, 6, 32, }, ++ { 2, 0, 1, 3, 6, 30, }, ++ { 1, 0, 1, 3, 6, 30, }, ++ { 0, 0, 1, 3, 7, 32, }, ++ { 2, 0, 1, 3, 7, 30, }, ++ { 1, 0, 1, 3, 7, 30, }, ++ { 0, 0, 1, 3, 8, 32, }, ++ { 2, 0, 1, 3, 8, 30, }, ++ { 1, 0, 1, 3, 8, 30, }, ++ { 0, 0, 1, 3, 9, 32, }, ++ { 2, 0, 1, 3, 9, 30, }, ++ { 1, 0, 1, 3, 9, 30, }, ++ { 0, 0, 1, 3, 10, 32, }, ++ { 2, 0, 1, 3, 10, 30, }, ++ { 1, 0, 1, 3, 10, 30, }, ++ { 0, 0, 1, 3, 11, 30, }, ++ { 2, 0, 1, 3, 11, 30, }, ++ { 1, 0, 1, 3, 11, 30, }, ++ { 0, 0, 1, 3, 12, 63, }, ++ { 2, 0, 1, 3, 12, 32, }, ++ { 1, 0, 1, 3, 12, 32, }, ++ { 0, 0, 1, 3, 13, 63, }, ++ { 2, 0, 1, 3, 13, 32, }, ++ { 1, 0, 1, 3, 13, 32, }, ++ { 0, 0, 1, 3, 14, 63, }, ++ { 2, 0, 1, 3, 14, 63, }, ++ { 1, 0, 1, 3, 14, 63, }, ++ { 0, 1, 0, 1, 36, 32, }, ++ { 2, 1, 0, 1, 36, 30, }, ++ { 1, 1, 0, 1, 36, 30, }, ++ { 0, 1, 0, 1, 40, 32, }, ++ { 2, 1, 0, 1, 40, 30, }, ++ { 1, 1, 0, 1, 40, 30, }, ++ { 0, 1, 0, 1, 44, 32, }, ++ { 2, 1, 0, 1, 44, 30, }, ++ { 1, 1, 0, 1, 44, 30, }, ++ { 0, 1, 0, 1, 48, 32, }, ++ { 2, 1, 0, 1, 48, 30, }, ++ { 1, 1, 0, 1, 48, 30, }, ++ { 0, 1, 0, 1, 52, 32, }, ++ { 2, 1, 0, 1, 52, 30, }, ++ { 1, 1, 0, 1, 52, 30, }, ++ { 0, 1, 0, 1, 56, 32, }, ++ { 2, 1, 0, 1, 56, 30, }, ++ { 1, 1, 0, 1, 56, 30, }, ++ { 0, 1, 0, 1, 60, 32, }, ++ { 2, 1, 0, 1, 60, 30, }, ++ { 1, 1, 0, 1, 60, 30, }, ++ { 0, 1, 0, 1, 64, 32, }, ++ { 2, 1, 0, 1, 64, 30, }, ++ { 1, 1, 0, 1, 64, 30, }, ++ { 0, 1, 0, 1, 100, 32, }, ++ { 2, 1, 0, 1, 100, 30, }, ++ { 1, 1, 0, 1, 100, 30, }, ++ { 0, 1, 0, 1, 104, 32, }, ++ { 2, 1, 0, 1, 104, 30, }, ++ { 1, 1, 0, 1, 104, 30, }, ++ { 0, 1, 0, 1, 108, 32, }, ++ { 2, 1, 0, 1, 108, 30, }, ++ { 1, 1, 0, 1, 108, 30, }, ++ { 0, 1, 0, 1, 112, 32, }, ++ { 2, 1, 0, 1, 112, 30, }, ++ { 1, 1, 0, 1, 112, 30, }, ++ { 0, 1, 0, 1, 116, 32, }, ++ { 2, 1, 0, 1, 116, 30, }, ++ { 1, 1, 0, 1, 116, 30, }, ++ { 0, 1, 0, 1, 120, 32, }, ++ { 2, 1, 0, 1, 120, 30, }, ++ { 1, 1, 0, 1, 120, 30, }, ++ { 0, 1, 0, 1, 124, 32, }, ++ { 2, 1, 0, 1, 124, 30, }, ++ { 1, 1, 0, 1, 124, 30, }, ++ { 0, 1, 0, 1, 128, 32, }, ++ { 2, 1, 0, 1, 128, 30, }, ++ { 1, 1, 0, 1, 128, 30, }, ++ { 0, 1, 0, 1, 132, 32, }, ++ { 2, 1, 0, 1, 132, 30, }, ++ { 1, 1, 0, 1, 132, 30, }, ++ { 0, 1, 0, 1, 136, 32, }, ++ { 2, 1, 0, 1, 136, 30, }, ++ { 1, 1, 0, 1, 136, 30, }, ++ { 0, 1, 0, 1, 140, 32, }, ++ { 2, 1, 0, 1, 140, 30, }, ++ { 1, 1, 0, 1, 140, 30, }, ++ { 0, 1, 0, 1, 149, 32, }, ++ { 2, 1, 0, 1, 149, 30, }, ++ { 1, 1, 0, 1, 149, 63, }, ++ { 0, 1, 0, 1, 153, 32, }, ++ { 2, 1, 0, 1, 153, 30, }, ++ { 1, 1, 0, 1, 153, 63, }, ++ { 0, 1, 0, 1, 157, 32, }, ++ { 2, 1, 0, 1, 157, 30, }, ++ { 1, 1, 0, 1, 157, 63, }, ++ { 0, 1, 0, 1, 161, 32, }, ++ { 2, 1, 0, 1, 161, 30, }, ++ { 1, 1, 0, 1, 161, 63, }, ++ { 0, 1, 0, 1, 165, 32, }, ++ { 2, 1, 0, 1, 165, 30, }, ++ { 1, 1, 0, 1, 165, 63, }, ++ { 0, 1, 0, 2, 36, 32, }, ++ { 2, 1, 0, 2, 36, 30, }, ++ { 1, 1, 0, 2, 36, 30, }, ++ { 0, 1, 0, 2, 40, 32, }, ++ { 2, 1, 0, 2, 40, 30, }, ++ { 1, 1, 0, 2, 40, 30, }, ++ { 0, 1, 0, 2, 44, 32, }, ++ { 2, 1, 0, 2, 44, 30, }, ++ { 1, 1, 0, 2, 44, 30, }, ++ { 0, 1, 0, 2, 48, 32, }, ++ { 2, 1, 0, 2, 48, 30, }, ++ { 1, 1, 0, 2, 48, 30, }, ++ { 0, 1, 0, 2, 52, 32, }, ++ { 2, 1, 0, 2, 52, 30, }, ++ { 1, 1, 0, 2, 52, 30, }, ++ { 0, 1, 0, 2, 56, 32, }, ++ { 2, 1, 0, 2, 56, 30, }, ++ { 1, 1, 0, 2, 56, 30, }, ++ { 0, 1, 0, 2, 60, 32, }, ++ { 2, 1, 0, 2, 60, 30, }, ++ { 1, 1, 0, 2, 60, 30, }, ++ { 0, 1, 0, 2, 64, 32, }, ++ { 2, 1, 0, 2, 64, 30, }, ++ { 1, 1, 0, 2, 64, 30, }, ++ { 0, 1, 0, 2, 100, 32, }, ++ { 2, 1, 0, 2, 100, 30, }, ++ { 1, 1, 0, 2, 100, 30, }, ++ { 0, 1, 0, 2, 104, 32, }, ++ { 2, 1, 0, 2, 104, 30, }, ++ { 1, 1, 0, 2, 104, 30, }, ++ { 0, 1, 0, 2, 108, 32, }, ++ { 2, 1, 0, 2, 108, 30, }, ++ { 1, 1, 0, 2, 108, 30, }, ++ { 0, 1, 0, 2, 112, 32, }, ++ { 2, 1, 0, 2, 112, 30, }, ++ { 1, 1, 0, 2, 112, 30, }, ++ { 0, 1, 0, 2, 116, 32, }, ++ { 2, 1, 0, 2, 116, 30, }, ++ { 1, 1, 0, 2, 116, 30, }, ++ { 0, 1, 0, 2, 120, 32, }, ++ { 2, 1, 0, 2, 120, 30, }, ++ { 1, 1, 0, 2, 120, 30, }, ++ { 0, 1, 0, 2, 124, 32, }, ++ { 2, 1, 0, 2, 124, 30, }, ++ { 1, 1, 0, 2, 124, 30, }, ++ { 0, 1, 0, 2, 128, 32, }, ++ { 2, 1, 0, 2, 128, 30, }, ++ { 1, 1, 0, 2, 128, 30, }, ++ { 0, 1, 0, 2, 132, 32, }, ++ { 2, 1, 0, 2, 132, 30, }, ++ { 1, 1, 0, 2, 132, 30, }, ++ { 0, 1, 0, 2, 136, 32, }, ++ { 2, 1, 0, 2, 136, 30, }, ++ { 1, 1, 0, 2, 136, 30, }, ++ { 0, 1, 0, 2, 140, 32, }, ++ { 2, 1, 0, 2, 140, 30, }, ++ { 1, 1, 0, 2, 140, 30, }, ++ { 0, 1, 0, 2, 149, 32, }, ++ { 2, 1, 0, 2, 149, 30, }, ++ { 1, 1, 0, 2, 149, 63, }, ++ { 0, 1, 0, 2, 153, 32, }, ++ { 2, 1, 0, 2, 153, 30, }, ++ { 1, 1, 0, 2, 153, 63, }, ++ { 0, 1, 0, 2, 157, 32, }, ++ { 2, 1, 0, 2, 157, 30, }, ++ { 1, 1, 0, 2, 157, 63, }, ++ { 0, 1, 0, 2, 161, 32, }, ++ { 2, 1, 0, 2, 161, 30, }, ++ { 1, 1, 0, 2, 161, 63, }, ++ { 0, 1, 0, 2, 165, 32, }, ++ { 2, 1, 0, 2, 165, 30, }, ++ { 1, 1, 0, 2, 165, 63, }, ++ { 0, 1, 0, 3, 36, 28, }, ++ { 2, 1, 0, 3, 36, 30, }, ++ { 1, 1, 0, 3, 36, 30, }, ++ { 0, 1, 0, 3, 40, 28, }, ++ { 2, 1, 0, 3, 40, 30, }, ++ { 1, 1, 0, 3, 40, 30, }, ++ { 0, 1, 0, 3, 44, 28, }, ++ { 2, 1, 0, 3, 44, 30, }, ++ { 1, 1, 0, 3, 44, 30, }, ++ { 0, 1, 0, 3, 48, 28, }, ++ { 2, 1, 0, 3, 48, 30, }, ++ { 1, 1, 0, 3, 48, 30, }, ++ { 0, 1, 0, 3, 52, 34, }, ++ { 2, 1, 0, 3, 52, 30, }, ++ { 1, 1, 0, 3, 52, 30, }, ++ { 0, 1, 0, 3, 56, 32, }, ++ { 2, 1, 0, 3, 56, 30, }, ++ { 1, 1, 0, 3, 56, 30, }, ++ { 0, 1, 0, 3, 60, 30, }, ++ { 2, 1, 0, 3, 60, 30, }, ++ { 1, 1, 0, 3, 60, 30, }, ++ { 0, 1, 0, 3, 64, 26, }, ++ { 2, 1, 0, 3, 64, 30, }, ++ { 1, 1, 0, 3, 64, 30, }, ++ { 0, 1, 0, 3, 100, 28, }, ++ { 2, 1, 0, 3, 100, 30, }, ++ { 1, 1, 0, 3, 100, 30, }, ++ { 0, 1, 0, 3, 104, 28, }, ++ { 2, 1, 0, 3, 104, 30, }, ++ { 1, 1, 0, 3, 104, 30, }, ++ { 0, 1, 0, 3, 108, 30, }, ++ { 2, 1, 0, 3, 108, 30, }, ++ { 1, 1, 0, 3, 108, 30, }, ++ { 0, 1, 0, 3, 112, 32, }, ++ { 2, 1, 0, 3, 112, 30, }, ++ { 1, 1, 0, 3, 112, 30, }, ++ { 0, 1, 0, 3, 116, 32, }, ++ { 2, 1, 0, 3, 116, 30, }, ++ { 1, 1, 0, 3, 116, 30, }, ++ { 0, 1, 0, 3, 120, 34, }, ++ { 2, 1, 0, 3, 120, 30, }, ++ { 1, 1, 0, 3, 120, 30, }, ++ { 0, 1, 0, 3, 124, 32, }, ++ { 2, 1, 0, 3, 124, 30, }, ++ { 1, 1, 0, 3, 124, 30, }, ++ { 0, 1, 0, 3, 128, 30, }, ++ { 2, 1, 0, 3, 128, 30, }, ++ { 1, 1, 0, 3, 128, 30, }, ++ { 0, 1, 0, 3, 132, 28, }, ++ { 2, 1, 0, 3, 132, 30, }, ++ { 1, 1, 0, 3, 132, 30, }, ++ { 0, 1, 0, 3, 136, 28, }, ++ { 2, 1, 0, 3, 136, 30, }, ++ { 1, 1, 0, 3, 136, 30, }, ++ { 0, 1, 0, 3, 140, 26, }, ++ { 2, 1, 0, 3, 140, 30, }, ++ { 1, 1, 0, 3, 140, 30, }, ++ { 0, 1, 0, 3, 149, 34, }, ++ { 2, 1, 0, 3, 149, 30, }, ++ { 1, 1, 0, 3, 149, 63, }, ++ { 0, 1, 0, 3, 153, 34, }, ++ { 2, 1, 0, 3, 153, 30, }, ++ { 1, 1, 0, 3, 153, 63, }, ++ { 0, 1, 0, 3, 157, 34, }, ++ { 2, 1, 0, 3, 157, 30, }, ++ { 1, 1, 0, 3, 157, 63, }, ++ { 0, 1, 0, 3, 161, 34, }, ++ { 2, 1, 0, 3, 161, 30, }, ++ { 1, 1, 0, 3, 161, 63, }, ++ { 0, 1, 0, 3, 165, 34, }, ++ { 2, 1, 0, 3, 165, 30, }, ++ { 1, 1, 0, 3, 165, 63, }, ++ { 0, 1, 1, 2, 38, 26, }, ++ { 2, 1, 1, 2, 38, 30, }, ++ { 1, 1, 1, 2, 38, 30, }, ++ { 0, 1, 1, 2, 46, 32, }, ++ { 2, 1, 1, 2, 46, 30, }, ++ { 1, 1, 1, 2, 46, 30, }, ++ { 0, 1, 1, 2, 54, 32, }, ++ { 2, 1, 1, 2, 54, 30, }, ++ { 1, 1, 1, 2, 54, 30, }, ++ { 0, 1, 1, 2, 62, 24, }, ++ { 2, 1, 1, 2, 62, 30, }, ++ { 1, 1, 1, 2, 62, 30, }, ++ { 0, 1, 1, 2, 102, 24, }, ++ { 2, 1, 1, 2, 102, 30, }, ++ { 1, 1, 1, 2, 102, 30, }, ++ { 0, 1, 1, 2, 110, 32, }, ++ { 2, 1, 1, 2, 110, 30, }, ++ { 1, 1, 1, 2, 110, 30, }, ++ { 0, 1, 1, 2, 118, 32, }, ++ { 2, 1, 1, 2, 118, 30, }, ++ { 1, 1, 1, 2, 118, 30, }, ++ { 0, 1, 1, 2, 126, 32, }, ++ { 2, 1, 1, 2, 126, 30, }, ++ { 1, 1, 1, 2, 126, 30, }, ++ { 0, 1, 1, 2, 134, 32, }, ++ { 2, 1, 1, 2, 134, 30, }, ++ { 1, 1, 1, 2, 134, 30, }, ++ { 0, 1, 1, 2, 151, 30, }, ++ { 2, 1, 1, 2, 151, 30, }, ++ { 1, 1, 1, 2, 151, 63, }, ++ { 0, 1, 1, 2, 159, 32, }, ++ { 2, 1, 1, 2, 159, 30, }, ++ { 1, 1, 1, 2, 159, 63, }, ++ { 0, 1, 1, 3, 38, 28, }, ++ { 2, 1, 1, 3, 38, 30, }, ++ { 1, 1, 1, 3, 38, 30, }, ++ { 0, 1, 1, 3, 46, 28, }, ++ { 2, 1, 1, 3, 46, 30, }, ++ { 1, 1, 1, 3, 46, 30, }, ++ { 0, 1, 1, 3, 54, 30, }, ++ { 2, 1, 1, 3, 54, 30, }, ++ { 1, 1, 1, 3, 54, 30, }, ++ { 0, 1, 1, 3, 62, 30, }, ++ { 2, 1, 1, 3, 62, 30, }, ++ { 1, 1, 1, 3, 62, 30, }, ++ { 0, 1, 1, 3, 102, 26, }, ++ { 2, 1, 1, 3, 102, 30, }, ++ { 1, 1, 1, 3, 102, 30, }, ++ { 0, 1, 1, 3, 110, 30, }, ++ { 2, 1, 1, 3, 110, 30, }, ++ { 1, 1, 1, 3, 110, 30, }, ++ { 0, 1, 1, 3, 118, 34, }, ++ { 2, 1, 1, 3, 118, 30, }, ++ { 1, 1, 1, 3, 118, 30, }, ++ { 0, 1, 1, 3, 126, 32, }, ++ { 2, 1, 1, 3, 126, 30, }, ++ { 1, 1, 1, 3, 126, 30, }, ++ { 0, 1, 1, 3, 134, 30, }, ++ { 2, 1, 1, 3, 134, 30, }, ++ { 1, 1, 1, 3, 134, 30, }, ++ { 0, 1, 1, 3, 151, 34, }, ++ { 2, 1, 1, 3, 151, 30, }, ++ { 1, 1, 1, 3, 151, 63, }, ++ { 0, 1, 1, 3, 159, 34, }, ++ { 2, 1, 1, 3, 159, 30, }, ++ { 1, 1, 1, 3, 159, 63, }, ++ { 0, 1, 2, 4, 42, 22, }, ++ { 2, 1, 2, 4, 42, 30, }, ++ { 1, 1, 2, 4, 42, 30, }, ++ { 0, 1, 2, 4, 58, 20, }, ++ { 2, 1, 2, 4, 58, 30, }, ++ { 1, 1, 2, 4, 58, 30, }, ++ { 0, 1, 2, 4, 106, 20, }, ++ { 2, 1, 2, 4, 106, 30, }, ++ { 1, 1, 2, 4, 106, 30, }, ++ { 0, 1, 2, 4, 122, 20, }, ++ { 2, 1, 2, 4, 122, 30, }, ++ { 1, 1, 2, 4, 122, 30, }, ++ { 0, 1, 2, 4, 155, 28, }, ++ { 2, 1, 2, 4, 155, 30, }, ++ { 1, 1, 2, 4, 155, 63, }, ++ { 0, 1, 2, 5, 42, 28, }, ++ { 2, 1, 2, 5, 42, 30, }, ++ { 1, 1, 2, 5, 42, 30, }, ++ { 0, 1, 2, 5, 58, 26, }, ++ { 2, 1, 2, 5, 58, 30, }, ++ { 1, 1, 2, 5, 58, 30, }, ++ { 0, 1, 2, 5, 106, 28, }, ++ { 2, 1, 2, 5, 106, 30, }, ++ { 1, 1, 2, 5, 106, 30, }, ++ { 0, 1, 2, 5, 122, 32, }, ++ { 2, 1, 2, 5, 122, 30, }, ++ { 1, 1, 2, 5, 122, 30, }, ++ { 0, 1, 2, 5, 155, 34, }, ++ { 2, 1, 2, 5, 155, 30, }, ++ { 1, 1, 2, 5, 155, 63, }, ++}; ++ ++RTW_DECL_TABLE_TXPWR_LMT(rtw8821a_txpwr_lmt); ++ ++static const struct rtw_pwr_seq_cmd trans_carddis_to_cardemu_8821a[] = { ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(7), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x004A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), 0}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_act_8821a[] = { ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), 0}, ++ {0x0001, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 1, RTW_PWR_DELAY_MS}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3) | BIT(2), 0}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), BIT(1)}, ++ {0x0075, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(7), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4) | BIT(3), 0}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(0), 0}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0067, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5) | BIT(4), BIT(5) | BIT(4)}, ++ {0x0025, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0063, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0062, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0058, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x005A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x002E, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x82}, ++ {0x0010, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(6), BIT(6)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_lps_8821a[] = { ++ {0x0301, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x0522, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0xFF}, ++ {0x05F8, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05F9, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FA, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x05FB, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, 0xFF, 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_DELAY, 0, RTW_PWR_DELAY_US}, ++ {0x0002, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0100, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x03}, ++ {0x0101, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0093, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x00}, ++ {0x0553, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_act_to_cardemu_8821a[] = { ++ {0x001F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0}, ++ {0x004F, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0x0049, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), 0}, ++ {0x0006, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(1), BIT(1)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0x0000, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(5), BIT(5)}, ++ {0x0020, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++static const struct rtw_pwr_seq_cmd trans_cardemu_to_carddis_8821a[] = { ++ {0x0007, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, 0xFF, 0x20}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK | RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(3) | BIT(4), BIT(3)}, ++ {0x0005, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_PCI_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(2), BIT(2)}, ++ {0x004A, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_USB_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(0), 1}, ++ {0x0023, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_MAC, ++ RTW_PWR_CMD_WRITE, BIT(4), BIT(4)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_WRITE, BIT(0), BIT(0)}, ++ {0x0086, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_SDIO_MSK, ++ RTW_PWR_ADDR_SDIO, ++ RTW_PWR_CMD_POLLING, BIT(1), 0}, ++ {0xFFFF, ++ RTW_PWR_CUT_ALL_MSK, ++ RTW_PWR_INTF_ALL_MSK, ++ 0, ++ RTW_PWR_CMD_END, 0, 0}, ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[] = { ++ trans_carddis_to_cardemu_8821a, ++ trans_cardemu_to_act_8821a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[] = { ++ trans_act_to_lps_8821a, ++ NULL ++}; ++ ++const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[] = { ++ trans_act_to_cardemu_8821a, ++ trans_cardemu_to_carddis_8821a, ++ NULL ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5gb_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_n[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_5ga_p[][RTW_PWR_TRK_TBL_SZ] = { ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++ {0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 12, 12, 13, 14, 15, ++ 15, 16, 16, 16, 16, 16, 16, 16, 16}, ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2gb_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2ga_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_b_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_n[] = { ++ 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, ++ 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10 ++}; ++ ++static const u8 rtw8821a_pwrtrk_2g_cck_a_p[] = { ++ 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, ++ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12 ++}; ++ ++const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl = { ++ .pwrtrk_5gb_n[0] = rtw8821a_pwrtrk_5gb_n[0], ++ .pwrtrk_5gb_n[1] = rtw8821a_pwrtrk_5gb_n[1], ++ .pwrtrk_5gb_n[2] = rtw8821a_pwrtrk_5gb_n[2], ++ .pwrtrk_5gb_p[0] = rtw8821a_pwrtrk_5gb_p[0], ++ .pwrtrk_5gb_p[1] = rtw8821a_pwrtrk_5gb_p[1], ++ .pwrtrk_5gb_p[2] = rtw8821a_pwrtrk_5gb_p[2], ++ .pwrtrk_5ga_n[0] = rtw8821a_pwrtrk_5ga_n[0], ++ .pwrtrk_5ga_n[1] = rtw8821a_pwrtrk_5ga_n[1], ++ .pwrtrk_5ga_n[2] = rtw8821a_pwrtrk_5ga_n[2], ++ .pwrtrk_5ga_p[0] = rtw8821a_pwrtrk_5ga_p[0], ++ .pwrtrk_5ga_p[1] = rtw8821a_pwrtrk_5ga_p[1], ++ .pwrtrk_5ga_p[2] = rtw8821a_pwrtrk_5ga_p[2], ++ .pwrtrk_2gb_n = rtw8821a_pwrtrk_2gb_n, ++ .pwrtrk_2gb_p = rtw8821a_pwrtrk_2gb_p, ++ .pwrtrk_2ga_n = rtw8821a_pwrtrk_2ga_n, ++ .pwrtrk_2ga_p = rtw8821a_pwrtrk_2ga_p, ++ .pwrtrk_2g_cckb_n = rtw8821a_pwrtrk_2g_cck_b_n, ++ .pwrtrk_2g_cckb_p = rtw8821a_pwrtrk_2g_cck_b_p, ++ .pwrtrk_2g_ccka_n = rtw8821a_pwrtrk_2g_cck_a_n, ++ .pwrtrk_2g_ccka_p = rtw8821a_pwrtrk_2g_cck_a_p, ++}; +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a_table.h +@@ -0,0 +1,21 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_TABLE_H__ ++#define __RTW8821A_TABLE_H__ ++ ++extern const struct rtw_table rtw8821a_mac_tbl; ++extern const struct rtw_table rtw8821a_agc_tbl; ++extern const struct rtw_table rtw8821a_bb_tbl; ++extern const struct rtw_table rtw8821a_bb_pg_tbl; ++extern const struct rtw_table rtw8821a_rf_a_tbl; ++extern const struct rtw_table rtw8821a_txpwr_lmt_tbl; ++ ++extern const struct rtw_pwr_seq_cmd * const card_enable_flow_8821a[]; ++extern const struct rtw_pwr_seq_cmd * const enter_lps_flow_8821a[]; ++extern const struct rtw_pwr_seq_cmd * const card_disable_flow_8821a[]; ++ ++extern const struct rtw_pwr_track_tbl rtw8821a_rtw_pwr_track_tbl; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch b/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch new file mode 100644 index 00000000000000..79e1deebf795ac --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/041-v6.13-wifi-rtw88-Add-rtw88xxa.-c-h.patch @@ -0,0 +1,2187 @@ +From b870b9d31c9e4e6b20c410e1e017f8c87d4c2ae0 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:27:39 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw88xxa.{c,h} + +These contain code shared by both RTL8821AU and RTL8812AU chips. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/b8590382-a954-412d-a96b-63e360b97acc@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw88xxa.c | 1989 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw88xxa.h | 175 ++ + 2 files changed, 2164 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw88xxa.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.c +@@ -0,0 +1,1989 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "rtw88xxa.h" ++#include "mac.h" ++#include "reg.h" ++#include "sec.h" ++#include "debug.h" ++#include "bf.h" ++#include "efuse.h" ++#include "usb.h" ++ ++void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on) ++{ ++ if (on) { ++ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); ++ ++ rtw_write16_set(rtwdev, REG_SYS_FUNC_EN, BIT_FEN_ELDR); ++ rtw_write16_set(rtwdev, REG_SYS_CLKR, ++ BIT_LOADER_CLK_EN | BIT_ANA8M); ++ } else { ++ rtw_write8(rtwdev, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_efuse_grant); ++ ++static void rtw8812a_read_amplifier_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ efuse->ext_pa_2g = (efuse->pa_type_2g & BIT(5)) && ++ (efuse->pa_type_2g & BIT(4)); ++ efuse->ext_lna_2g = (efuse->lna_type_2g & BIT(7)) && ++ (efuse->lna_type_2g & BIT(3)); ++ ++ efuse->ext_pa_5g = (efuse->pa_type_5g & BIT(1)) && ++ (efuse->pa_type_5g & BIT(0)); ++ efuse->ext_lna_5g = (efuse->lna_type_5g & BIT(7)) && ++ (efuse->lna_type_5g & BIT(3)); ++ ++ /* For rtw_phy_cond2: */ ++ if (efuse->ext_pa_2g) { ++ u8 ext_type_pa_2g_a = u8_get_bits(efuse->lna_type_2g, BIT(2)); ++ u8 ext_type_pa_2g_b = u8_get_bits(efuse->lna_type_2g, BIT(6)); ++ ++ efuse->gpa_type = (ext_type_pa_2g_b << 2) | ext_type_pa_2g_a; ++ } ++ ++ if (efuse->ext_pa_5g) { ++ u8 ext_type_pa_5g_a = u8_get_bits(efuse->lna_type_5g, BIT(2)); ++ u8 ext_type_pa_5g_b = u8_get_bits(efuse->lna_type_5g, BIT(6)); ++ ++ efuse->apa_type = (ext_type_pa_5g_b << 2) | ext_type_pa_5g_a; ++ } ++ ++ if (efuse->ext_lna_2g) { ++ u8 ext_type_lna_2g_a = u8_get_bits(efuse->lna_type_2g, ++ BIT(1) | BIT(0)); ++ u8 ext_type_lna_2g_b = u8_get_bits(efuse->lna_type_2g, ++ BIT(5) | BIT(4)); ++ ++ efuse->glna_type = (ext_type_lna_2g_b << 2) | ext_type_lna_2g_a; ++ } ++ ++ if (efuse->ext_lna_5g) { ++ u8 ext_type_lna_5g_a = u8_get_bits(efuse->lna_type_5g, ++ BIT(1) | BIT(0)); ++ u8 ext_type_lna_5g_b = u8_get_bits(efuse->lna_type_5g, ++ BIT(5) | BIT(4)); ++ ++ efuse->alna_type = (ext_type_lna_5g_b << 2) | ext_type_lna_5g_a; ++ } ++} ++ ++static void rtw8812a_read_rfe_type(struct rtw_dev *rtwdev, ++ struct rtw88xxa_efuse *map) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ if (map->rfe_option == 0xff) { ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) ++ efuse->rfe_option = 0; ++ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ efuse->rfe_option = 2; ++ else ++ efuse->rfe_option = 4; ++ } else if (map->rfe_option & BIT(7)) { ++ if (efuse->ext_lna_5g) { ++ if (efuse->ext_pa_5g) { ++ if (efuse->ext_lna_2g && efuse->ext_pa_2g) ++ efuse->rfe_option = 3; ++ else ++ efuse->rfe_option = 0; ++ } else { ++ efuse->rfe_option = 2; ++ } ++ } else { ++ efuse->rfe_option = 4; ++ } ++ } else { ++ efuse->rfe_option = map->rfe_option & 0x3f; ++ ++ /* Due to other customer already use incorrect EFUSE map for ++ * their product. We need to add workaround to prevent to ++ * modify spec and notify all customer to revise the IC 0xca ++ * content. ++ */ ++ if (efuse->rfe_option == 4 && ++ (efuse->ext_pa_5g || efuse->ext_pa_2g || ++ efuse->ext_lna_5g || efuse->ext_lna_2g)) { ++ if (rtwdev->hci.type == RTW_HCI_TYPE_USB) ++ efuse->rfe_option = 0; ++ else if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ efuse->rfe_option = 2; ++ } ++ } ++} ++ ++static void rtw88xxa_read_usb_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw_hal *hal = &rtwdev->hal; ++ u8 antenna = 0; ++ u8 wmode = 0; ++ u8 val8, i; ++ ++ efuse->hw_cap.bw = BIT(RTW_CHANNEL_WIDTH_20) | ++ BIT(RTW_CHANNEL_WIDTH_40) | ++ BIT(RTW_CHANNEL_WIDTH_80); ++ efuse->hw_cap.ptcl = EFUSE_HW_CAP_PTCL_VHT; ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->hw_cap.nss = 1; ++ else ++ efuse->hw_cap.nss = 2; ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ goto print_hw_cap; ++ ++ for (i = 0; i < 2; i++) { ++ rtw_read8_physical_efuse(rtwdev, 1019 - i, &val8); ++ ++ antenna = u8_get_bits(val8, GENMASK(7, 5)); ++ if (antenna) ++ break; ++ antenna = u8_get_bits(val8, GENMASK(3, 1)); ++ if (antenna) ++ break; ++ } ++ ++ for (i = 0; i < 2; i++) { ++ rtw_read8_physical_efuse(rtwdev, 1021 - i, &val8); ++ ++ wmode = u8_get_bits(val8, GENMASK(3, 2)); ++ if (wmode) ++ break; ++ } ++ ++ if (antenna == 1) { ++ rtw_info(rtwdev, "This RTL8812AU says it is 1T1R.\n"); ++ ++ efuse->hw_cap.nss = 1; ++ hal->rf_type = RF_1T1R; ++ hal->rf_path_num = 1; ++ hal->rf_phy_num = 1; ++ hal->antenna_tx = BB_PATH_A; ++ hal->antenna_rx = BB_PATH_A; ++ } else { ++ /* Override rtw_chip_parameter_setup(). It detects 8812au as 1T1R. */ ++ efuse->hw_cap.nss = 2; ++ hal->rf_type = RF_2T2R; ++ hal->rf_path_num = 2; ++ hal->rf_phy_num = 2; ++ hal->antenna_tx = BB_PATH_AB; ++ hal->antenna_rx = BB_PATH_AB; ++ ++ if (antenna == 2 && wmode == 2) { ++ rtw_info(rtwdev, "This RTL8812AU says it can't do VHT.\n"); ++ ++ /* Can't be EFUSE_HW_CAP_IGNORE and can't be ++ * EFUSE_HW_CAP_PTCL_VHT, so make it 1. ++ */ ++ efuse->hw_cap.ptcl = 1; ++ efuse->hw_cap.bw &= ~BIT(RTW_CHANNEL_WIDTH_80); ++ } ++ } ++ ++print_hw_cap: ++ rtw_dbg(rtwdev, RTW_DBG_EFUSE, ++ "hw cap: hci=0x%02x, bw=0x%02x, ptcl=0x%02x, ant_num=%d, nss=%d\n", ++ efuse->hw_cap.hci, efuse->hw_cap.bw, efuse->hw_cap.ptcl, ++ efuse->hw_cap.ant_num, efuse->hw_cap.nss); ++} ++ ++int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw88xxa_efuse *map; ++ int i; ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtwdev->hal.cut_version += 1; ++ ++ if (rtw_dbg_is_enabled(rtwdev, RTW_DBG_EFUSE)) ++ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1, ++ log_map, chip->log_efuse_size, true); ++ ++ map = (struct rtw88xxa_efuse *)log_map; ++ ++ efuse->rf_board_option = map->rf_board_option; ++ efuse->crystal_cap = map->xtal_k; ++ if (efuse->crystal_cap == 0xff) ++ efuse->crystal_cap = 0x20; ++ efuse->pa_type_2g = map->pa_type; ++ efuse->pa_type_5g = map->pa_type; ++ efuse->lna_type_2g = map->lna_type_2g; ++ efuse->lna_type_5g = map->lna_type_5g; ++ if (chip->id == RTW_CHIP_TYPE_8812A) { ++ rtw8812a_read_amplifier_type(rtwdev); ++ rtw8812a_read_rfe_type(rtwdev, map); ++ ++ efuse->usb_mode_switch = u8_get_bits(map->usb_mode, BIT(1)); ++ } ++ efuse->channel_plan = map->channel_plan; ++ efuse->country_code[0] = map->country_code[0]; ++ efuse->country_code[1] = map->country_code[1]; ++ efuse->bt_setting = map->rf_bt_setting; ++ efuse->regd = map->rf_board_option & 0x7; ++ efuse->thermal_meter[0] = map->thermal_meter; ++ efuse->thermal_meter[1] = map->thermal_meter; ++ efuse->thermal_meter_k = map->thermal_meter; ++ efuse->tx_bb_swing_setting_2g = map->tx_bb_swing_setting_2g; ++ efuse->tx_bb_swing_setting_5g = map->tx_bb_swing_setting_5g; ++ ++ rtw88xxa_read_usb_type(rtwdev); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, ++ BIT_BT_FUNC_EN); ++ else ++ efuse->btcoex = (map->rf_board_option & 0xe0) == 0x20; ++ efuse->share_ant = !!(efuse->bt_setting & BIT(0)); ++ ++ /* No antenna diversity because it's disabled in the vendor driver */ ++ efuse->ant_div_cfg = 0; ++ ++ efuse->ant_div_type = map->rf_antenna_option; ++ if (efuse->ant_div_type == 0xff) ++ efuse->ant_div_type = 0x3; ++ ++ for (i = 0; i < 4; i++) ++ efuse->txpwr_idx_table[i] = map->txpwr_idx_table[i]; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_USB: ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ ether_addr_copy(efuse->addr, map->rtw8821au.mac_addr); ++ else ++ ether_addr_copy(efuse->addr, map->rtw8812au.mac_addr); ++ break; ++ case RTW_HCI_TYPE_PCIE: ++ case RTW_HCI_TYPE_SDIO: ++ default: ++ /* unsupported now */ ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL(rtw88xxa_read_efuse); ++ ++static void rtw88xxa_reset_8051(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u8 val8; ++ ++ /* Reset MCU IO Wrapper */ ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(3)); ++ else ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL + 1, BIT(0)); ++ ++ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN + 1); ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 & ~BIT(2)); ++ ++ /* Enable MCU IO Wrapper */ ++ rtw_write8_clr(rtwdev, REG_RSV_CTRL, BIT(1)); ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(3)); ++ else ++ rtw_write8_set(rtwdev, REG_RSV_CTRL + 1, BIT(0)); ++ ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN + 1, val8 | BIT(2)); ++} ++ ++/* A lightweight deinit function */ ++static void rtw88xxau_hw_reset(struct rtw_dev *rtwdev) ++{ ++ u8 val8; ++ ++ if (!(rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL)) ++ return; ++ ++ rtw88xxa_reset_8051(rtwdev); ++ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0x00); ++ ++ /* before BB reset should do clock gated */ ++ rtw_write32_set(rtwdev, REG_FPGA0_XCD_RF_PARA, BIT(6)); ++ ++ /* reset BB */ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1)); ++ ++ /* reset RF */ ++ rtw_write8(rtwdev, REG_RF_CTRL, 0); ++ ++ /* reset TRX path */ ++ rtw_write16(rtwdev, REG_CR, 0); ++ ++ /* reset MAC, reg0x5[1], auto FSM off */ ++ rtw_write8_set(rtwdev, REG_APS_FSMCO + 1, APS_FSMCO_MAC_OFF >> 8); ++ ++ /* check if reg0x5[1] auto cleared */ ++ if (read_poll_timeout_atomic(rtw_read8, val8, ++ !(val8 & (APS_FSMCO_MAC_OFF >> 8)), ++ 1, 5000, false, ++ rtwdev, REG_APS_FSMCO + 1)) ++ rtw_err(rtwdev, "%s: timed out waiting for 0x5[1]\n", __func__); ++ ++ /* reg0x5[0], auto FSM on */ ++ val8 |= APS_FSMCO_MAC_ENABLE >> 8; ++ rtw_write8(rtwdev, REG_APS_FSMCO + 1, val8); ++ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); ++ rtw_write8_set(rtwdev, REG_SYS_FUNC_EN + 1, BIT(4) | BIT(7)); ++} ++ ++static int rtw88xxau_init_power_on(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u16 val16; ++ int ret; ++ ++ ret = rtw_pwr_seq_parser(rtwdev, chip->pwr_on_seq); ++ if (ret) { ++ rtw_err(rtwdev, "power on flow failed\n"); ++ return ret; ++ } ++ ++ rtw_write16(rtwdev, REG_CR, 0); ++ val16 = BIT_HCI_TXDMA_EN | BIT_HCI_RXDMA_EN | BIT_TXDMA_EN | ++ BIT_RXDMA_EN | BIT_PROTOCOL_EN | BIT_SCHEDULE_EN | ++ BIT_MAC_SEC_EN | BIT_32K_CAL_TMR_EN; ++ rtw_write16_set(rtwdev, REG_CR, val16); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ if (rtw_read8(rtwdev, REG_SYS_CFG1 + 3) & BIT(0)) ++ rtw_write8_set(rtwdev, REG_LDO_SWR_CTRL, BIT(6)); ++ } ++ ++ return ret; ++} ++ ++static int rtw88xxa_llt_write(struct rtw_dev *rtwdev, u32 address, u32 data) ++{ ++ u32 value = BIT_LLT_WRITE_ACCESS | (address << 8) | data; ++ int count = 0; ++ ++ rtw_write32(rtwdev, REG_LLT_INIT, value); ++ ++ do { ++ if (!rtw_read32_mask(rtwdev, REG_LLT_INIT, BIT(31) | BIT(30))) ++ break; ++ ++ if (count > 20) { ++ rtw_err(rtwdev, "Failed to poll write LLT done at %d!\n", ++ address); ++ return -EBUSY; ++ } ++ } while (++count); ++ ++ return 0; ++} ++ ++static int rtw88xxa_llt_init(struct rtw_dev *rtwdev, u32 boundary) ++{ ++ u32 last_entry = 255; ++ int status = 0; ++ u32 i; ++ ++ for (i = 0; i < boundary - 1; i++) { ++ status = rtw88xxa_llt_write(rtwdev, i, i + 1); ++ if (status) ++ return status; ++ } ++ ++ status = rtw88xxa_llt_write(rtwdev, boundary - 1, 0xFF); ++ if (status) ++ return status; ++ ++ for (i = boundary; i < last_entry; i++) { ++ status = rtw88xxa_llt_write(rtwdev, i, i + 1); ++ if (status) ++ return status; ++ } ++ ++ status = rtw88xxa_llt_write(rtwdev, last_entry, boundary); ++ ++ return status; ++} ++ ++static void rtw88xxau_init_queue_reserved_page(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_fifo_conf *fifo = &rtwdev->fifo; ++ const struct rtw_page_table *pg_tbl = NULL; ++ u16 pubq_num; ++ u32 val32; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_PCIE: ++ pg_tbl = &chip->page_table[1]; ++ break; ++ case RTW_HCI_TYPE_USB: ++ if (rtwdev->hci.bulkout_num == 2) ++ pg_tbl = &chip->page_table[2]; ++ else if (rtwdev->hci.bulkout_num == 3) ++ pg_tbl = &chip->page_table[3]; ++ else if (rtwdev->hci.bulkout_num == 4) ++ pg_tbl = &chip->page_table[4]; ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ pg_tbl = &chip->page_table[0]; ++ break; ++ default: ++ break; ++ } ++ ++ pubq_num = fifo->acq_pg_num - pg_tbl->hq_num - pg_tbl->lq_num - ++ pg_tbl->nq_num - pg_tbl->exq_num - pg_tbl->gapq_num; ++ ++ val32 = BIT_RQPN_NE(pg_tbl->nq_num, pg_tbl->exq_num); ++ rtw_write32(rtwdev, REG_RQPN_NPQ, val32); ++ ++ val32 = BIT_RQPN_HLP(pg_tbl->hq_num, pg_tbl->lq_num, pubq_num); ++ rtw_write32(rtwdev, REG_RQPN, val32); ++} ++ ++static void rtw88xxau_init_tx_buffer_boundary(struct rtw_dev *rtwdev) ++{ ++ struct rtw_fifo_conf *fifo = &rtwdev->fifo; ++ ++ rtw_write8(rtwdev, REG_BCNQ_BDNY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_MGQ_BDNY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_WMAC_LBK_BF_HD, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_TRXFF_BNDY, fifo->rsvd_boundary); ++ rtw_write8(rtwdev, REG_DWBCN0_CTRL + 1, fifo->rsvd_boundary); ++} ++ ++static int rtw88xxau_init_queue_priority(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u8 bulkout_num = rtwdev->hci.bulkout_num; ++ const struct rtw_rqpn *rqpn = NULL; ++ u16 txdma_pq_map; ++ ++ switch (rtw_hci_type(rtwdev)) { ++ case RTW_HCI_TYPE_PCIE: ++ rqpn = &chip->rqpn_table[1]; ++ break; ++ case RTW_HCI_TYPE_USB: ++ if (bulkout_num == 2) ++ rqpn = &chip->rqpn_table[2]; ++ else if (bulkout_num == 3) ++ rqpn = &chip->rqpn_table[3]; ++ else if (bulkout_num == 4) ++ rqpn = &chip->rqpn_table[4]; ++ else ++ return -EINVAL; ++ break; ++ case RTW_HCI_TYPE_SDIO: ++ rqpn = &chip->rqpn_table[0]; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ rtwdev->fifo.rqpn = rqpn; ++ ++ txdma_pq_map = rtw_read16(rtwdev, REG_TXDMA_PQ_MAP) & 0x7; ++ txdma_pq_map |= BIT_TXDMA_HIQ_MAP(rqpn->dma_map_hi); ++ txdma_pq_map |= BIT_TXDMA_MGQ_MAP(rqpn->dma_map_mg); ++ txdma_pq_map |= BIT_TXDMA_BKQ_MAP(rqpn->dma_map_bk); ++ txdma_pq_map |= BIT_TXDMA_BEQ_MAP(rqpn->dma_map_be); ++ txdma_pq_map |= BIT_TXDMA_VIQ_MAP(rqpn->dma_map_vi); ++ txdma_pq_map |= BIT_TXDMA_VOQ_MAP(rqpn->dma_map_vo); ++ rtw_write16(rtwdev, REG_TXDMA_PQ_MAP, txdma_pq_map); ++ ++ /* Packet in Hi Queue Tx immediately (No constraint for ATIM Period). */ ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_USB && bulkout_num == 4) ++ rtw_write8(rtwdev, REG_HIQ_NO_LMT_EN, 0xff); ++ ++ return 0; ++} ++ ++static void rtw88xxa_init_wmac_setting(struct rtw_dev *rtwdev) ++{ ++ rtw_write16(rtwdev, REG_RXFLTMAP0, 0xffff); ++ rtw_write16(rtwdev, REG_RXFLTMAP1, 0x0400); ++ rtw_write16(rtwdev, REG_RXFLTMAP2, 0xffff); ++ ++ rtw_write32(rtwdev, REG_MAR, 0xffffffff); ++ rtw_write32(rtwdev, REG_MAR + 4, 0xffffffff); ++} ++ ++static void rtw88xxa_init_adaptive_ctrl(struct rtw_dev *rtwdev) ++{ ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, 0xffff1); ++ rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x3030); ++} ++ ++static void rtw88xxa_init_edca(struct rtw_dev *rtwdev) ++{ ++ rtw_write16(rtwdev, REG_SPEC_SIFS, 0x100a); ++ rtw_write16(rtwdev, REG_MAC_SPEC_SIFS, 0x100a); ++ ++ rtw_write16(rtwdev, REG_SIFS, 0x100a); ++ rtw_write16(rtwdev, REG_SIFS + 2, 0x100a); ++ ++ rtw_write32(rtwdev, REG_EDCA_BE_PARAM, 0x005EA42B); ++ rtw_write32(rtwdev, REG_EDCA_BK_PARAM, 0x0000A44F); ++ rtw_write32(rtwdev, REG_EDCA_VI_PARAM, 0x005EA324); ++ rtw_write32(rtwdev, REG_EDCA_VO_PARAM, 0x002FA226); ++ ++ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); ++ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); ++} ++ ++static void rtw88xxau_tx_aggregation(struct rtw_dev *rtwdev) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ ++ rtw_write32_mask(rtwdev, REG_DWBCN0_CTRL, 0xf0, ++ chip->usb_tx_agg_desc_num); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw_write8(rtwdev, REG_DWBCN1_CTRL, ++ chip->usb_tx_agg_desc_num << 1); ++} ++ ++static void rtw88xxa_init_beacon_parameters(struct rtw_dev *rtwdev) ++{ ++ u16 val16; ++ ++ val16 = (BIT_DIS_TSF_UDT << 8) | BIT_DIS_TSF_UDT; ++ if (rtwdev->efuse.btcoex) ++ val16 |= BIT_EN_BCN_FUNCTION; ++ rtw_write16(rtwdev, REG_BCN_CTRL, val16); ++ ++ rtw_write32_mask(rtwdev, REG_TBTT_PROHIBIT, 0xfffff, WLAN_TBTT_TIME); ++ rtw_write8(rtwdev, REG_DRVERLYINT, 0x05); ++ rtw_write8(rtwdev, REG_BCNDMATIM, WLAN_BCN_DMA_TIME); ++ rtw_write16(rtwdev, REG_BCNTCFG, 0x4413); ++} ++ ++static void rtw88xxa_phy_bb_config(struct rtw_dev *rtwdev) ++{ ++ u8 val8, crystal_cap; ++ ++ /* power on BB/RF domain */ ++ val8 = rtw_read8(rtwdev, REG_SYS_FUNC_EN); ++ val8 |= BIT_FEN_USBA; ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); ++ ++ /* toggle BB reset */ ++ val8 |= BIT_FEN_BB_RSTB | BIT_FEN_BB_GLB_RST; ++ rtw_write8(rtwdev, REG_SYS_FUNC_EN, val8); ++ ++ rtw_write8(rtwdev, REG_RF_CTRL, ++ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, ++ BIT_RF_EN | BIT_RF_RSTB | BIT_RF_SDM_RSTB); ++ ++ rtw_load_table(rtwdev, rtwdev->chip->bb_tbl); ++ rtw_load_table(rtwdev, rtwdev->chip->agc_tbl); ++ ++ crystal_cap = rtwdev->efuse.crystal_cap & 0x3F; ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x7FF80000, ++ crystal_cap | (crystal_cap << 6)); ++ else ++ rtw_write32_mask(rtwdev, REG_AFE_CTRL3, 0x00FFF000, ++ crystal_cap | (crystal_cap << 6)); ++} ++ ++static void rtw88xxa_phy_rf_config(struct rtw_dev *rtwdev) ++{ ++ u8 rf_path; ++ ++ for (rf_path = 0; rf_path < rtwdev->hal.rf_path_num; rf_path++) ++ rtw_load_table(rtwdev, rtwdev->chip->rf_tbl[rf_path]); ++} ++ ++static void rtw8812a_config_1t(struct rtw_dev *rtwdev) ++{ ++ /* BB OFDM RX Path_A */ ++ rtw_write32_mask(rtwdev, REG_RXPSEL, 0xff, 0x11); ++ ++ /* BB OFDM TX Path_A */ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, MASKLWORD, 0x1111); ++ ++ /* BB CCK R/Rx Path_A */ ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0c000000, 0x0); ++ ++ /* MCS support */ ++ rtw_write32_mask(rtwdev, REG_RX_MCS_LIMIT, 0xc0000060, 0x4); ++ ++ /* RF Path_B HSSI OFF */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); ++ ++ /* RF Path_B Power Down */ ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, MASKDWORD, 0); ++ ++ /* ADDA Path_B OFF */ ++ rtw_write32_mask(rtwdev, REG_AFE_PWR1_B, MASKDWORD, 0); ++ rtw_write32_mask(rtwdev, REG_AFE_PWR2_B, MASKDWORD, 0); ++} ++ ++static const u32 rtw88xxa_txscale_tbl[] = { ++ 0x081, 0x088, 0x090, 0x099, 0x0a2, 0x0ac, 0x0b6, 0x0c0, 0x0cc, 0x0d8, ++ 0x0e5, 0x0f2, 0x101, 0x110, 0x120, 0x131, 0x143, 0x156, 0x16a, 0x180, ++ 0x197, 0x1af, 0x1c8, 0x1e3, 0x200, 0x21e, 0x23e, 0x261, 0x285, 0x2ab, ++ 0x2d3, 0x2fe, 0x32b, 0x35c, 0x38e, 0x3c4, 0x3fe ++}; ++ ++static u32 rtw88xxa_get_bb_swing(struct rtw_dev *rtwdev, u8 band, u8 path) ++{ ++ static const u32 swing2setting[4] = {0x200, 0x16a, 0x101, 0x0b6}; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ u8 tx_bb_swing; ++ ++ if (band == RTW_BAND_2G) ++ tx_bb_swing = efuse->tx_bb_swing_setting_2g; ++ else ++ tx_bb_swing = efuse->tx_bb_swing_setting_5g; ++ ++ if (path == RF_PATH_B) ++ tx_bb_swing >>= 2; ++ tx_bb_swing &= 0x3; ++ ++ return swing2setting[tx_bb_swing]; ++} ++ ++static u8 rtw88xxa_get_swing_index(struct rtw_dev *rtwdev) ++{ ++ u32 swing, table_value; ++ u8 i; ++ ++ swing = rtw88xxa_get_bb_swing(rtwdev, rtwdev->hal.current_band_type, ++ RF_PATH_A); ++ ++ for (i = 0; i < ARRAY_SIZE(rtw88xxa_txscale_tbl); i++) { ++ table_value = rtw88xxa_txscale_tbl[i]; ++ if (swing == table_value) ++ return i; ++ } ++ ++ return 24; ++} ++ ++static void rtw88xxa_pwrtrack_init(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 path; ++ ++ dm_info->default_ofdm_index = rtw88xxa_get_swing_index(rtwdev); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8821A) ++ dm_info->default_cck_index = 0; ++ else ++ dm_info->default_cck_index = 24; ++ ++ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { ++ ewma_thermal_init(&dm_info->avg_thermal[path]); ++ dm_info->delta_power_index[path] = 0; ++ dm_info->delta_power_index_last[path] = 0; ++ } ++ ++ dm_info->pwr_trk_triggered = false; ++ dm_info->pwr_trk_init_trigger = true; ++ dm_info->thermal_meter_k = rtwdev->efuse.thermal_meter_k; ++} ++ ++void rtw88xxa_power_off(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd *const *enter_lps_flow) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ enum usb_device_speed speed = rtwusb->udev->speed; ++ u16 ori_fsmc0; ++ u8 reg_cr; ++ ++ reg_cr = rtw_read8(rtwdev, REG_CR); ++ ++ /* Already powered off */ ++ if (reg_cr == 0 || reg_cr == 0xEA) ++ return; ++ ++ rtw_hci_stop(rtwdev); ++ ++ if (!rtwdev->efuse.btcoex) ++ rtw_write16_clr(rtwdev, REG_GPIO_MUXCFG, BIT_EN_SIC); ++ ++ /* set Reg 0xf008[3:4] to 2'11 to enable U1/U2 Mode in USB3.0. */ ++ if (speed == USB_SPEED_SUPER) ++ rtw_write8_set(rtwdev, REG_USB_MOD, 0x18); ++ ++ rtw_write32(rtwdev, REG_HISR0, 0xffffffff); ++ rtw_write32(rtwdev, REG_HISR1, 0xffffffff); ++ rtw_write32(rtwdev, REG_HIMR0, 0); ++ rtw_write32(rtwdev, REG_HIMR1, 0); ++ ++ if (rtwdev->efuse.btcoex) ++ rtw_coex_power_off_setting(rtwdev); ++ ++ ori_fsmc0 = rtw_read16(rtwdev, REG_APS_FSMCO); ++ rtw_write16(rtwdev, REG_APS_FSMCO, ori_fsmc0 & ~APS_FSMCO_HW_POWERDOWN); ++ ++ /* Stop Tx Report Timer. */ ++ rtw_write8_clr(rtwdev, REG_TX_RPT_CTRL, BIT(1)); ++ ++ /* Stop Rx */ ++ rtw_write8(rtwdev, REG_CR, 0); ++ ++ rtw_pwr_seq_parser(rtwdev, enter_lps_flow); ++ ++ if (rtw_read8(rtwdev, REG_MCUFW_CTRL) & BIT_RAM_DL_SEL) ++ rtw88xxa_reset_8051(rtwdev); ++ ++ rtw_write8_clr(rtwdev, REG_SYS_FUNC_EN + 1, BIT(2)); ++ rtw_write8(rtwdev, REG_MCUFW_CTRL, 0); ++ ++ rtw_pwr_seq_parser(rtwdev, rtwdev->chip->pwr_off_seq); ++ ++ if (ori_fsmc0 & APS_FSMCO_HW_POWERDOWN) ++ rtw_write16_set(rtwdev, REG_APS_FSMCO, APS_FSMCO_HW_POWERDOWN); ++ ++ clear_bit(RTW_FLAG_POWERON, rtwdev->flags); ++} ++EXPORT_SYMBOL(rtw88xxa_power_off); ++ ++static void rtw88xxa_set_channel_bb_swing(struct rtw_dev *rtwdev, u8 band) ++{ ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, BB_SWING_MASK, ++ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_A)); ++ rtw_write32_mask(rtwdev, REG_TXSCALE_B, BB_SWING_MASK, ++ rtw88xxa_get_bb_swing(rtwdev, band, RF_PATH_B)); ++ rtw88xxa_pwrtrack_init(rtwdev); ++} ++ ++static void rtw8821a_set_ext_band_switch(struct rtw_dev *rtwdev, u8 band) ++{ ++ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN, 0); ++ rtw_write32_mask(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL, 1); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf, 7); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0xf0, 7); ++ ++ if (band == RTW_BAND_2G) ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 1); ++ else ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(29) | BIT(28), 2); ++} ++ ++static void rtw8821a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) ++{ ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ ++ /* Turn off RF PA and LNA */ ++ ++ /* 0xCB0[15:12] = 0x7 (LNA_On)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x7); ++ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x7); ++ ++ if (efuse->ext_lna_2g) { ++ /* Turn on 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 1); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x2); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x2); ++ } else { ++ /* Bypass 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); ++ } ++} ++ ++static void rtw8821a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) ++{ ++ /* Turn ON RF PA and LNA */ ++ ++ /* 0xCB0[15:12] = 0x7 (LNA_On)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF000, 0x5); ++ /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xF0, 0x4); ++ ++ /* Bypass 2.4G External LNA */ ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(20), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, BIT(22), 0); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(2, 0), 0x7); ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, GENMASK(10, 8), 0x7); ++} ++ ++static void rtw8812a_phy_set_rfe_reg_24g(struct rtw_dev *rtwdev) ++{ ++ switch (rtwdev->efuse.rfe_option) { ++ case 0: ++ case 2: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ break; ++ case 1: ++ if (rtwdev->efuse.btcoex) { ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } ++ break; ++ case 3: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337770); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337770); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); ++ break; ++ case 4: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x001); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x001); ++ break; ++ case 5: ++ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x77); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777777); ++ rtw_write8_clr(rtwdev, REG_RFE_INV_A + 3, BIT(0)); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ break; ++ case 6: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07772770); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07772770); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_phy_set_rfe_reg_5g(struct rtw_dev *rtwdev) ++{ ++ switch (rtwdev->efuse.rfe_option) { ++ case 0: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 1: ++ if (rtwdev->efuse.btcoex) { ++ rtw_write32_mask(rtwdev, REG_RFE_PINMUX_A, 0xffffff, 0x337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, 0x33f00000, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x000); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x000); ++ } ++ break; ++ case 2: ++ case 4: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77337777); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 3: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x54337717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x54337717); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_A, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ rtw_write32_mask(rtwdev, REG_ANTSEL_SW, 0x00000303, 0x1); ++ break; ++ case 5: ++ rtw_write8(rtwdev, REG_RFE_PINMUX_A + 2, 0x33); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77337777); ++ rtw_write8_set(rtwdev, REG_RFE_INV_A + 3, BIT(0)); ++ rtw_write32_mask(rtwdev, REG_RFE_INV_B, RFE_INV_MASK, 0x010); ++ break; ++ case 6: ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x07737717); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x07737717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw88xxa_switch_band(struct rtw_dev *rtwdev, u8 new_band, u8 bw) ++{ ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ u16 basic_rates, reg_41a; ++ ++ /* 8811au one antenna module doesn't support antenna div, so driver must ++ * control antenna band, otherwise one of the band will have issue ++ */ ++ if (chip->id == RTW_CHIP_TYPE_8821A && !rtwdev->efuse.btcoex && ++ rtwdev->efuse.ant_div_cfg == 0) ++ rtw8821a_set_ext_band_switch(rtwdev, new_band); ++ ++ if (new_band == RTW_BAND_2G) { ++ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ rtw8821a_phy_set_rfe_reg_24g(rtwdev); ++ ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x1); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x17); ++ ++ if (bw == RTW_CHANNEL_WIDTH_20 && ++ rtwdev->hal.rf_type == RF_1T1R && ++ !rtwdev->efuse.ext_lna_2g) ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x02); ++ else ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); ++ ++ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 0); ++ ++ rtw8812a_phy_set_rfe_reg_24g(rtwdev); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0x1); ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0x1); ++ ++ basic_rates = BIT(DESC_RATE1M) | BIT(DESC_RATE2M) | ++ BIT(DESC_RATE5_5M) | BIT(DESC_RATE11M) | ++ BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | ++ BIT(DESC_RATE24M); ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); ++ ++ rtw_write8_clr(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); ++ } else { /* RTW_BAND_5G */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw8821a_phy_set_rfe_reg_5g(rtwdev); ++ ++ rtw_write8_set(rtwdev, REG_CCK_CHECK, BIT_CHECK_CCK_EN); ++ ++ read_poll_timeout_atomic(rtw_read16, reg_41a, (reg_41a & 0x30) == 0x30, ++ 50, 2500, false, rtwdev, REG_TXPKT_EMPTY); ++ ++ rtw_write32_set(rtwdev, REG_RXPSEL, BIT_RX_PSEL_RST); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ rtw_write32_mask(rtwdev, REG_TXSCALE_A, 0xf00, 1); ++ } else { ++ rtw_write32_mask(rtwdev, REG_BWINDICATION, 0x3, 0x2); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(17, 13), 0x15); ++ rtw_write32_mask(rtwdev, REG_PDMFTH, GENMASK(3, 1), 0x04); ++ ++ rtw_write32_mask(rtwdev, REG_CCASEL, 0x3, 1); ++ ++ rtw8812a_phy_set_rfe_reg_5g(rtwdev); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_TXPSEL, 0xf0, 0); ++ rtw_write32_mask(rtwdev, REG_CCK_RX, 0x0f000000, 0xf); ++ ++ basic_rates = BIT(DESC_RATE6M) | BIT(DESC_RATE12M) | ++ BIT(DESC_RATE24M); ++ rtw_write32_mask(rtwdev, REG_RRSR, 0xfffff, basic_rates); ++ } ++ ++ rtw88xxa_set_channel_bb_swing(rtwdev, new_band); ++} ++ ++int rtw88xxa_power_on(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ struct rtw_hal *hal = &rtwdev->hal; ++ int ret; ++ ++ if (test_bit(RTW_FLAG_POWERON, rtwdev->flags)) ++ return 0; ++ ++ /* Override rtw_chip_efuse_info_setup() */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ efuse->btcoex = rtw_read32_mask(rtwdev, REG_WL_BT_PWR_CTRL, ++ BIT_BT_FUNC_EN); ++ ++ /* Override rtw_chip_efuse_info_setup() */ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_read_amplifier_type(rtwdev); ++ ++ ret = rtw_hci_setup(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to setup hci\n"); ++ goto err; ++ } ++ ++ /* Revise for U2/U3 switch we can not update RF-A/B reset. ++ * Reset after MAC power on to prevent RF R/W error. ++ * Is it a right method? ++ */ ++ if (chip->id == RTW_CHIP_TYPE_8812A) { ++ rtw_write8(rtwdev, REG_RF_CTRL, 5); ++ rtw_write8(rtwdev, REG_RF_CTRL, 7); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, 5); ++ rtw_write8(rtwdev, REG_RF_B_CTRL, 7); ++ } ++ ++ /* If HW didn't go through a complete de-initial procedure, ++ * it probably occurs some problem for double initial ++ * procedure. ++ */ ++ rtw88xxau_hw_reset(rtwdev); ++ ++ ret = rtw88xxau_init_power_on(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to power on\n"); ++ goto err; ++ } ++ ++ ret = rtw_set_trx_fifo_info(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to set trx fifo info\n"); ++ goto err; ++ } ++ ++ ret = rtw88xxa_llt_init(rtwdev, rtwdev->fifo.rsvd_boundary); ++ if (ret) { ++ rtw_err(rtwdev, "failed to init llt\n"); ++ goto err; ++ } ++ ++ rtw_write32_set(rtwdev, REG_TXDMA_OFFSET_CHK, BIT_DROP_DATA_EN); ++ ++ ret = rtw_wait_firmware_completion(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to wait firmware completion\n"); ++ goto err_off; ++ } ++ ++ ret = rtw_download_firmware(rtwdev, &rtwdev->fw); ++ if (ret) { ++ rtw_err(rtwdev, "failed to download firmware\n"); ++ goto err_off; ++ } ++ ++ rtw_write8(rtwdev, REG_HMETFR, 0xf); ++ ++ rtw_load_table(rtwdev, chip->mac_tbl); ++ ++ rtw88xxau_init_queue_reserved_page(rtwdev); ++ rtw88xxau_init_tx_buffer_boundary(rtwdev); ++ rtw88xxau_init_queue_priority(rtwdev); ++ ++ rtw_write16(rtwdev, REG_TRXFF_BNDY + 2, ++ chip->rxff_size - REPORT_BUF - 1); ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A) ++ rtw_write8(rtwdev, REG_PBP, ++ u8_encode_bits(PBP_512, PBP_TX_MASK) | ++ u8_encode_bits(PBP_64, PBP_RX_MASK)); ++ ++ rtw_write8(rtwdev, REG_RX_DRVINFO_SZ, PHY_STATUS_SIZE); ++ ++ rtw_write32(rtwdev, REG_HIMR0, 0); ++ rtw_write32(rtwdev, REG_HIMR1, 0); ++ ++ rtw_write32_mask(rtwdev, REG_CR, 0x30000, 0x2); ++ ++ rtw88xxa_init_wmac_setting(rtwdev); ++ rtw88xxa_init_adaptive_ctrl(rtwdev); ++ rtw88xxa_init_edca(rtwdev); ++ ++ rtw_write8_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ rtw_write8(rtwdev, REG_ACKTO, 0x80); ++ ++ rtw88xxau_tx_aggregation(rtwdev); ++ ++ rtw88xxa_init_beacon_parameters(rtwdev); ++ rtw_write8(rtwdev, REG_BCN_MAX_ERR, 0xff); ++ ++ rtw_hci_interface_cfg(rtwdev); ++ ++ /* usb3 rx interval */ ++ rtw_write8(rtwdev, REG_USB3_RXITV, 0x01); ++ ++ /* burst length=4, set 0x3400 for burst length=2 */ ++ rtw_write16(rtwdev, REG_RXDMA_STATUS, 0x7400); ++ rtw_write8(rtwdev, REG_RXDMA_STATUS + 1, 0xf5); ++ ++ /* 0x456 = 0x70, sugguested by Zhilin */ ++ if (chip->id == RTW_CHIP_TYPE_8821A) ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x5e); ++ else ++ rtw_write8(rtwdev, REG_AMPDU_MAX_TIME, 0x70); ++ ++ rtw_write32(rtwdev, REG_AMPDU_MAX_LENGTH, 0xffffffff); ++ rtw_write8(rtwdev, REG_USTIME_TSF, 0x50); ++ rtw_write8(rtwdev, REG_USTIME_EDCA, 0x50); ++ ++ if (rtwusb->udev->speed == USB_SPEED_SUPER) ++ /* Disable U1/U2 Mode to avoid 2.5G spur in USB3.0. */ ++ rtw_write8_clr(rtwdev, REG_USB_MOD, BIT(4) | BIT(3)); ++ ++ rtw_write8_set(rtwdev, REG_SINGLE_AMPDU_CTRL, BIT_EN_SINGLE_APMDU); ++ ++ /* for VHT packet length 11K */ ++ rtw_write8(rtwdev, REG_RX_PKT_LIMIT, 0x18); ++ ++ rtw_write8(rtwdev, REG_PIFS, 0x00); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A) { ++ /* 0x0a0a too small, it can't pass AC logo. change to 0x1f1f */ ++ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); ++ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL, 0x80); ++ rtw_write32(rtwdev, REG_FAST_EDCA_CTRL, 0x03087777); ++ } else { ++ rtw_write16(rtwdev, REG_MAX_AGGR_NUM, 0x1f1f); ++ rtw_write8_clr(rtwdev, REG_FWHW_TXQ_CTRL, BIT(7)); ++ } ++ ++ /* to prevent mac is reseted by bus. */ ++ rtw_write8_set(rtwdev, REG_RSV_CTRL, BIT(5) | BIT(6)); ++ ++ /* ARFB table 9 for 11ac 5G 2SS */ ++ rtw_write32(rtwdev, REG_ARFR0, 0x00000010); ++ rtw_write32(rtwdev, REG_ARFRH0, 0xfffff000); ++ ++ /* ARFB table 10 for 11ac 5G 1SS */ ++ rtw_write32(rtwdev, REG_ARFR1_V1, 0x00000010); ++ rtw_write32(rtwdev, REG_ARFRH1_V1, 0x003ff000); ++ ++ /* ARFB table 11 for 11ac 24G 1SS */ ++ rtw_write32(rtwdev, REG_ARFR2_V1, 0x00000015); ++ rtw_write32(rtwdev, REG_ARFRH2_V1, 0x003ff000); ++ ++ /* ARFB table 12 for 11ac 24G 2SS */ ++ rtw_write32(rtwdev, REG_ARFR3_V1, 0x00000015); ++ rtw_write32(rtwdev, REG_ARFRH3_V1, 0xffcff000); ++ ++ rtw_write8_set(rtwdev, REG_CR, BIT_MACTXEN | BIT_MACRXEN); ++ ++ rtw88xxa_phy_bb_config(rtwdev); ++ rtw88xxa_phy_rf_config(rtwdev); ++ ++ if (chip->id == RTW_CHIP_TYPE_8812A && hal->rf_path_num == 1) ++ rtw8812a_config_1t(rtwdev); ++ ++ rtw88xxa_switch_band(rtwdev, RTW_BAND_2G, RTW_CHANNEL_WIDTH_20); ++ ++ rtw_write32(rtwdev, RTW_SEC_CMD_REG, BIT(31) | BIT(30)); ++ ++ rtw_write8(rtwdev, REG_HWSEQ_CTRL, 0xff); ++ rtw_write32(rtwdev, REG_BAR_MODE_CTRL, 0x0201ffff); ++ rtw_write8(rtwdev, REG_NAV_CTRL + 2, 0); ++ ++ rtw_write8_clr(rtwdev, REG_GPIO_MUXCFG, BIT(5)); ++ ++ rtw_phy_init(rtwdev); ++ ++ rtw88xxa_pwrtrack_init(rtwdev); ++ ++ /* 0x4c6[3] 1: RTS BW = Data BW ++ * 0: RTS BW depends on CCA / secondary CCA result. ++ */ ++ rtw_write8_clr(rtwdev, REG_QUEUE_CTRL, BIT(3)); ++ ++ /* enable Tx report. */ ++ rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 1, 0x0f); ++ ++ /* Pretx_en, for WEP/TKIP SEC */ ++ rtw_write8(rtwdev, REG_EARLY_MODE_CONTROL + 3, 0x01); ++ ++ rtw_write16(rtwdev, REG_TX_RPT_TIME, 0x3df0); ++ ++ /* Reset USB mode switch setting */ ++ rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x0); ++ rtw_write8(rtwdev, REG_ACLK_MON, 0x0); ++ ++ rtw_write8(rtwdev, REG_USB_HRPWM, 0); ++ ++ /* ack for xmit mgmt frames. */ ++ rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL, BIT(12)); ++ ++ hal->cck_high_power = rtw_read32_mask(rtwdev, REG_CCK_RPT_FORMAT, ++ BIT_CCK_RPT_FORMAT); ++ ++ ret = rtw_hci_start(rtwdev); ++ if (ret) { ++ rtw_err(rtwdev, "failed to start hci\n"); ++ goto err_off; ++ } ++ ++ if (efuse->btcoex) { ++ rtw_coex_power_on_setting(rtwdev); ++ rtw_coex_init_hw_config(rtwdev, false); ++ } ++ ++ set_bit(RTW_FLAG_POWERON, rtwdev->flags); ++ ++ return 0; ++ ++err_off: ++ chip->ops->power_off(rtwdev); ++ ++err: ++ return ret; ++} ++EXPORT_SYMBOL(rtw88xxa_power_on); ++ ++u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path rf_path, u32 addr, u32 mask) ++{ ++ static const u32 pi_addr[2] = { REG_3WIRE_SWA, REG_3WIRE_SWB }; ++ static const u32 read_addr[2][2] = { ++ { REG_SI_READ_A, REG_SI_READ_B }, ++ { REG_PI_READ_A, REG_PI_READ_B } ++ }; ++ const struct rtw_chip_info *chip = rtwdev->chip; ++ const struct rtw_hal *hal = &rtwdev->hal; ++ bool set_cca, pi_mode; ++ u32 val; ++ ++ if (rf_path >= hal->rf_phy_num) { ++ rtw_err(rtwdev, "unsupported rf path (%d)\n", rf_path); ++ return INV_RF_DATA; ++ } ++ ++ /* CCA off to avoid reading the wrong value. ++ * Toggling CCA would affect RF 0x0, skip it. ++ */ ++ set_cca = addr != 0x0 && chip->id == RTW_CHIP_TYPE_8812A && ++ hal->cut_version != RTW_CHIP_VER_CUT_C; ++ ++ if (set_cca) ++ rtw_write32_set(rtwdev, REG_CCA2ND, BIT(3)); ++ ++ addr &= 0xff; ++ ++ pi_mode = rtw_read32_mask(rtwdev, pi_addr[rf_path], 0x4); ++ ++ rtw_write32_mask(rtwdev, REG_HSSI_READ, MASKBYTE0, addr); ++ ++ if (chip->id == RTW_CHIP_TYPE_8821A || ++ hal->cut_version == RTW_CHIP_VER_CUT_C) ++ udelay(20); ++ ++ val = rtw_read32_mask(rtwdev, read_addr[pi_mode][rf_path], mask); ++ ++ /* CCA on */ ++ if (set_cca) ++ rtw_write32_clr(rtwdev, REG_CCA2ND, BIT(3)); ++ ++ return val; ++} ++EXPORT_SYMBOL(rtw88xxa_phy_read_rf); ++ ++static void rtw8812a_phy_fix_spur(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ /* C cut Item12 ADC FIFO CLOCK */ ++ if (rtwdev->hal.cut_version == RTW_CHIP_VER_CUT_C) { ++ if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x3); ++ else ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0xC00, 0x2); ++ ++ /* A workaround to resolve 2480Mhz spur by setting ADC clock ++ * as 160M. ++ */ ++ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) { ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ } else if (bw == RTW_CHANNEL_WIDTH_40 && channel == 11) { ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ } else if (bw != RTW_CHANNEL_WIDTH_80) { ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ } ++ } else { ++ /* A workaround to resolve 2480Mhz spur by setting ADC clock ++ * as 160M. ++ */ ++ if (bw == RTW_CHANNEL_WIDTH_20 && (channel == 13 || channel == 14)) ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x3); ++ else if (channel <= 14) /* 2.4G only */ ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x300, 0x2); ++ } ++} ++ ++static void rtw88xxa_switch_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u32 fc_area, rf_mod_ag; ++ u8 path; ++ ++ switch (channel) { ++ case 36 ... 48: ++ fc_area = 0x494; ++ break; ++ case 50 ... 64: ++ fc_area = 0x453; ++ break; ++ case 100 ... 116: ++ fc_area = 0x452; ++ break; ++ default: ++ if (channel >= 118) ++ fc_area = 0x412; ++ else ++ fc_area = 0x96a; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_CLKTRK, 0x1ffe0000, fc_area); ++ ++ for (path = 0; path < hal->rf_path_num; path++) { ++ switch (channel) { ++ case 36 ... 64: ++ rf_mod_ag = 0x101; ++ break; ++ case 100 ... 140: ++ rf_mod_ag = 0x301; ++ break; ++ default: ++ if (channel > 140) ++ rf_mod_ag = 0x501; ++ else ++ rf_mod_ag = 0x000; ++ break; ++ } ++ ++ rtw_write_rf(rtwdev, path, RF_CFGCH, ++ RF18_RFSI_MASK | RF18_BAND_MASK, rf_mod_ag); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_phy_fix_spur(rtwdev, channel, bw); ++ ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_CHANNEL_MASK, channel); ++ } ++} ++ ++static void rtw88xxa_set_reg_bw(struct rtw_dev *rtwdev, u8 bw) ++{ ++ u16 val16 = rtw_read16(rtwdev, REG_WMAC_TRXPTCL_CTL); ++ ++ val16 &= ~BIT_RFMOD; ++ if (bw == RTW_CHANNEL_WIDTH_80) ++ val16 |= BIT_RFMOD_80M; ++ else if (bw == RTW_CHANNEL_WIDTH_40) ++ val16 |= BIT_RFMOD_40M; ++ ++ rtw_write16(rtwdev, REG_WMAC_TRXPTCL_CTL, val16); ++} ++ ++static void rtw88xxa_post_set_bw_mode(struct rtw_dev *rtwdev, u8 channel, ++ u8 bw, u8 primary_chan_idx) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u8 txsc40 = 0, txsc20, txsc; ++ u8 reg_837, l1pkval; ++ ++ rtw88xxa_set_reg_bw(rtwdev, bw); ++ ++ txsc20 = primary_chan_idx; ++ if (bw == RTW_CHANNEL_WIDTH_80) { ++ if (txsc20 == RTW_SC_20_UPPER || txsc20 == RTW_SC_20_UPMOST) ++ txsc40 = RTW_SC_40_UPPER; ++ else ++ txsc40 = RTW_SC_40_LOWER; ++ } ++ ++ txsc = BIT_TXSC_20M(txsc20) | BIT_TXSC_40M(txsc40); ++ rtw_write8(rtwdev, REG_DATA_SC, txsc); ++ ++ reg_837 = rtw_read8(rtwdev, REG_BWINDICATION + 3); ++ ++ switch (bw) { ++ default: ++ case RTW_CHANNEL_WIDTH_20: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300200); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ ++ if (hal->rf_type == RF_2T2R) ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 7); ++ else ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, 8); ++ ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300201); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 0); ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); ++ ++ if (reg_837 & BIT(2)) { ++ l1pkval = 6; ++ } else { ++ if (hal->rf_type == RF_2T2R) ++ l1pkval = 7; ++ else ++ l1pkval = 8; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); ++ ++ if (txsc == RTW_SC_20_UPPER) ++ rtw_write32_set(rtwdev, REG_RXSB, BIT(4)); ++ else ++ rtw_write32_clr(rtwdev, REG_RXSB, BIT(4)); ++ ++ break; ++ case RTW_CHANNEL_WIDTH_80: ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x003003C3, 0x00300202); ++ rtw_write32_mask(rtwdev, REG_ADC160, BIT(30), 1); ++ rtw_write32_mask(rtwdev, REG_ADCCLK, 0x3C, txsc); ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf0000000, txsc); ++ ++ if (reg_837 & BIT(2)) { ++ l1pkval = 5; ++ } else { ++ if (hal->rf_type == RF_2T2R) ++ l1pkval = 6; ++ else ++ l1pkval = 7; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_L1PKTH, 0x03C00000, l1pkval); ++ ++ break; ++ } ++} ++ ++static void rtw88xxa_set_channel_rf(struct rtw_dev *rtwdev, u8 channel, u8 bw) ++{ ++ u8 path; ++ ++ for (path = RF_PATH_A; path < rtwdev->hal.rf_path_num; path++) { ++ switch (bw) { ++ case RTW_CHANNEL_WIDTH_5: ++ case RTW_CHANNEL_WIDTH_10: ++ case RTW_CHANNEL_WIDTH_20: ++ default: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 3); ++ break; ++ case RTW_CHANNEL_WIDTH_40: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 1); ++ break; ++ case RTW_CHANNEL_WIDTH_80: ++ rtw_write_rf(rtwdev, path, RF_CFGCH, RF18_BW_MASK, 0); ++ break; ++ } ++ } ++} ++ ++void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, ++ u8 primary_chan_idx) ++{ ++ u8 old_band, new_band; ++ ++ if (rtw_read8(rtwdev, REG_CCK_CHECK) & BIT_CHECK_CCK_EN) ++ old_band = RTW_BAND_5G; ++ else ++ old_band = RTW_BAND_2G; ++ ++ if (channel > 14) ++ new_band = RTW_BAND_5G; ++ else ++ new_band = RTW_BAND_2G; ++ ++ if (new_band != old_band) ++ rtw88xxa_switch_band(rtwdev, new_band, bw); ++ ++ rtw88xxa_switch_channel(rtwdev, channel, bw); ++ ++ rtw88xxa_post_set_bw_mode(rtwdev, channel, bw, primary_chan_idx); ++ ++ if (rtwdev->chip->id == RTW_CHIP_TYPE_8812A) ++ rtw8812a_phy_fix_spur(rtwdev, channel, bw); ++ ++ rtw88xxa_set_channel_rf(rtwdev, channel, bw); ++} ++EXPORT_SYMBOL(rtw88xxa_set_channel); ++ ++void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_jaguar_phy_status_rpt *rpt; ++ u8 gain[RTW_RF_PATH_MAX], rssi, i; ++ s8 rx_pwr_db, power_a, power_b; ++ const s8 min_rx_power = -120; ++ u8 lna_idx, vga_idx; ++ ++ rpt = (struct rtw_jaguar_phy_status_rpt *)phy_status; ++ ++ if (pkt_stat->rate <= DESC_RATE11M) { ++ lna_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_LNA_IDX); ++ vga_idx = le32_get_bits(rpt->w1, RTW_JGRPHY_W1_AGC_RPT_VGA_IDX); ++ ++ rx_pwr_db = cck_rx_pwr(lna_idx, vga_idx); ++ ++ pkt_stat->rx_power[RF_PATH_A] = rx_pwr_db; ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, 1); ++ dm_info->rssi[RF_PATH_A] = pkt_stat->rssi; ++ pkt_stat->bw = RTW_CHANNEL_WIDTH_20; ++ pkt_stat->signal_power = rx_pwr_db; ++ } else { /* OFDM rate */ ++ gain[RF_PATH_A] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_A); ++ gain[RF_PATH_B] = le32_get_bits(rpt->w0, RTW_JGRPHY_W0_GAIN_B); ++ ++ for (i = RF_PATH_A; i < rtwdev->hal.rf_path_num; i++) { ++ pkt_stat->rx_power[i] = gain[i] - 110; ++ rssi = rtw_phy_rf_power_2_rssi(&pkt_stat->rx_power[i], 1); ++ dm_info->rssi[i] = rssi; ++ } ++ ++ pkt_stat->rssi = rtw_phy_rf_power_2_rssi(pkt_stat->rx_power, ++ rtwdev->hal.rf_path_num); ++ ++ power_a = pkt_stat->rx_power[RF_PATH_A]; ++ power_b = pkt_stat->rx_power[RF_PATH_B]; ++ if (rtwdev->hal.rf_path_num == 1) ++ power_b = power_a; ++ ++ pkt_stat->signal_power = max3(power_a, power_b, min_rx_power); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_query_phy_status); ++ ++static void ++rtw88xxa_set_tx_power_index_by_rate(struct rtw_dev *rtwdev, u8 path, ++ u8 rs, u32 *phy_pwr_idx) ++{ ++ static const u32 offset_txagc[2] = { ++ REG_TX_AGC_A_CCK_11_CCK_1, REG_TX_AGC_B_CCK_11_CCK_1 ++ }; ++ u8 rate, rate_idx, pwr_index, shift; ++ struct rtw_hal *hal = &rtwdev->hal; ++ bool write_1ss_mcs9; ++ u32 mask; ++ int j; ++ ++ for (j = 0; j < rtw_rate_size[rs]; j++) { ++ rate = rtw_rate_section[rs][j]; ++ ++ pwr_index = hal->tx_pwr_tbl[path][rate]; ++ ++ shift = rate & 0x3; ++ *phy_pwr_idx |= ((u32)pwr_index << (shift * 8)); ++ ++ write_1ss_mcs9 = rate == DESC_RATEVHT1SS_MCS9 && ++ hal->rf_path_num == 1; ++ ++ if (write_1ss_mcs9) ++ mask = MASKLWORD; ++ else ++ mask = MASKDWORD; ++ ++ if (shift == 0x3 || write_1ss_mcs9) { ++ rate_idx = rate & 0xfc; ++ if (rate >= DESC_RATEVHT1SS_MCS0) ++ rate_idx -= 0x10; ++ ++ rtw_write32_mask(rtwdev, offset_txagc[path] + rate_idx, ++ mask, *phy_pwr_idx); ++ ++ *phy_pwr_idx = 0; ++ } ++ } ++} ++ ++static void rtw88xxa_tx_power_training(struct rtw_dev *rtwdev, u8 bw, ++ u8 channel, u8 path) ++{ ++ static const u32 write_offset[] = { ++ REG_TX_PWR_TRAINING_A, REG_TX_PWR_TRAINING_B, ++ }; ++ u32 power_level, write_data; ++ u8 i; ++ ++ power_level = rtwdev->hal.tx_pwr_tbl[path][DESC_RATEMCS7]; ++ write_data = 0; ++ ++ for (i = 0; i < 3; i++) { ++ if (i == 0) ++ power_level -= 10; ++ else if (i == 1) ++ power_level -= 8; ++ else ++ power_level -= 6; ++ ++ write_data |= max_t(u32, power_level, 2) << (i * 8); ++ } ++ ++ rtw_write32_mask(rtwdev, write_offset[path], 0xffffff, write_data); ++} ++ ++void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev) ++{ ++ struct rtw_hal *hal = &rtwdev->hal; ++ u32 phy_pwr_idx = 0; ++ int rs, path; ++ ++ for (path = 0; path < hal->rf_path_num; path++) { ++ for (rs = 0; rs < RTW_RATE_SECTION_MAX; rs++) { ++ if (hal->rf_path_num == 1 && ++ (rs == RTW_RATE_SECTION_HT_2S || ++ rs == RTW_RATE_SECTION_VHT_2S)) ++ continue; ++ ++ if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags) && ++ rs > RTW_RATE_SECTION_OFDM) ++ continue; ++ ++ if (hal->current_band_type == RTW_BAND_5G && ++ rs == RTW_RATE_SECTION_CCK) ++ continue; ++ ++ rtw88xxa_set_tx_power_index_by_rate(rtwdev, path, rs, ++ &phy_pwr_idx); ++ } ++ ++ rtw88xxa_tx_power_training(rtwdev, hal->current_band_width, ++ hal->current_channel, path); ++ } ++} ++EXPORT_SYMBOL(rtw88xxa_set_tx_power_index); ++ ++void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u32 cck_fa_cnt, ofdm_fa_cnt; ++ u32 crc32_cnt, cca32_cnt; ++ u32 cck_enable; ++ ++ cck_enable = rtw_read32(rtwdev, REG_RXPSEL) & BIT(28); ++ cck_fa_cnt = rtw_read16(rtwdev, REG_FA_CCK); ++ ofdm_fa_cnt = rtw_read16(rtwdev, REG_FA_OFDM); ++ ++ dm_info->cck_fa_cnt = cck_fa_cnt; ++ dm_info->ofdm_fa_cnt = ofdm_fa_cnt; ++ dm_info->total_fa_cnt = ofdm_fa_cnt; ++ if (cck_enable) ++ dm_info->total_fa_cnt += cck_fa_cnt; ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_CCK); ++ dm_info->cck_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->cck_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_OFDM); ++ dm_info->ofdm_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->ofdm_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_HT); ++ dm_info->ht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->ht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ crc32_cnt = rtw_read32(rtwdev, REG_CRC_VHT); ++ dm_info->vht_ok_cnt = u32_get_bits(crc32_cnt, MASKLWORD); ++ dm_info->vht_err_cnt = u32_get_bits(crc32_cnt, MASKHWORD); ++ ++ cca32_cnt = rtw_read32(rtwdev, REG_CCA_OFDM); ++ dm_info->ofdm_cca_cnt = u32_get_bits(cca32_cnt, MASKHWORD); ++ dm_info->total_cca_cnt = dm_info->ofdm_cca_cnt; ++ if (cck_enable) { ++ cca32_cnt = rtw_read32(rtwdev, REG_CCA_CCK); ++ dm_info->cck_cca_cnt = u32_get_bits(cca32_cnt, MASKLWORD); ++ dm_info->total_cca_cnt += dm_info->cck_cca_cnt; ++ } ++ ++ rtw_write32_set(rtwdev, REG_FAS, BIT(17)); ++ rtw_write32_clr(rtwdev, REG_FAS, BIT(17)); ++ rtw_write32_clr(rtwdev, REG_CCK0_FAREPORT, BIT(15)); ++ rtw_write32_set(rtwdev, REG_CCK0_FAREPORT, BIT(15)); ++ rtw_write32_set(rtwdev, REG_CNTRST, BIT(0)); ++ rtw_write32_clr(rtwdev, REG_CNTRST, BIT(0)); ++} ++EXPORT_SYMBOL(rtw88xxa_false_alarm_statistics); ++ ++void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* save MACBB default value */ ++ for (i = 0; i < macbb_num; i++) ++ macbb_backup[i] = rtw_read32(rtwdev, backup_macbb_reg[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_backup_mac_bb); ++ ++void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ afe_backup[i] = rtw_read32(rtwdev, backup_afe_reg[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_backup_afe); ++ ++void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload MacBB Parameters */ ++ for (i = 0; i < macbb_num; i++) ++ rtw_write32(rtwdev, backup_macbb_reg[i], macbb_backup[i]); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_restore_mac_bb); ++ ++void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev) ++{ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ rtw_write8(rtwdev, REG_TXPAUSE, 0x3f); ++ rtw_write32_mask(rtwdev, REG_BCN_CTRL, ++ (BIT_EN_BCN_FUNCTION << 8) | BIT_EN_BCN_FUNCTION, 0x0); ++ ++ /* RX ante off */ ++ rtw_write8(rtwdev, REG_RXPSEL, 0x00); ++ ++ /* CCA off */ ++ rtw_write32_mask(rtwdev, REG_CCA2ND, 0xf, 0xc); ++ ++ /* CCK RX path off */ ++ rtw_write8(rtwdev, REG_CCK_RX + 3, 0xf); ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_configure_mac); ++ ++bool rtw88xxa_iqk_finish(int average, int threshold, ++ int *x_temp, int *y_temp, int *x, int *y, ++ bool break_inner, bool break_outer) ++{ ++ bool finish = false; ++ int i, ii, dx, dy; ++ ++ for (i = 0; i < average; i++) { ++ for (ii = i + 1; ii < average; ii++) { ++ dx = abs_diff(x_temp[i] >> 21, x_temp[ii] >> 21); ++ dy = abs_diff(y_temp[i] >> 21, y_temp[ii] >> 21); ++ ++ if (dx < threshold && dy < threshold) { ++ *x = ((x_temp[i] >> 21) + (x_temp[ii] >> 21)); ++ *y = ((y_temp[i] >> 21) + (y_temp[ii] >> 21)); ++ ++ *x /= 2; ++ *y /= 2; ++ ++ finish = true; ++ ++ if (break_inner) ++ break; ++ } ++ } ++ ++ if (finish && break_outer) ++ break; ++ } ++ ++ return finish; ++} ++EXPORT_SYMBOL(rtw88xxa_iqk_finish); ++ ++static void rtw88xxa_pwrtrack_set(struct rtw_dev *rtwdev, u8 tx_rate, u8 path) ++{ ++ static const u32 reg_txscale[2] = { REG_TXSCALE_A, REG_TXSCALE_B }; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ u8 cck_swing_idx, ofdm_swing_idx; ++ u8 pwr_tracking_limit; ++ ++ switch (tx_rate) { ++ case DESC_RATE1M ... DESC_RATE11M: ++ pwr_tracking_limit = 32; ++ break; ++ case DESC_RATE6M ... DESC_RATE48M: ++ case DESC_RATEMCS3 ... DESC_RATEMCS4: ++ case DESC_RATEMCS11 ... DESC_RATEMCS12: ++ case DESC_RATEVHT1SS_MCS3 ... DESC_RATEVHT1SS_MCS4: ++ case DESC_RATEVHT2SS_MCS3 ... DESC_RATEVHT2SS_MCS4: ++ pwr_tracking_limit = 30; ++ break; ++ case DESC_RATE54M: ++ case DESC_RATEMCS5 ... DESC_RATEMCS7: ++ case DESC_RATEMCS13 ... DESC_RATEMCS15: ++ case DESC_RATEVHT1SS_MCS5 ... DESC_RATEVHT1SS_MCS6: ++ case DESC_RATEVHT2SS_MCS5 ... DESC_RATEVHT2SS_MCS6: ++ pwr_tracking_limit = 28; ++ break; ++ case DESC_RATEMCS0 ... DESC_RATEMCS2: ++ case DESC_RATEMCS8 ... DESC_RATEMCS10: ++ case DESC_RATEVHT1SS_MCS0 ... DESC_RATEVHT1SS_MCS2: ++ case DESC_RATEVHT2SS_MCS0 ... DESC_RATEVHT2SS_MCS2: ++ pwr_tracking_limit = 34; ++ break; ++ case DESC_RATEVHT1SS_MCS7: ++ case DESC_RATEVHT2SS_MCS7: ++ pwr_tracking_limit = 26; ++ break; ++ default: ++ case DESC_RATEVHT1SS_MCS8: ++ case DESC_RATEVHT2SS_MCS8: ++ pwr_tracking_limit = 24; ++ break; ++ case DESC_RATEVHT1SS_MCS9: ++ case DESC_RATEVHT2SS_MCS9: ++ pwr_tracking_limit = 22; ++ break; ++ } ++ ++ cck_swing_idx = dm_info->delta_power_index[path] + dm_info->default_cck_index; ++ ofdm_swing_idx = dm_info->delta_power_index[path] + dm_info->default_ofdm_index; ++ ++ if (ofdm_swing_idx > pwr_tracking_limit) { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = cck_swing_idx - pwr_tracking_limit; ++ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx - pwr_tracking_limit; ++ ++ ofdm_swing_idx = pwr_tracking_limit; ++ } else if (ofdm_swing_idx == 0) { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = cck_swing_idx; ++ dm_info->txagc_remnant_ofdm[path] = ofdm_swing_idx; ++ } else { ++ if (path == RF_PATH_A) ++ dm_info->txagc_remnant_cck = 0; ++ dm_info->txagc_remnant_ofdm[path] = 0; ++ } ++ ++ rtw_write32_mask(rtwdev, reg_txscale[path], GENMASK(31, 21), ++ rtw88xxa_txscale_tbl[ofdm_swing_idx]); ++} ++ ++void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, ++ void (*do_lck)(struct rtw_dev *rtwdev), ++ void (*do_iqk)(struct rtw_dev *rtwdev)) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ struct rtw_hal *hal = &rtwdev->hal; ++ struct rtw_swing_table swing_table; ++ s8 remnant_pre[RTW_RF_PATH_MAX]; ++ u8 thermal_value, delta, path; ++ bool need_iqk; ++ ++ rtw_phy_config_swing_table(rtwdev, &swing_table); ++ ++ if (rtwdev->efuse.thermal_meter[0] == 0xff) { ++ pr_err_once("efuse thermal meter is 0xff\n"); ++ return; ++ } ++ ++ thermal_value = rtw_read_rf(rtwdev, RF_PATH_A, RF_T_METER, 0xfc00); ++ ++ rtw_phy_pwrtrack_avg(rtwdev, thermal_value, RF_PATH_A); ++ ++ need_iqk = rtw_phy_pwrtrack_need_iqk(rtwdev); ++ ++ if (need_iqk && do_lck) ++ do_lck(rtwdev); ++ ++ if (dm_info->pwr_trk_init_trigger) ++ dm_info->pwr_trk_init_trigger = false; ++ else if (!rtw_phy_pwrtrack_thermal_changed(rtwdev, thermal_value, ++ RF_PATH_A)) ++ goto iqk; ++ ++ delta = rtw_phy_pwrtrack_get_delta(rtwdev, RF_PATH_A); ++ ++ for (path = RF_PATH_A; path < hal->rf_path_num; path++) { ++ remnant_pre[path] = dm_info->txagc_remnant_ofdm[path]; ++ ++ dm_info->delta_power_index[path] = ++ rtw_phy_pwrtrack_get_pwridx(rtwdev, &swing_table, path, ++ RF_PATH_A, delta); ++ ++ if (dm_info->delta_power_index[path] != ++ dm_info->delta_power_index_last[path]) { ++ dm_info->delta_power_index_last[path] = ++ dm_info->delta_power_index[path]; ++ ++ rtw88xxa_pwrtrack_set(rtwdev, dm_info->tx_rate, path); ++ } ++ } ++ ++ for (path = RF_PATH_A; path < hal->rf_path_num; path++) { ++ if (remnant_pre[path] != dm_info->txagc_remnant_ofdm[path]) { ++ rtw_phy_set_tx_power_level(rtwdev, ++ hal->current_channel); ++ break; ++ } ++ } ++ ++iqk: ++ if (need_iqk) ++ do_iqk(rtwdev); ++} ++EXPORT_SYMBOL(rtw88xxa_phy_pwrtrack); ++ ++void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl) ++{ ++ static const u8 pd[CCK_PD_LV_MAX] = {0x40, 0x83, 0xcd, 0xdd, 0xed}; ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ /* Override rtw_phy_cck_pd_lv_link(). It implements something ++ * like type 2/3/4. We need type 1 here. ++ */ ++ if (rtw_is_assoc(rtwdev)) { ++ if (dm_info->min_rssi > 60) { ++ new_lvl = CCK_PD_LV3; ++ } else if (dm_info->min_rssi > 35) { ++ new_lvl = CCK_PD_LV2; ++ } else if (dm_info->min_rssi > 20) { ++ if (dm_info->cck_fa_avg > 500) ++ new_lvl = CCK_PD_LV2; ++ else if (dm_info->cck_fa_avg < 250) ++ new_lvl = CCK_PD_LV1; ++ else ++ return; ++ } else { ++ new_lvl = CCK_PD_LV1; ++ } ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_PHY, "lv: (%d) -> (%d)\n", ++ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A], new_lvl); ++ ++ if (dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] == new_lvl) ++ return; ++ ++ dm_info->cck_fa_avg = CCK_FA_AVG_RESET; ++ dm_info->cck_pd_lv[RTW_CHANNEL_WIDTH_20][RF_PATH_A] = new_lvl; ++ ++ rtw_write8(rtwdev, REG_CCK_PD_TH, pd[new_lvl]); ++} ++EXPORT_SYMBOL(rtw88xxa_phy_cck_pd_set); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a/8812a common code"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw88xxa.h +@@ -0,0 +1,175 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW88XXA_H__ ++#define __RTW88XXA_H__ ++ ++#include ++#include "reg.h" ++ ++struct rtw8821au_efuse { ++ u8 res4[48]; /* 0xd0 */ ++ u8 vid[2]; /* 0x100 */ ++ u8 pid[2]; ++ u8 res8[3]; ++ u8 mac_addr[ETH_ALEN]; /* 0x107 */ ++ u8 res9[243]; ++} __packed; ++ ++struct rtw8812au_efuse { ++ u8 vid[2]; /* 0xd0 */ ++ u8 pid[2]; /* 0xd2 */ ++ u8 res0[3]; ++ u8 mac_addr[ETH_ALEN]; /* 0xd7 */ ++ u8 res1[291]; ++} __packed; ++ ++struct rtw88xxa_efuse { ++ __le16 rtl_id; ++ u8 res0[6]; /* 0x02 */ ++ u8 usb_mode; /* 0x08 */ ++ u8 res1[7]; /* 0x09 */ ++ ++ /* power index for four RF paths */ ++ struct rtw_txpwr_idx txpwr_idx_table[4]; ++ ++ u8 channel_plan; /* 0xb8 */ ++ u8 xtal_k; ++ u8 thermal_meter; ++ u8 iqk_lck; ++ u8 pa_type; /* 0xbc */ ++ u8 lna_type_2g; /* 0xbd */ ++ u8 res2; ++ u8 lna_type_5g; /* 0xbf */ ++ u8 res3; ++ u8 rf_board_option; /* 0xc1 */ ++ u8 rf_feature_option; ++ u8 rf_bt_setting; ++ u8 eeprom_version; ++ u8 eeprom_customer_id; /* 0xc5 */ ++ u8 tx_bb_swing_setting_2g; ++ u8 tx_bb_swing_setting_5g; ++ u8 tx_pwr_calibrate_rate; ++ u8 rf_antenna_option; /* 0xc9 */ ++ u8 rfe_option; ++ u8 country_code[2]; ++ u8 res4[3]; ++ union { ++ struct rtw8821au_efuse rtw8821au; ++ struct rtw8812au_efuse rtw8812au; ++ }; ++} __packed; ++ ++static_assert(sizeof(struct rtw88xxa_efuse) == 512); ++ ++#define WLAN_BCN_DMA_TIME 0x02 ++#define WLAN_TBTT_PROHIBIT 0x04 ++#define WLAN_TBTT_HOLD_TIME 0x064 ++#define WLAN_TBTT_TIME (WLAN_TBTT_PROHIBIT |\ ++ (WLAN_TBTT_HOLD_TIME << BIT_SHIFT_TBTT_HOLD_TIME_AP)) ++ ++struct rtw_jaguar_phy_status_rpt { ++ __le32 w0; ++ __le32 w1; ++ __le32 w2; ++ __le32 w3; ++ __le32 w4; ++ __le32 w5; ++ __le32 w6; ++} __packed; ++ ++#define RTW_JGRPHY_W0_GAIN_A GENMASK(6, 0) ++#define RTW_JGRPHY_W0_TRSW_A BIT(7) ++#define RTW_JGRPHY_W0_GAIN_B GENMASK(14, 8) ++#define RTW_JGRPHY_W0_TRSW_B BIT(15) ++#define RTW_JGRPHY_W0_CHL_NUM GENMASK(25, 16) ++#define RTW_JGRPHY_W0_SUB_CHNL GENMASK(29, 26) ++#define RTW_JGRPHY_W0_R_RFMOD GENMASK(31, 30) ++ ++/* CCK: */ ++#define RTW_JGRPHY_W1_SIG_QUAL GENMASK(7, 0) ++#define RTW_JGRPHY_W1_AGC_RPT_VGA_IDX GENMASK(12, 8) ++#define RTW_JGRPHY_W1_AGC_RPT_LNA_IDX GENMASK(15, 13) ++#define RTW_JGRPHY_W1_BB_POWER GENMASK(23, 16) ++/* OFDM: */ ++#define RTW_JGRPHY_W1_PWDB_ALL GENMASK(7, 0) ++#define RTW_JGRPHY_W1_CFO_SHORT_A GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W1_CFO_SHORT_B GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W1_BT_RF_CH_MSB GENMASK(31, 30) ++ ++#define RTW_JGRPHY_W2_ANT_DIV_SW_A BIT(0) ++#define RTW_JGRPHY_W2_ANT_DIV_SW_B BIT(1) ++#define RTW_JGRPHY_W2_BT_RF_CH_LSB GENMASK(7, 2) ++#define RTW_JGRPHY_W2_CFO_TAIL_A GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W2_CFO_TAIL_B GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W2_PCTS_MSK_RPT_0 GENMASK(31, 24) ++ ++#define RTW_JGRPHY_W3_PCTS_MSK_RPT_1 GENMASK(7, 0) ++/* Stream 1 and 2 RX EVM: */ ++#define RTW_JGRPHY_W3_RXEVM_1 GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W3_RXEVM_2 GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W3_RXSNR_A GENMASK(31, 24) /* s8 */ ++ ++#define RTW_JGRPHY_W4_RXSNR_B GENMASK(7, 0) /* s8 */ ++#define RTW_JGRPHY_W4_PCTS_MSK_RPT_2 GENMASK(21, 8) ++#define RTW_JGRPHY_W4_PCTS_RPT_VALID BIT(22) ++#define RTW_JGRPHY_W4_RXEVM_3 GENMASK(31, 24) /* s8 */ ++ ++#define RTW_JGRPHY_W5_RXEVM_4 GENMASK(7, 0) /* s8 */ ++/* 8812a, stream 1 and 2 CSI: */ ++#define RTW_JGRPHY_W5_CSI_CURRENT_1 GENMASK(15, 8) ++#define RTW_JGRPHY_W5_CSI_CURRENT_2 GENMASK(23, 16) ++/* 8814a: */ ++#define RTW_JGRPHY_W5_RXSNR_C GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W5_RXSNR_D GENMASK(23, 16) /* s8 */ ++#define RTW_JGRPHY_W5_GAIN_C GENMASK(30, 24) ++#define RTW_JGRPHY_W5_TRSW_C BIT(31) ++ ++#define RTW_JGRPHY_W6_GAIN_D GENMASK(6, 0) ++#define RTW_JGRPHY_W6_TRSW_D BIT(7) ++#define RTW_JGRPHY_W6_SIGEVM GENMASK(15, 8) /* s8 */ ++#define RTW_JGRPHY_W6_ANTIDX_ANTC GENMASK(18, 16) ++#define RTW_JGRPHY_W6_ANTIDX_ANTD GENMASK(21, 19) ++#define RTW_JGRPHY_W6_DPDT_CTRL_KEEP BIT(22) ++#define RTW_JGRPHY_W6_GNT_BT_KEEP BIT(23) ++#define RTW_JGRPHY_W6_ANTIDX_ANTA GENMASK(26, 24) ++#define RTW_JGRPHY_W6_ANTIDX_ANTB GENMASK(29, 27) ++#define RTW_JGRPHY_W6_HW_ANTSW_OCCUR GENMASK(31, 30) ++ ++#define RF18_BW_MASK (BIT(11) | BIT(10)) ++ ++void rtw88xxa_efuse_grant(struct rtw_dev *rtwdev, bool on); ++int rtw88xxa_read_efuse(struct rtw_dev *rtwdev, u8 *log_map); ++void rtw88xxa_power_off(struct rtw_dev *rtwdev, ++ const struct rtw_pwr_seq_cmd *const *enter_lps_flow); ++int rtw88xxa_power_on(struct rtw_dev *rtwdev); ++u32 rtw88xxa_phy_read_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path rf_path, u32 addr, u32 mask); ++void rtw88xxa_set_channel(struct rtw_dev *rtwdev, u8 channel, u8 bw, ++ u8 primary_chan_idx); ++void rtw88xxa_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat, ++ s8 (*cck_rx_pwr)(u8 lna_idx, u8 vga_idx)); ++void rtw88xxa_set_tx_power_index(struct rtw_dev *rtwdev); ++void rtw88xxa_false_alarm_statistics(struct rtw_dev *rtwdev); ++void rtw88xxa_iqk_backup_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num); ++void rtw88xxa_iqk_backup_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num); ++void rtw88xxa_iqk_restore_mac_bb(struct rtw_dev *rtwdev, ++ u32 *macbb_backup, ++ const u32 *backup_macbb_reg, ++ u32 macbb_num); ++void rtw88xxa_iqk_configure_mac(struct rtw_dev *rtwdev); ++bool rtw88xxa_iqk_finish(int average, int threshold, ++ int *x_temp, int *y_temp, int *x, int *y, ++ bool break_inner, bool break_outer); ++void rtw88xxa_phy_pwrtrack(struct rtw_dev *rtwdev, ++ void (*do_lck)(struct rtw_dev *rtwdev), ++ void (*do_iqk)(struct rtw_dev *rtwdev)); ++void rtw88xxa_phy_cck_pd_set(struct rtw_dev *rtwdev, u8 new_lvl); ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch b/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch new file mode 100644 index 00000000000000..dca3f7b275aab6 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/042-v6.13-wifi-rtw88-Add-rtw8821a.-c-h.patch @@ -0,0 +1,1230 @@ +From 32e284a238806d1984ea68cda25f6b09a4053b94 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:28:15 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821a.{c,h} + +These contain code specific to RTL8821AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/37218648-ada7-4fad-b7bd-d2aee28cefb9@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw8821a.c | 1197 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8821a.h | 10 + + 2 files changed, 1207 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821a.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.c +@@ -0,0 +1,1197 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw88xxa.h" ++#include "rtw8821a.h" ++#include "rtw8821a_table.h" ++#include "tx.h" ++ ++static void rtw8821a_power_off(struct rtw_dev *rtwdev) ++{ ++ rtw88xxa_power_off(rtwdev, enter_lps_flow_8821a); ++} ++ ++static s8 rtw8821a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) ++{ ++ static const s8 lna_gain_table[] = {15, -1, -17, 0, -30, -38}; ++ s8 rx_pwr_all = 0; ++ s8 lna_gain; ++ ++ switch (lna_idx) { ++ case 5: ++ case 4: ++ case 2: ++ case 1: ++ case 0: ++ lna_gain = lna_gain_table[lna_idx]; ++ rx_pwr_all = lna_gain - 2 * vga_idx; ++ break; ++ default: ++ break; ++ } ++ ++ return rx_pwr_all; ++} ++ ++static void rtw8821a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, ++ rtw8821a_cck_rx_pwr); ++} ++ ++static void rtw8821a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++} ++ ++#define CAL_NUM_8821A 3 ++#define MACBB_REG_NUM_8821A 8 ++#define AFE_REG_NUM_8821A 4 ++#define RF_REG_NUM_8821A 3 ++ ++static void rtw8821a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, ++ const u32 *backup_rf_reg, u32 rf_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save RF Parameters */ ++ for (i = 0; i < rf_num; i++) ++ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, ++ backup_rf_reg[i], MASKDWORD); ++} ++ ++static void rtw8821a_iqk_restore_rf(struct rtw_dev *rtwdev, ++ const u32 *backup_rf_reg, ++ u32 *RF_backup, u32 rf_reg_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ for (i = 0; i < rf_reg_num; i++) ++ rtw_write_rf(rtwdev, RF_PATH_A, backup_rf_reg[i], ++ RFREG_MASK, RF_backup[i]); ++} ++ ++static void rtw8821a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); ++ rtw_write32(rtwdev, REG_TXAGCIDX, 0x00000000); ++ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); ++ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x0); ++} ++ ++static void rtw8821a_iqk_rx_fill(struct rtw_dev *rtwdev, ++ unsigned int rx_x, unsigned int rx_y) ++{ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, (rx_y >> 1) & 0x3ff); ++} ++ ++static void rtw8821a_iqk_tx_fill(struct rtw_dev *rtwdev, ++ unsigned int tx_x, unsigned int tx_y) ++{ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_LSSI_WRITE_A, 0x00000080); ++ rtw_write32(rtwdev, REG_IQK_DPD_CFG, 0x20040000); ++ rtw_write32(rtwdev, REG_CFG_PMPD, 0x20000000); ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); ++} ++ ++static void rtw8821a_iqk_tx_vdf_true(struct rtw_dev *rtwdev, u32 cal, ++ bool *tx0iqkok, ++ int tx_x0[CAL_NUM_8821A], ++ int tx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, tx_fail; ++ int tx_dt[3], vdf_y[3], vdf_x[3]; ++ int k; ++ ++ for (k = 0; k < 3; k++) { ++ switch (k) { ++ case 0: ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ 0x18008c38); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c38); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); ++ break; ++ case 1: ++ rtw_write32_mask(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ BIT(28), 0x0); ++ rtw_write32_mask(rtwdev, REG_OFDM0_A_TX_AFE, ++ BIT(28), 0x0); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x0); ++ break; ++ case 2: ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "vdf_y[1] = %x vdf_y[0] = %x\n", ++ vdf_y[1] >> 21 & 0x00007ff, ++ vdf_y[0] >> 21 & 0x00007ff); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "vdf_x[1] = %x vdf_x[0] = %x\n", ++ vdf_x[1] >> 21 & 0x00007ff, ++ vdf_x[0] >> 21 & 0x00007ff); ++ ++ tx_dt[cal] = (vdf_y[1] >> 20) - (vdf_y[0] >> 20); ++ tx_dt[cal] = (16 * tx_dt[cal]) * 10000 / 15708; ++ tx_dt[cal] = (tx_dt[cal] >> 1) + (tx_dt[cal] & BIT(0)); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, ++ 0x18008c20); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c20); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_INTPO_SETA, 0x3fff0000, ++ tx_dt[cal] & 0x00003fff); ++ break; ++ } ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============TXIQK Check============== */ ++ tx_fail = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(12)); ++ ++ /* Originally: if (~tx_fail) { ++ * It looks like a typo, so make it more explicit. ++ */ ++ tx_fail = false; ++ ++ if (!tx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, ++ 0x02000000); ++ vdf_x[k] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ vdf_x[k] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, ++ 0x04000000); ++ vdf_y[k] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ vdf_y[k] <<= 21; ++ ++ *tx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQC_Y, ++ 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, ++ 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++ } ++ ++ if (k == 3) { ++ tx_x0[cal] = vdf_x[k - 1]; ++ tx_y0[cal] = vdf_y[k - 1]; ++ } ++} ++ ++static void rtw8821a_iqk_tx_vdf_false(struct rtw_dev *rtwdev, u32 cal, ++ bool *tx0iqkok, ++ int tx_x0[CAL_NUM_8821A], ++ int tx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, tx_fail; ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============TXIQK Check============== */ ++ tx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); ++ ++ /* Originally: if (~tx_fail) { ++ * It looks like a typo, so make it more explicit. ++ */ ++ tx_fail = false; ++ ++ if (!tx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); ++ tx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_x0[cal] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); ++ tx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ tx_y0[cal] <<= 21; ++ ++ *tx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, 0x0); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, 0x200); ++ } ++ ++ *tx0iqkok = false; ++ } ++} ++ ++static void rtw8821a_iqk_rx(struct rtw_dev *rtwdev, u32 cal, bool *rx0iqkok, ++ int rx_x0[CAL_NUM_8821A], ++ int rx_y0[CAL_NUM_8821A]) ++{ ++ u32 cal_retry, delay_count, iqk_ready, rx_fail; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ ++ for (cal_retry = 0; cal_retry < 10; cal_retry++) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ iqk_ready = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(10)); ++ ++ /* Originally: if (~iqk_ready || delay_count > 20) ++ * that looks like a typo so make it more explicit ++ */ ++ iqk_ready = true; ++ ++ if (iqk_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ if (delay_count < 20) { ++ /* ============RXIQK Check============== */ ++ rx_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); ++ if (!rx_fail) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); ++ rx_x0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ rx_x0[cal] <<= 21; ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); ++ rx_y0[cal] = rtw_read32_mask(rtwdev, REG_IQKA_END, ++ 0x07ff0000); ++ rx_y0[cal] <<= 21; ++ ++ *rx0iqkok = true; ++ break; ++ } ++ ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, 0x200 >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, 0x0 >> 1); ++ } ++ ++ *rx0iqkok = false; ++ } ++} ++ ++static void rtw8821a_iqk(struct rtw_dev *rtwdev) ++{ ++ int tx_average = 0, rx_average = 0, rx_iqk_loop = 0; ++ const struct rtw_efuse *efuse = &rtwdev->efuse; ++ int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0; ++ const struct rtw_hal *hal = &rtwdev->hal; ++ bool tx0iqkok = false, rx0iqkok = false; ++ int rx_x_temp = 0, rx_y_temp = 0; ++ int rx_x0[2][CAL_NUM_8821A]; ++ int rx_y0[2][CAL_NUM_8821A]; ++ int tx_x0[CAL_NUM_8821A]; ++ int tx_y0[CAL_NUM_8821A]; ++ bool rx_finish1 = false; ++ bool rx_finish2 = false; ++ bool vdf_enable; ++ u32 cal; ++ int i; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "band_width = %d, ext_pa = %d, ext_pa_5g = %d\n", ++ hal->current_band_width, efuse->ext_pa_2g, efuse->ext_pa_5g); ++ ++ vdf_enable = hal->current_band_width == RTW_CHANNEL_WIDTH_80; ++ ++ for (cal = 0; cal < CAL_NUM_8821A; cal++) { ++ /* path-A LOK */ ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* ========path-A AFE all on======== */ ++ /* Port 0 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); ++ ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); ++ ++ /* hardware 3-wire off */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); ++ ++ /* LOK setting */ ++ ++ /* 1. DAC/ADC sampling rate (160 MHz) */ ++ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); ++ ++ /* 2. LoK RF setting (at BW = 20M) */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x00c00, 0x3); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0003f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xf3fc3); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, ++ 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); ++ /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); ++ /* [0]:AGC_en, [15]:idac_K_Mask */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f4); ++ ++ if (hal->current_band_type == RTW_BAND_5G) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); ++ ++ if (hal->current_band_width == RTW_CHANNEL_WIDTH_40) ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, ++ RF18_BW_MASK, 0x1); ++ else if (hal->current_band_width == RTW_CHANNEL_WIDTH_80) ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, ++ RF18_BW_MASK, 0x0); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* 3. TX RF setting */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0003f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xf3fc3); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); ++ /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); ++ /* [0]:AGC_en, [15]:idac_K_Mask */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a910); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403e3); ++ ++ if (hal->current_band_type == RTW_BAND_5G) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x40163e96); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x00163e96); ++ ++ if (vdf_enable) ++ rtw8821a_iqk_tx_vdf_true(rtwdev, cal, &tx0iqkok, ++ tx_x0, tx_y0); ++ else ++ rtw8821a_iqk_tx_vdf_false(rtwdev, cal, &tx0iqkok, ++ tx_x0, tx_y0); ++ ++ if (!tx0iqkok) ++ break; /* TXK fail, Don't do RXK */ ++ ++ /* ====== RX IQK ====== */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* 1. RX RF setting */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x0002f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfffbb); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d8); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ (tx_x0[cal] >> 21) & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ (tx_y0[cal] >> 21) & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x02140119); ++ ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) ++ rx_iqk_loop = 2; /* for 2% fail; */ ++ else ++ rx_iqk_loop = 1; ++ ++ for (i = 0; i < rx_iqk_loop; i++) { ++ if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE && i == 0) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161100); /* Good */ ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160d00); ++ ++ rtw8821a_iqk_rx(rtwdev, cal, &rx0iqkok, ++ rx_x0[i], rx_y0[i]); ++ } ++ ++ if (tx0iqkok) ++ tx_average++; ++ if (rx0iqkok) ++ rx_average++; ++ } ++ ++ /* FillIQK Result */ ++ ++ if (tx_average == 0) ++ return; ++ ++ for (i = 0; i < tx_average; i++) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", ++ i, (tx_x0[i] >> 21) & 0x000007ff, ++ i, (tx_y0[i] >> 21) & 0x000007ff); ++ ++ if (rtw88xxa_iqk_finish(tx_average, 3, tx_x0, tx_y0, ++ &tx_x, &tx_y, true, true)) ++ rtw8821a_iqk_tx_fill(rtwdev, tx_x, tx_y); ++ else ++ rtw8821a_iqk_tx_fill(rtwdev, 0x200, 0x0); ++ ++ if (rx_average == 0) ++ return; ++ ++ for (i = 0; i < rx_average; i++) { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[0][%d] = %x ;; rx_y0[0][%d] = %x\n", ++ i, (rx_x0[0][i] >> 21) & 0x000007ff, ++ i, (rx_y0[0][i] >> 21) & 0x000007ff); ++ ++ if (rx_iqk_loop == 2) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[1][%d] = %x ;; rx_y0[1][%d] = %x\n", ++ i, (rx_x0[1][i] >> 21) & 0x000007ff, ++ i, (rx_y0[1][i] >> 21) & 0x000007ff); ++ } ++ ++ rx_finish1 = rtw88xxa_iqk_finish(rx_average, 4, rx_x0[0], rx_y0[0], ++ &rx_x_temp, &rx_y_temp, true, true); ++ ++ if (rx_finish1) { ++ rx_x = rx_x_temp; ++ rx_y = rx_y_temp; ++ } ++ ++ if (rx_iqk_loop == 2) { ++ rx_finish2 = rtw88xxa_iqk_finish(rx_average, 4, ++ rx_x0[1], rx_y0[1], ++ &rx_x, &rx_y, true, true); ++ ++ if (rx_finish1 && rx_finish2) { ++ rx_x = (rx_x + rx_x_temp) / 2; ++ rx_y = (rx_y + rx_y_temp) / 2; ++ } ++ } ++ ++ if (rx_finish1 || rx_finish2) ++ rtw8821a_iqk_rx_fill(rtwdev, rx_x, rx_y); ++ else ++ rtw8821a_iqk_rx_fill(rtwdev, 0x200, 0x0); ++} ++ ++static void rtw8821a_do_iqk(struct rtw_dev *rtwdev) ++{ ++ static const u32 backup_macbb_reg[MACBB_REG_NUM_8821A] = { ++ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0x838, 0x82c ++ }; ++ static const u32 backup_afe_reg[AFE_REG_NUM_8821A] = { ++ 0xc5c, 0xc60, 0xc64, 0xc68 ++ }; ++ static const u32 backup_rf_reg[RF_REG_NUM_8821A] = { ++ 0x65, 0x8f, 0x0 ++ }; ++ u32 macbb_backup[MACBB_REG_NUM_8821A]; ++ u32 afe_backup[AFE_REG_NUM_8821A]; ++ u32 rfa_backup[RF_REG_NUM_8821A]; ++ ++ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8821A); ++ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8821A); ++ rtw8821a_iqk_backup_rf(rtwdev, rfa_backup, ++ backup_rf_reg, RF_REG_NUM_8821A); ++ ++ rtw88xxa_iqk_configure_mac(rtwdev); ++ ++ rtw8821a_iqk(rtwdev); ++ ++ rtw8821a_iqk_restore_rf(rtwdev, backup_rf_reg, ++ rfa_backup, RF_REG_NUM_8821A); ++ rtw8821a_iqk_restore_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8821A); ++ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8821A); ++} ++ ++static void rtw8821a_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ rtw8821a_do_iqk(rtwdev); ++} ++ ++static void rtw8821a_pwr_track(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ if (!dm_info->pwr_trk_triggered) { ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, ++ GENMASK(17, 16), 0x03); ++ dm_info->pwr_trk_triggered = true; ++ return; ++ } ++ ++ rtw88xxa_phy_pwrtrack(rtwdev, NULL, rtw8821a_do_iqk); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++static void rtw8821a_fill_txdesc_checksum(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc) ++{ ++ fill_txdesc_checksum_common(txdesc, 16); ++} ++ ++static void rtw8821a_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++ u8 val8; ++ ++ /* BT report packet sample rate */ ++ rtw_write8_mask(rtwdev, REG_BT_TDMA_TIME, BIT_MASK_SAMPLE_RATE, 0x5); ++ ++ val8 = BIT_STATIS_BT_EN; ++ if (rtwdev->efuse.share_ant) ++ val8 |= BIT_R_GRANTALL_WLMASK; ++ rtw_write8(rtwdev, REG_BT_COEX_ENH_INTR_CTRL, val8); ++ ++ /* enable BT counter statistics */ ++ rtw_write8(rtwdev, REG_BT_STAT_CTRL, 0x3); ++ ++ /* enable PTA */ ++ rtw_write32_set(rtwdev, REG_GPIO_MUXCFG, BIT_BT_PTA_EN); ++} ++ ++static void rtw8821a_coex_cfg_ant_switch(struct rtw_dev *rtwdev, u8 ctrl_type, ++ u8 pos_type) ++{ ++ bool share_ant = rtwdev->efuse.share_ant; ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ u32 phase = coex_dm->cur_ant_pos_type; ++ ++ if (!rtwdev->efuse.btcoex) ++ return; ++ ++ switch (phase) { ++ case COEX_SET_ANT_POWERON: ++ case COEX_SET_ANT_INIT: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, ++ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_WONLY: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_2G: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_clr(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, ++ share_ant ? PTA_CTRL_PIN : DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, 0x1); ++ break; ++ case COEX_SET_ANT_5G: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_set(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, ++ share_ant ? 0x2 : 0x1); ++ break; ++ case COEX_SET_ANT_WOFF: ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_SEL_EN); ++ rtw_write32_clr(rtwdev, REG_LED_CFG, BIT_DPDT_WL_SEL); ++ rtw_write8_set(rtwdev, REG_GNT_BT, BIT_PTA_SW_CTL); ++ ++ rtw_write8(rtwdev, REG_RFE_CTRL8, DPDT_CTRL_PIN); ++ rtw_write32_mask(rtwdev, REG_RFE_CTRL8, 0x30000000, ++ share_ant ? 0x2 : 0x1); ++ break; ++ default: ++ rtw_warn(rtwdev, "%s: not handling phase %d\n", ++ __func__, phase); ++ break; ++ } ++} ++ ++static void rtw8821a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_gnt_debug(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_rfe *coex_rfe = &coex->rfe; ++ ++ coex_rfe->ant_switch_exist = true; ++} ++ ++static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++ struct rtw_coex *coex = &rtwdev->coex; ++ struct rtw_coex_dm *coex_dm = &coex->dm; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ bool share_ant = efuse->share_ant; ++ ++ if (share_ant) ++ return; ++ ++ if (wl_pwr == coex_dm->cur_wl_pwr_lvl) ++ return; ++ ++ coex_dm->cur_wl_pwr_lvl = wl_pwr; ++} ++ ++static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++static const struct rtw_chip_ops rtw8821a_ops = { ++ .power_on = rtw88xxa_power_on, ++ .power_off = rtw8821a_power_off, ++ .phy_set_param = NULL, ++ .read_efuse = rtw88xxa_read_efuse, ++ .query_phy_status = rtw8821a_query_phy_status, ++ .set_channel = rtw88xxa_set_channel, ++ .mac_init = NULL, ++ .read_rf = rtw88xxa_phy_read_rf, ++ .write_rf = rtw_phy_write_rf_reg_sipi, ++ .set_antenna = NULL, ++ .set_tx_power_index = rtw88xxa_set_tx_power_index, ++ .cfg_ldo25 = rtw8821a_cfg_ldo25, ++ .efuse_grant = rtw88xxa_efuse_grant, ++ .false_alarm_statistics = rtw88xxa_false_alarm_statistics, ++ .phy_calibration = rtw8821a_phy_calibration, ++ .cck_pd_set = rtw88xxa_phy_cck_pd_set, ++ .pwr_track = rtw8821a_pwr_track, ++ .config_bfee = NULL, ++ .set_gid_table = NULL, ++ .cfg_csi_rate = NULL, ++ .fill_txdesc_checksum = rtw8821a_fill_txdesc_checksum, ++ .coex_set_init = rtw8821a_coex_cfg_init, ++ .coex_set_ant_switch = rtw8821a_coex_cfg_ant_switch, ++ .coex_set_gnt_fix = rtw8821a_coex_cfg_gnt_fix, ++ .coex_set_gnt_debug = rtw8821a_coex_cfg_gnt_debug, ++ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, ++ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, ++ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, ++}; ++ ++static const struct rtw_page_table page_table_8821a[] = { ++ /* hq_num, nq_num, lq_num, exq_num, gapq_num */ ++ {0, 0, 0, 0, 0}, /* SDIO */ ++ {0, 0, 0, 0, 0}, /* PCI */ ++ {8, 0, 0, 0, 1}, /* 2 bulk out endpoints */ ++ {8, 0, 8, 0, 1}, /* 3 bulk out endpoints */ ++ {8, 0, 8, 4, 1}, /* 4 bulk out endpoints */ ++}; ++ ++static const struct rtw_rqpn rqpn_table_8821a[] = { ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, ++ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++}; ++ ++static const struct rtw_prioq_addrs prioq_addrs_8821a = { ++ .prio[RTW_DMA_MAPPING_EXTRA] = { ++ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, ++ }, ++ .prio[RTW_DMA_MAPPING_LOW] = { ++ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_NORMAL] = { ++ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_HIGH] = { ++ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, ++ }, ++ .wsize = false, ++}; ++ ++static const struct rtw_hw_reg rtw8821a_dig[] = { ++ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, ++}; ++ ++static const struct rtw_rfe_def rtw8821a_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8821a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8821a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8821a_rtw_pwr_track_tbl, }, ++}; ++ ++/* TODO */ ++/* rssi in percentage % (dbm = % - 100) */ ++static const u8 wl_rssi_step_8821a[] = {101, 45, 101, 40}; ++static const u8 bt_rssi_step_8821a[] = {101, 101, 101, 101}; ++ ++/* table_sant_8821a, table_nsant_8821a, tdma_sant_8821a, and tdma_nsant_8821a ++ * are copied from rtw8821c.c because the 8821au driver's tables are not ++ * compatible with the coex code in rtw88. ++ * ++ * tdma case 112 (A2DP) byte 0 had to be modified from 0x61 to 0x51, ++ * otherwise the firmware gets confused after pausing the music: ++ * rtw_8821au 1-2:1.2: [BTCoex], Bt_info[1], len=7, data=[81 00 0a 01 00 00] ++ * - 81 means PAN (personal area network) when it should be 4x (A2DP) ++ * The music is not smooth with the PAN algorithm. ++ */ ++ ++/* Shared-Antenna Coex Table */ ++static const struct coex_table_para table_sant_8821a[] = { ++ {0x55555555, 0x55555555}, /* case-0 */ ++ {0x55555555, 0x55555555}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xfafafafa, 0xfafafafa}, /* case-5 */ ++ {0x6a5a5555, 0xaaaaaaaa}, ++ {0x6a5a56aa, 0x6a5a56aa}, ++ {0x6a5a5a5a, 0x6a5a5a5a}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-10 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0x6aaa6aaa}, ++ {0x66555555, 0x6a5a5aaa}, ++ {0x66555555, 0xaaaaaaaa}, /* case-15 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x6afa5afa}, ++ {0xaaffffaa, 0xfafafafa}, ++ {0xaa5555aa, 0x5a5a5a5a}, ++ {0xaa5555aa, 0x6a5a5a5a}, /* case-20 */ ++ {0xaa5555aa, 0xaaaaaaaa}, ++ {0xffffffff, 0x55555555}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5a5a}, ++ {0xffffffff, 0x5a5a5aaa}, /* case-25 */ ++ {0x55555555, 0x5a5a5a5a}, ++ {0x55555555, 0xaaaaaaaa}, ++ {0x66555555, 0x6a5a6a5a}, ++ {0x66556655, 0x66556655}, ++ {0x66556aaa, 0x6a5a6aaa}, /* case-30 */ ++ {0xffffffff, 0x5aaa5aaa}, ++ {0x56555555, 0x5a5a5aaa} ++}; ++ ++/* Non-Shared-Antenna Coex Table */ ++static const struct coex_table_para table_nsant_8821a[] = { ++ {0xffffffff, 0xffffffff}, /* case-100 */ ++ {0xffff55ff, 0xfafafafa}, ++ {0x66555555, 0x66555555}, ++ {0xaaaaaaaa, 0xaaaaaaaa}, ++ {0x5a5a5a5a, 0x5a5a5a5a}, ++ {0xffffffff, 0xffffffff}, /* case-105 */ ++ {0x5afa5afa, 0x5afa5afa}, ++ {0x55555555, 0xfafafafa}, ++ {0x66555555, 0xfafafafa}, ++ {0x66555555, 0x5a5a5a5a}, ++ {0x66555555, 0x6a5a5a5a}, /* case-110 */ ++ {0x66555555, 0xaaaaaaaa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0xaaaaaaaa}, ++ {0xffff55ff, 0xffff55ff}, /* case-115 */ ++ {0xaaffffaa, 0x5afa5afa}, ++ {0xaaffffaa, 0xaaaaaaaa}, ++ {0xffffffff, 0xfafafafa}, ++ {0xffff55ff, 0xfafafafa}, ++ {0xffffffff, 0xaaaaaaaa}, /* case-120 */ ++ {0xffff55ff, 0x5afa5afa}, ++ {0xffff55ff, 0x5afa5afa}, ++ {0x55ff55ff, 0x55ff55ff} ++}; ++ ++/* Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_sant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x00, 0x00} }, /* case-0 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, /* case-1 */ ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x3a, 0x03, 0x11, 0x11} }, /* case-5 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-10 */ ++ { {0x61, 0x08, 0x03, 0x11, 0x15} }, ++ { {0x61, 0x08, 0x03, 0x10, 0x14} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-15 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x11, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x50} }, /* case-20 */ ++ { {0x51, 0x4a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x08, 0x03, 0x30, 0x54} }, ++ { {0x55, 0x08, 0x03, 0x10, 0x54} }, ++ { {0x65, 0x10, 0x03, 0x11, 0x10} }, ++ { {0x51, 0x10, 0x03, 0x10, 0x51} }, /* case-25 */ ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x61, 0x08, 0x03, 0x11, 0x11} } ++}; ++ ++/* Non-Shared-Antenna TDMA */ ++static const struct coex_tdma_para tdma_nsant_8821a[] = { ++ { {0x00, 0x00, 0x00, 0x40, 0x00} }, /* case-100 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x25, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x35, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x11} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, /* case-105 */ ++ { {0x61, 0x45, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x30, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x20, 0x03, 0x11, 0x10} }, ++ { {0x61, 0x10, 0x03, 0x11, 0x10} }, /* case-110 */ ++ { {0x61, 0x10, 0x03, 0x11, 0x11} }, ++ { {0x51, 0x08, 0x03, 0x10, 0x14} }, /* a2dp high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x54} }, /* a2dp not high rssi */ ++ { {0x51, 0x08, 0x03, 0x10, 0x55} }, ++ { {0x51, 0x08, 0x07, 0x10, 0x54} }, /* case-115 */ ++ { {0x51, 0x45, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x3a, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x30, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, ++ { {0x51, 0x21, 0x03, 0x10, 0x50} }, /* case-120 */ ++ { {0x51, 0x10, 0x03, 0x10, 0x50} } ++}; ++ ++/* TODO */ ++static const struct coex_rf_para rf_para_tx_8821a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {8, 17, true, 4}, ++ {7, 18, true, 4}, ++ {6, 19, true, 4}, ++ {5, 20, true, 4} ++}; ++ ++static const struct coex_rf_para rf_para_rx_8821a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {3, 24, true, 5}, ++ {2, 26, true, 5}, ++ {1, 27, true, 5}, ++ {0, 28, true, 5} ++}; ++ ++static_assert(ARRAY_SIZE(rf_para_tx_8821a) == ARRAY_SIZE(rf_para_rx_8821a)); ++ ++static const struct coex_5g_afh_map afh_5g_8821a[] = { {0, 0, 0} }; ++ ++static const struct rtw_reg_domain coex_info_hw_regs_8821a[] = { ++ {0xCB0, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0xCB4, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0xCBA, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x430, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x434, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x42a, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0x426, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x45e, BIT(3), RTW_REG_DOMAIN_MAC8}, ++ {0x454, MASKLWORD, RTW_REG_DOMAIN_MAC16}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x4c, BIT(24) | BIT(23), RTW_REG_DOMAIN_MAC32}, ++ {0x64, BIT(0), RTW_REG_DOMAIN_MAC8}, ++ {0x4c6, BIT(4), RTW_REG_DOMAIN_MAC8}, ++ {0x40, BIT(5), RTW_REG_DOMAIN_MAC8}, ++ {0x1, RFREG_MASK, RTW_REG_DOMAIN_RF_A}, ++ {0, 0, RTW_REG_DOMAIN_NL}, ++ {0x550, MASKDWORD, RTW_REG_DOMAIN_MAC32}, ++ {0x522, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x953, BIT(1), RTW_REG_DOMAIN_MAC8}, ++ {0xc50, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++ {0x60A, MASKBYTE0, RTW_REG_DOMAIN_MAC8}, ++}; ++ ++const struct rtw_chip_info rtw8821a_hw_spec = { ++ .ops = &rtw8821a_ops, ++ .id = RTW_CHIP_TYPE_8821A, ++ .fw_name = "rtw88/rtw8821a_fw.bin", ++ .wlan_cpu = RTW_WCPU_11N, ++ .tx_pkt_desc_sz = 40, ++ .tx_buf_desc_sz = 16, ++ .rx_pkt_desc_sz = 24, ++ .rx_buf_desc_sz = 8, ++ .phy_efuse_size = 512, ++ .log_efuse_size = 512, ++ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ ++ .txff_size = 65536, ++ .rxff_size = 16128, ++ .rsvd_drv_pg_num = 8, ++ .txgi_factor = 1, ++ .is_pwr_by_rate_dec = true, ++ .max_power_index = 0x3f, ++ .csi_buf_pg_num = 0, ++ .band = RTW_BAND_2G | RTW_BAND_5G, ++ .page_size = 256, ++ .dig_min = 0x20, ++ .ht_supported = true, ++ .vht_supported = true, ++ .lps_deep_mode_supported = 0, ++ .sys_func_en = 0xFD, ++ .pwr_on_seq = card_enable_flow_8821a, ++ .pwr_off_seq = card_disable_flow_8821a, ++ .page_table = page_table_8821a, ++ .rqpn_table = rqpn_table_8821a, ++ .prioq_addrs = &prioq_addrs_8821a, ++ .intf_table = NULL, ++ .dig = rtw8821a_dig, ++ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, ++ .ltecoex_addr = NULL, ++ .mac_tbl = &rtw8821a_mac_tbl, ++ .agc_tbl = &rtw8821a_agc_tbl, ++ .bb_tbl = &rtw8821a_bb_tbl, ++ .rf_tbl = {&rtw8821a_rf_a_tbl}, ++ .rfe_defs = rtw8821a_rfe_defs, ++ .rfe_defs_size = ARRAY_SIZE(rtw8821a_rfe_defs), ++ .rx_ldpc = false, ++ .hw_feature_report = false, ++ .c2h_ra_report_size = 4, ++ .old_datarate_fb_limit = true, ++ .usb_tx_agg_desc_num = 6, ++ .iqk_threshold = 8, ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, ++ ++ .coex_para_ver = 20190509, /* glcoex_ver_date_8821a_1ant */ ++ .bt_desired_ver = 0x62, /* But for 2 ant it's 0x5c */ ++ .scbd_support = false, ++ .new_scbd10_def = false, ++ .ble_hid_profile_support = false, ++ .wl_mimo_ps_support = false, ++ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, ++ .bt_rssi_type = COEX_BTRSSI_RATIO, ++ .ant_isolation = 10, ++ .rssi_tolerance = 2, ++ .wl_rssi_step = wl_rssi_step_8821a, ++ .bt_rssi_step = bt_rssi_step_8821a, ++ .table_sant_num = ARRAY_SIZE(table_sant_8821a), ++ .table_sant = table_sant_8821a, ++ .table_nsant_num = ARRAY_SIZE(table_nsant_8821a), ++ .table_nsant = table_nsant_8821a, ++ .tdma_sant_num = ARRAY_SIZE(tdma_sant_8821a), ++ .tdma_sant = tdma_sant_8821a, ++ .tdma_nsant_num = ARRAY_SIZE(tdma_nsant_8821a), ++ .tdma_nsant = tdma_nsant_8821a, ++ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8821a), ++ .wl_rf_para_tx = rf_para_tx_8821a, ++ .wl_rf_para_rx = rf_para_rx_8821a, ++ .bt_afh_span_bw20 = 0x20, ++ .bt_afh_span_bw40 = 0x30, ++ .afh_5g_num = ARRAY_SIZE(afh_5g_8821a), ++ .afh_5g = afh_5g_8821a, ++ ++ .coex_info_hw_regs_num = ARRAY_SIZE(coex_info_hw_regs_8821a), ++ .coex_info_hw_regs = coex_info_hw_regs_8821a, ++}; ++EXPORT_SYMBOL(rtw8821a_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8821a_fw.bin"); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821a/8811a driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821a.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8821A_H__ ++#define __RTW8821A_H__ ++ ++extern const struct rtw_chip_info rtw8821a_hw_spec; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch b/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch new file mode 100644 index 00000000000000..610dca037a2367 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/043-v6.13-wifi-rtw88-Add-rtw8812a.-c-h.patch @@ -0,0 +1,1135 @@ +From 4f8ec8927bc292b2a71cd5a253c96ce3c6b2927f Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:28:49 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8812a.{c,h} + +These contain code specific to RTL8812AU. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/a0057683-79eb-4ab2-8f74-11a3bc58adfb@gmail.com +--- + drivers/net/wireless/realtek/rtw88/rtw8812a.c | 1102 +++++++++++++++++ + drivers/net/wireless/realtek/rtw88/rtw8812a.h | 10 + + 2 files changed, 1112 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812a.h + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.c +@@ -0,0 +1,1102 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include "main.h" ++#include "coex.h" ++#include "phy.h" ++#include "reg.h" ++#include "rtw88xxa.h" ++#include "rtw8812a.h" ++#include "rtw8812a_table.h" ++#include "tx.h" ++ ++static void rtw8812a_power_off(struct rtw_dev *rtwdev) ++{ ++ rtw88xxa_power_off(rtwdev, enter_lps_flow_8812a); ++} ++ ++static s8 rtw8812a_cck_rx_pwr(u8 lna_idx, u8 vga_idx) ++{ ++ s8 rx_pwr_all = 0; ++ ++ switch (lna_idx) { ++ case 7: ++ if (vga_idx <= 27) ++ rx_pwr_all = -94 + 2 * (27 - vga_idx); ++ else ++ rx_pwr_all = -94; ++ break; ++ case 6: ++ rx_pwr_all = -42 + 2 * (2 - vga_idx); ++ break; ++ case 5: ++ rx_pwr_all = -36 + 2 * (7 - vga_idx); ++ break; ++ case 4: ++ rx_pwr_all = -30 + 2 * (7 - vga_idx); ++ break; ++ case 3: ++ rx_pwr_all = -18 + 2 * (7 - vga_idx); ++ break; ++ case 2: ++ rx_pwr_all = 2 * (5 - vga_idx); ++ break; ++ case 1: ++ rx_pwr_all = 14 - 2 * vga_idx; ++ break; ++ case 0: ++ rx_pwr_all = 20 - 2 * vga_idx; ++ break; ++ default: ++ break; ++ } ++ ++ return rx_pwr_all; ++} ++ ++static void rtw8812a_query_phy_status(struct rtw_dev *rtwdev, u8 *phy_status, ++ struct rtw_rx_pkt_stat *pkt_stat) ++{ ++ rtw88xxa_query_phy_status(rtwdev, phy_status, pkt_stat, ++ rtw8812a_cck_rx_pwr); ++ ++ if (pkt_stat->rate >= DESC_RATE6M) ++ return; ++ ++ if (rtwdev->hal.cck_high_power) ++ return; ++ ++ if (pkt_stat->rssi >= 80) ++ pkt_stat->rssi = ((pkt_stat->rssi - 80) << 1) + ++ ((pkt_stat->rssi - 80) >> 1) + 80; ++ else if (pkt_stat->rssi <= 78 && pkt_stat->rssi >= 20) ++ pkt_stat->rssi += 3; ++} ++ ++static void rtw8812a_cfg_ldo25(struct rtw_dev *rtwdev, bool enable) ++{ ++} ++ ++static void rtw8812a_do_lck(struct rtw_dev *rtwdev) ++{ ++ u32 cont_tx, lc_cal, i; ++ ++ cont_tx = rtw_read32_mask(rtwdev, REG_SINGLE_TONE_CONT_TX, 0x70000); ++ ++ lc_cal = rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK); ++ ++ if (!cont_tx) ++ rtw_write8(rtwdev, REG_TXPAUSE, 0xff); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 1); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000, 1); ++ ++ mdelay(150); ++ ++ for (i = 0; i < 5; i++) { ++ if (rtw_read_rf(rtwdev, RF_PATH_A, RF_CFGCH, 0x08000) != 1) ++ break; ++ ++ mdelay(10); ++ } ++ ++ if (i == 5) ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "LCK timed out\n"); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LCK, BIT(14), 0); ++ ++ if (!cont_tx) ++ rtw_write8(rtwdev, REG_TXPAUSE, 0); ++ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_CFGCH, RFREG_MASK, lc_cal); ++} ++ ++static void rtw8812a_iqk_backup_rf(struct rtw_dev *rtwdev, u32 *rfa_backup, ++ u32 *rfb_backup, const u32 *backup_rf_reg, ++ u32 rf_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Save RF Parameters */ ++ for (i = 0; i < rf_num; i++) { ++ rfa_backup[i] = rtw_read_rf(rtwdev, RF_PATH_A, ++ backup_rf_reg[i], MASKDWORD); ++ rfb_backup[i] = rtw_read_rf(rtwdev, RF_PATH_B, ++ backup_rf_reg[i], MASKDWORD); ++ } ++} ++ ++static void rtw8812a_iqk_restore_rf(struct rtw_dev *rtwdev, ++ enum rtw_rf_path path, ++ const u32 *backup_rf_reg, ++ u32 *RF_backup, u32 rf_reg_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ for (i = 0; i < rf_reg_num; i++) ++ rtw_write_rf(rtwdev, path, backup_rf_reg[i], ++ RFREG_MASK, RF_backup[i]); ++ ++ rtw_write_rf(rtwdev, path, RF_LUTWE, RFREG_MASK, 0); ++} ++ ++static void rtw8812a_iqk_restore_afe(struct rtw_dev *rtwdev, u32 *afe_backup, ++ const u32 *backup_afe_reg, u32 afe_num) ++{ ++ u32 i; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* Reload AFE Parameters */ ++ for (i = 0; i < afe_num; i++) ++ rtw_write32(rtwdev, backup_afe_reg[i], afe_backup[i]); ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x0); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x0); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_A, BIT(7), 1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 1); ++ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 1); ++ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x0); ++ rtw_write32(rtwdev, REG_RXTONEB, 0x0); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x0); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); ++ rtw_write32_mask(rtwdev, REG_LSSI_WRITE_B, BIT(7), 1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 1); ++ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 1); ++} ++ ++static void rtw8812a_iqk_rx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, ++ unsigned int rx_x, unsigned int rx_y) ++{ ++ switch (path) { ++ case RF_PATH_A: ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (rx_x >> 1 >= 0x112 || ++ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, 0x100); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_A, ++ 0x03ff0000, rx_y >> 1); ++ } ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x = %x;;rx_y = %x ====>fill to IQC\n", ++ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xc10 = %x ====>fill to IQC\n", ++ rtw_read32(rtwdev, REG_RX_IQC_AB_A)); ++ break; ++ case RF_PATH_B: ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (rx_x >> 1 >= 0x112 || ++ (rx_y >> 1 >= 0x12 && rx_y >> 1 <= 0x3ee)) { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x000003ff, 0x100); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x03ff0000, 0); ++ } else { ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x000003ff, rx_x >> 1); ++ rtw_write32_mask(rtwdev, REG_RX_IQC_AB_B, ++ 0x03ff0000, rx_y >> 1); ++ } ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x = %x;;rx_y = %x ====>fill to IQC\n", ++ rx_x >> 1 & 0x000003ff, rx_y >> 1 & 0x000003ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "0xe10 = %x====>fill to IQC\n", ++ rtw_read32(rtwdev, REG_RX_IQC_AB_B)); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_iqk_tx_fill(struct rtw_dev *rtwdev, enum rtw_rf_path path, ++ unsigned int tx_x, unsigned int tx_y) ++{ ++ switch (path) { ++ case RF_PATH_A: ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_PREDISTA, BIT(7), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(18), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_DPD_CFG, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_CFG_PMPD, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQC_Y, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQC_X, 0x000007ff, tx_x); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x = %x;;tx_y = %x =====> fill to IQC\n", ++ tx_x & 0x000007ff, tx_y & 0x000007ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", ++ rtw_read32_mask(rtwdev, REG_IQC_X, 0x000007ff), ++ rtw_read32_mask(rtwdev, REG_IQC_Y, 0x000007ff)); ++ break; ++ case RF_PATH_B: ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_PREDISTB, BIT(7), 0x1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(18), 0x1); ++ rtw_write32_mask(rtwdev, REG_BPBDB, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_PHYTXONB, BIT(29), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQKYB, 0x000007ff, tx_y); ++ rtw_write32_mask(rtwdev, REG_IQKXB, 0x000007ff, tx_x); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x = %x;;tx_y = %x =====> fill to IQC\n", ++ tx_x & 0x000007ff, tx_y & 0x000007ff); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "0xed4 = %x;;0xecc = %x ====>fill to IQC\n", ++ rtw_read32_mask(rtwdev, REG_IQKXB, 0x000007ff), ++ rtw_read32_mask(rtwdev, REG_IQKYB, 0x000007ff)); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void rtw8812a_iqk(struct rtw_dev *rtwdev) ++{ ++ int tx_x0_temp[10], tx_y0_temp[10], tx_x1_temp[10], tx_y1_temp[10]; ++ int rx_x0_temp[10], rx_y0_temp[10], rx_x1_temp[10], rx_y1_temp[10]; ++ bool iqk0_ready = false, tx0_finish = false, rx0_finish = false; ++ bool iqk1_ready = false, tx1_finish = false, rx1_finish = false; ++ u8 tx0_avg = 0, tx1_avg = 0, rx0_avg = 0, rx1_avg = 0; ++ int tx_x0 = 0, tx_y0 = 0, tx_x1 = 0, tx_y1 = 0; ++ int rx_x0 = 0, rx_y0 = 0, rx_x1 = 0, rx_y1 = 0; ++ struct rtw_efuse *efuse = &rtwdev->efuse; ++ bool tx0_fail = true, rx0_fail = true; ++ bool tx1_fail = true, rx1_fail = true; ++ u8 cal0_retry, cal1_retry; ++ u8 delay_count; ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ /* ========path-A AFE all on======== */ ++ /* Port 0 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_A, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_A, 0x77777777); ++ ++ /* Port 1 DAC/ADC on */ ++ rtw_write32(rtwdev, REG_AFE_PWR1_B, 0x77777777); ++ rtw_write32(rtwdev, REG_AFE_PWR2_B, 0x77777777); ++ ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_A, 0x19791979); ++ rtw_write32(rtwdev, REG_RX_WAIT_CCA_TX_CCK_RFON_B, 0x19791979); ++ ++ /* hardware 3-wire off */ ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWA, 0xf, 0x4); ++ rtw_write32_mask(rtwdev, REG_3WIRE_SWB, 0xf, 0x4); ++ ++ /* DAC/ADC sampling rate (160 MHz) */ ++ rtw_write32_mask(rtwdev, REG_CK_MONHA, GENMASK(26, 24), 0x7); ++ rtw_write32_mask(rtwdev, REG_CK_MONHB, GENMASK(26, 24), 0x7); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* ====== path A TX IQK RF setting ====== */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x8a001); ++ ++ /* ====== path B TX IQK RF setting ====== */ ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80002); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, 0x20000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, 0x3fffd); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, 0xfe83f); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d5); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x8a001); ++ ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ rtw_write32_mask(rtwdev, REG_TXAGCIDX, BIT(0), 0x1); ++ rtw_write32_mask(rtwdev, REG_INIDLYB, BIT(0), 0x1); ++ rtw_write32(rtwdev, REG_IQK_COM00, 0x29002000); /* TX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM32, 0xa9002000); /* RX (X,Y) */ ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x00462910); /* [0]:AGC_en, [15]:idac_K_Mask */ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (efuse->ext_pa_5g) { ++ if (efuse->rfe_option == 1) { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403e3); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403e3); ++ } else { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f7); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f7); ++ } ++ } else { ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x821403f1); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x821403f1); ++ } ++ ++ if (rtwdev->hal.current_band_type == RTW_BAND_5G) { ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x68163e96); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x68163e96); ++ } else { ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28163e96); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28163e96); ++ ++ if (efuse->rfe_option == 3) { ++ if (efuse->ext_pa_2g) ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403e3); ++ else ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, ++ 0x821403f7); ++ } ++ } ++ ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x38008c10); ++ rtw_write32(rtwdev, REG_INTPO_SETA, 0x00000000); ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x18008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_RXTONEB, 0x38008c10); ++ rtw_write32(rtwdev, REG_INTPO_SETB, 0x00000000); ++ ++ cal0_retry = 0; ++ cal1_retry = 0; ++ while (1) { ++ /* one shot */ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xfa000000); ++ rtw_write32(rtwdev, REG_IQK_COM64, 0xf8000000); ++ ++ mdelay(10); ++ ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ if (!tx0_finish) ++ iqk0_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ if (!tx1_finish) ++ iqk1_ready = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ BIT(10)); ++ if (iqk0_ready && iqk1_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TX delay_count = %d\n", ++ delay_count); ++ ++ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ ++ /* ============TXIQK Check============== */ ++ tx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(12)); ++ tx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(12)); ++ ++ if (!(tx0_fail || tx0_finish)) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x02000000); ++ tx_x0_temp[tx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x04000000); ++ tx_y0_temp[tx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x0[%d] = %x ;; tx_y0[%d] = %x\n", ++ tx0_avg, tx_x0_temp[tx0_avg], ++ tx0_avg, tx_y0_temp[tx0_avg]); ++ ++ tx_x0_temp[tx0_avg] <<= 21; ++ tx_y0_temp[tx0_avg] <<= 21; ++ ++ tx0_avg++; ++ } else { ++ cal0_retry++; ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (!(tx1_fail || tx1_finish)) { ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x02000000); ++ tx_x1_temp[tx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x04000000); ++ tx_y1_temp[tx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx_x1[%d] = %x ;; tx_y1[%d] = %x\n", ++ tx1_avg, tx_x1_temp[tx1_avg], ++ tx1_avg, tx_y1_temp[tx1_avg]); ++ ++ tx_x1_temp[tx1_avg] <<= 21; ++ tx_y1_temp[tx1_avg] <<= 21; ++ ++ tx1_avg++; ++ } else { ++ cal1_retry++; ++ if (cal1_retry == 10) ++ break; ++ } ++ } else { ++ cal0_retry++; ++ cal1_retry++; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "delay 20ms TX IQK Not Ready!!!!!\n"); ++ ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (tx0_avg >= 2) ++ tx0_finish = rtw88xxa_iqk_finish(tx0_avg, 4, ++ tx_x0_temp, tx_y0_temp, &tx_x0, &tx_y0, ++ false, false); ++ ++ if (tx1_avg >= 2) ++ tx1_finish = rtw88xxa_iqk_finish(tx1_avg, 4, ++ tx_x1_temp, tx_y1_temp, &tx_x1, &tx_y1, ++ false, false); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx0_average = %d, tx1_average = %d\n", ++ tx0_avg, tx1_avg); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "tx0_finish = %d, tx1_finish = %d\n", ++ tx0_finish, tx1_finish); ++ ++ if (tx0_finish && tx1_finish) ++ break; ++ ++ if ((cal0_retry + tx0_avg) >= 10 || ++ (cal1_retry + tx1_avg) >= 10) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXA_cal_retry = %d\n", cal0_retry); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "TXB_cal_retry = %d\n", cal1_retry); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ /* Load LOK */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_A, RF_DTXLOK, 0xffc00)); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXMOD, 0x7fe00, ++ rtw_read_rf(rtwdev, RF_PATH_B, RF_DTXLOK, 0xffc00)); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ if (tx0_finish) { ++ /* ====== path A RX IQK RF setting====== */ ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x3f7ff); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfe7bf); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_LUTWE, RFREG_MASK, 0x00000); ++ } ++ if (tx1_finish) { ++ /* ====== path B RX IQK RF setting====== */ ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x80000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_ADDR, RFREG_MASK, ++ 0x30000); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA0, RFREG_MASK, ++ 0x3f7ff); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_MODE_TABLE_DATA1, RFREG_MASK, ++ 0xfe7bf); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_RXBB2, RFREG_MASK, 0x88001); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_TXA_PREPAD, RFREG_MASK, 0x931d1); ++ rtw_write_rf(rtwdev, RF_PATH_B, RF_LUTWE, RFREG_MASK, 0x00000); ++ } ++ ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x1); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, BIT(31), 0x0); ++ rtw_write32(rtwdev, REG_DAC_RSTB, 0x00008000); ++ ++ if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE) ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a911); ++ else ++ rtw_write32(rtwdev, REG_IQK_COM96, 0x0046a890); ++ ++ if (efuse->rfe_option == 1) { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x00000077); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x00000077); ++ } else { ++ rtw_write32(rtwdev, REG_RFE_PINMUX_A, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_A, 0x02000077); ++ rtw_write32(rtwdev, REG_RFE_PINMUX_B, 0x77777717); ++ rtw_write32(rtwdev, REG_RFE_INV_B, 0x02000077); ++ } ++ ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ ++ if (tx0_finish) { ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_OFDM0_XA_TX_IQ_IMBALANCE, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_OFDM0_A_TX_AFE, 0x18008c10); ++ rtw_write32(rtwdev, REG_OFDM0_XB_TX_IQ_IMBALANCE, 0x82140119); ++ } ++ if (tx1_finish) { ++ /* TX_Tone_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ ++ rtw_write32(rtwdev, REG_TXTONEB, 0x38008c10); ++ /* RX_Tone_idx[9:0], RxK_Mask[29] */ ++ rtw_write32(rtwdev, REG_RXTONEB, 0x18008c10); ++ rtw_write32(rtwdev, REG_TXPITMB, 0x82140119); ++ } ++ ++ cal0_retry = 0; ++ cal1_retry = 0; ++ while (1) { ++ /* one shot */ ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ ++ if (tx0_finish) { ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ tx_x0 & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ tx_y0 & 0x000007ff); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ if (efuse->rfe_option == 1) ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28161500); ++ else ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x28160cc0); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00300000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00100000); ++ mdelay(5); ++ rtw_write32(rtwdev, REG_TSSI_TRK_SW, 0x3c000000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x00000000); ++ } ++ ++ if (tx1_finish) { ++ /* [31] = 0 --> Page C */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x0); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x03FF8000, ++ tx_x1 & 0x000007ff); ++ rtw_write32_mask(rtwdev, REG_IQK_COM00, 0x000007FF, ++ tx_y1 & 0x000007ff); ++ /* [31] = 1 --> Page C1 */ ++ rtw_write32_mask(rtwdev, REG_CCASEL, BIT(31), 0x1); ++ if (efuse->rfe_option == 1) ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28161500); ++ else ++ rtw_write32(rtwdev, REG_RXPITMB, 0x28160ca0); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00300000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00100000); ++ mdelay(5); ++ rtw_write32(rtwdev, REG_RXPITMB, 0x3c000000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x00000000); ++ } ++ ++ for (delay_count = 0; delay_count < 20; delay_count++) { ++ if (!rx0_finish && tx0_finish) ++ iqk0_ready = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ BIT(10)); ++ if (!rx1_finish && tx1_finish) ++ iqk1_ready = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ BIT(10)); ++ if (iqk0_ready && iqk1_ready) ++ break; ++ ++ mdelay(1); ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RX delay_count = %d\n", ++ delay_count); ++ ++ if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ ++ /* ============RXIQK Check============== */ ++ rx0_fail = rtw_read32_mask(rtwdev, REG_IQKA_END, BIT(11)); ++ rx1_fail = rtw_read32_mask(rtwdev, REG_IQKB_END, BIT(11)); ++ ++ if (!(rx0_fail || rx0_finish) && tx0_finish) { ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x06000000); ++ rx_x0_temp[rx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_A, 0x08000000); ++ rx_y0_temp[rx0_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKA_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x0[%d] = %x ;; rx_y0[%d] = %x\n", ++ rx0_avg, rx_x0_temp[rx0_avg], ++ rx0_avg, rx_y0_temp[rx0_avg]); ++ ++ rx_x0_temp[rx0_avg] <<= 21; ++ rx_y0_temp[rx0_avg] <<= 21; ++ ++ rx0_avg++; ++ } else { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "1. RXA_cal_retry = %d\n", cal0_retry); ++ ++ cal0_retry++; ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ if (!(rx1_fail || rx1_finish) && tx1_finish) { ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x06000000); ++ rx_x1_temp[rx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ rtw_write32(rtwdev, REG_RFECTL_B, 0x08000000); ++ rx_y1_temp[rx1_avg] = rtw_read32_mask(rtwdev, ++ REG_IQKB_END, ++ 0x07ff0000); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx_x1[%d] = %x ;; rx_y1[%d] = %x\n", ++ rx1_avg, rx_x1_temp[rx1_avg], ++ rx1_avg, rx_y1_temp[rx1_avg]); ++ ++ rx_x1_temp[rx1_avg] <<= 21; ++ rx_y1_temp[rx1_avg] <<= 21; ++ ++ rx1_avg++; ++ } else { ++ cal1_retry++; ++ if (cal1_retry == 10) ++ break; ++ } ++ } else { ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "2. RXA_cal_retry = %d\n", cal0_retry); ++ ++ cal0_retry++; ++ cal1_retry++; ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "delay 20ms RX IQK Not Ready!!!!!\n"); ++ ++ if (cal0_retry == 10) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "3. RXA_cal_retry = %d\n", ++ cal0_retry); ++ ++ if (rx0_avg >= 2) ++ rx0_finish = rtw88xxa_iqk_finish(rx0_avg, 4, ++ rx_x0_temp, rx_y0_temp, ++ &rx_x0, &rx_y0, ++ true, false); ++ ++ if (rx1_avg >= 2) ++ rx1_finish = rtw88xxa_iqk_finish(rx1_avg, 4, ++ rx_x1_temp, rx_y1_temp, ++ &rx_x1, &rx_y1, ++ true, false); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx0_average = %d, rx1_average = %d\n", ++ rx0_avg, rx1_avg); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, ++ "rx0_finish = %d, rx1_finish = %d\n", ++ rx0_finish, rx1_finish); ++ ++ if ((rx0_finish || !tx0_finish) && (rx1_finish || !tx1_finish)) ++ break; ++ ++ if ((cal0_retry + rx0_avg) >= 10 || ++ (cal1_retry + rx1_avg) >= 10 || ++ rx0_avg == 3 || rx1_avg == 3) ++ break; ++ } ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXA_cal_retry = %d\n", cal0_retry); ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "RXB_cal_retry = %d\n", cal1_retry); ++ ++ /* FillIQK Result */ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_A =======\n"); ++ ++ if (tx0_finish) ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, tx_x0, tx_y0); ++ else ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); ++ ++ if (rx0_finish) ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, rx_x0, rx_y0); ++ else ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_A, 0x200, 0x0); ++ ++ rtw_dbg(rtwdev, RTW_DBG_RFK, "========Path_B =======\n"); ++ ++ if (tx1_finish) ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, tx_x1, tx_y1); ++ else ++ rtw8812a_iqk_tx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); ++ ++ if (rx1_finish) ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, rx_x1, rx_y1); ++ else ++ rtw8812a_iqk_rx_fill(rtwdev, RF_PATH_B, 0x200, 0x0); ++} ++ ++#define MACBB_REG_NUM_8812A 9 ++#define AFE_REG_NUM_8812A 12 ++#define RF_REG_NUM_8812A 3 ++ ++static void rtw8812a_do_iqk(struct rtw_dev *rtwdev) ++{ ++ static const u32 backup_macbb_reg[MACBB_REG_NUM_8812A] = { ++ 0x520, 0x550, 0x808, 0xa04, 0x90c, 0xc00, 0xe00, 0x838, 0x82c ++ }; ++ static const u32 backup_afe_reg[AFE_REG_NUM_8812A] = { ++ 0xc5c, 0xc60, 0xc64, 0xc68, 0xcb0, 0xcb4, ++ 0xe5c, 0xe60, 0xe64, 0xe68, 0xeb0, 0xeb4 ++ }; ++ static const u32 backup_rf_reg[RF_REG_NUM_8812A] = { ++ 0x65, 0x8f, 0x0 ++ }; ++ u32 macbb_backup[MACBB_REG_NUM_8812A] = {}; ++ u32 afe_backup[AFE_REG_NUM_8812A] = {}; ++ u32 rfa_backup[RF_REG_NUM_8812A] = {}; ++ u32 rfb_backup[RF_REG_NUM_8812A] = {}; ++ u32 reg_cb8, reg_eb8; ++ ++ rtw88xxa_iqk_backup_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8812A); ++ ++ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); ++ reg_cb8 = rtw_read32(rtwdev, REG_RFECTL_A); ++ reg_eb8 = rtw_read32(rtwdev, REG_RFECTL_B); ++ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); ++ ++ rtw88xxa_iqk_backup_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8812A); ++ rtw8812a_iqk_backup_rf(rtwdev, rfa_backup, rfb_backup, ++ backup_rf_reg, RF_REG_NUM_8812A); ++ ++ rtw88xxa_iqk_configure_mac(rtwdev); ++ ++ rtw8812a_iqk(rtwdev); ++ ++ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_A, backup_rf_reg, ++ rfa_backup, RF_REG_NUM_8812A); ++ rtw8812a_iqk_restore_rf(rtwdev, RF_PATH_B, backup_rf_reg, ++ rfb_backup, RF_REG_NUM_8812A); ++ ++ rtw8812a_iqk_restore_afe(rtwdev, afe_backup, ++ backup_afe_reg, AFE_REG_NUM_8812A); ++ ++ rtw_write32_set(rtwdev, REG_CCASEL, BIT(31)); ++ rtw_write32(rtwdev, REG_RFECTL_A, reg_cb8); ++ rtw_write32(rtwdev, REG_RFECTL_B, reg_eb8); ++ rtw_write32_clr(rtwdev, REG_CCASEL, BIT(31)); ++ ++ rtw88xxa_iqk_restore_mac_bb(rtwdev, macbb_backup, ++ backup_macbb_reg, MACBB_REG_NUM_8812A); ++} ++ ++static void rtw8812a_phy_calibration(struct rtw_dev *rtwdev) ++{ ++ u8 channel = rtwdev->hal.current_channel; ++ ++ rtw8812a_do_iqk(rtwdev); ++ ++ /* The official driver wants to do this after connecting ++ * but before first writing a new igi (phydm_get_new_igi). ++ * Here seems close enough. ++ */ ++ if (channel >= 36 && channel <= 64) ++ rtw_load_table(rtwdev, &rtw8812a_agc_diff_lb_tbl); ++ else if (channel >= 100) ++ rtw_load_table(rtwdev, &rtw8812a_agc_diff_hb_tbl); ++} ++ ++static void rtw8812a_pwr_track(struct rtw_dev *rtwdev) ++{ ++ struct rtw_dm_info *dm_info = &rtwdev->dm_info; ++ ++ if (!dm_info->pwr_trk_triggered) { ++ rtw_write_rf(rtwdev, RF_PATH_A, RF_T_METER, ++ GENMASK(17, 16), 0x03); ++ dm_info->pwr_trk_triggered = true; ++ return; ++ } ++ ++ rtw88xxa_phy_pwrtrack(rtwdev, rtw8812a_do_lck, rtw8812a_do_iqk); ++ dm_info->pwr_trk_triggered = false; ++} ++ ++static void rtw8812a_fill_txdesc_checksum(struct rtw_dev *rtwdev, ++ struct rtw_tx_pkt_info *pkt_info, ++ u8 *txdesc) ++{ ++ fill_txdesc_checksum_common(txdesc, 16); ++} ++ ++static void rtw8812a_coex_cfg_init(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8812a_coex_cfg_gnt_fix(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_rfe_type(struct rtw_dev *rtwdev) ++{ ++} ++ ++static void rtw8821a_coex_cfg_wl_tx_power(struct rtw_dev *rtwdev, u8 wl_pwr) ++{ ++} ++ ++static void rtw8821a_coex_cfg_wl_rx_gain(struct rtw_dev *rtwdev, bool low_gain) ++{ ++} ++ ++static const struct rtw_chip_ops rtw8812a_ops = { ++ .power_on = rtw88xxa_power_on, ++ .power_off = rtw8812a_power_off, ++ .phy_set_param = NULL, ++ .read_efuse = rtw88xxa_read_efuse, ++ .query_phy_status = rtw8812a_query_phy_status, ++ .set_channel = rtw88xxa_set_channel, ++ .mac_init = NULL, ++ .read_rf = rtw88xxa_phy_read_rf, ++ .write_rf = rtw_phy_write_rf_reg_sipi, ++ .set_antenna = NULL, ++ .set_tx_power_index = rtw88xxa_set_tx_power_index, ++ .cfg_ldo25 = rtw8812a_cfg_ldo25, ++ .efuse_grant = rtw88xxa_efuse_grant, ++ .false_alarm_statistics = rtw88xxa_false_alarm_statistics, ++ .phy_calibration = rtw8812a_phy_calibration, ++ .cck_pd_set = rtw88xxa_phy_cck_pd_set, ++ .pwr_track = rtw8812a_pwr_track, ++ .config_bfee = NULL, ++ .set_gid_table = NULL, ++ .cfg_csi_rate = NULL, ++ .fill_txdesc_checksum = rtw8812a_fill_txdesc_checksum, ++ .coex_set_init = rtw8812a_coex_cfg_init, ++ .coex_set_ant_switch = NULL, ++ .coex_set_gnt_fix = rtw8812a_coex_cfg_gnt_fix, ++ .coex_set_gnt_debug = NULL, ++ .coex_set_rfe_type = rtw8821a_coex_cfg_rfe_type, ++ .coex_set_wl_tx_power = rtw8821a_coex_cfg_wl_tx_power, ++ .coex_set_wl_rx_gain = rtw8821a_coex_cfg_wl_rx_gain, ++}; ++ ++static const struct rtw_page_table page_table_8812a[] = { ++ /* hq_num, nq_num, lq_num, exq_num, gapq_num */ ++ {0, 0, 0, 0, 0}, /* SDIO */ ++ {0, 0, 0, 0, 0}, /* PCI */ ++ {16, 0, 0, 0, 1}, /* 2 bulk out endpoints */ ++ {16, 0, 16, 0, 1}, /* 3 bulk out endpoints */ ++ {16, 0, 16, 0, 1}, /* 4 bulk out endpoints */ ++}; ++ ++static const struct rtw_rqpn rqpn_table_8812a[] = { ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH, ++ RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_HIGH, RTW_DMA_MAPPING_HIGH}, ++ ++ {RTW_DMA_MAPPING_NORMAL, RTW_DMA_MAPPING_NORMAL, ++ RTW_DMA_MAPPING_LOW, RTW_DMA_MAPPING_LOW, ++ RTW_DMA_MAPPING_EXTRA, RTW_DMA_MAPPING_HIGH}, ++}; ++ ++static const struct rtw_prioq_addrs prioq_addrs_8812a = { ++ .prio[RTW_DMA_MAPPING_EXTRA] = { ++ .rsvd = REG_RQPN_NPQ + 2, .avail = REG_RQPN_NPQ + 3, ++ }, ++ .prio[RTW_DMA_MAPPING_LOW] = { ++ .rsvd = REG_RQPN + 1, .avail = REG_FIFOPAGE_CTRL_2 + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_NORMAL] = { ++ .rsvd = REG_RQPN_NPQ, .avail = REG_RQPN_NPQ + 1, ++ }, ++ .prio[RTW_DMA_MAPPING_HIGH] = { ++ .rsvd = REG_RQPN, .avail = REG_FIFOPAGE_CTRL_2, ++ }, ++ .wsize = false, ++}; ++ ++static const struct rtw_hw_reg rtw8812a_dig[] = { ++ [0] = { .addr = REG_RXIGI_A, .mask = 0x7f }, ++ [1] = { .addr = REG_RXIGI_B, .mask = 0x7f }, ++}; ++ ++static const struct rtw_rfe_def rtw8812a_rfe_defs[] = { ++ [0] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, ++ [1] = { .phy_pg_tbl = &rtw8812a_bb_pg_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_tbl, }, ++ [3] = { .phy_pg_tbl = &rtw8812a_bb_pg_rfe3_tbl, ++ .txpwr_lmt_tbl = &rtw8812a_txpwr_lmt_tbl, ++ .pwr_track_tbl = &rtw8812a_rtw_pwr_track_rfe3_tbl, }, ++}; ++ ++static const u8 wl_rssi_step_8812a[] = {101, 45, 101, 40}; ++static const u8 bt_rssi_step_8812a[] = {101, 101, 101, 101}; ++ ++static const struct coex_rf_para rf_para_tx_8812a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {8, 17, true, 4}, ++ {7, 18, true, 4}, ++ {6, 19, true, 4}, ++ {5, 20, true, 4} ++}; ++ ++static const struct coex_rf_para rf_para_rx_8812a[] = { ++ {0, 0, false, 7}, /* for normal */ ++ {0, 20, false, 7}, /* for WL-CPT */ ++ {3, 24, true, 5}, ++ {2, 26, true, 5}, ++ {1, 27, true, 5}, ++ {0, 28, true, 5} ++}; ++ ++static_assert(ARRAY_SIZE(rf_para_tx_8812a) == ARRAY_SIZE(rf_para_rx_8812a)); ++ ++const struct rtw_chip_info rtw8812a_hw_spec = { ++ .ops = &rtw8812a_ops, ++ .id = RTW_CHIP_TYPE_8812A, ++ .fw_name = "rtw88/rtw8812a_fw.bin", ++ .wlan_cpu = RTW_WCPU_11N, ++ .tx_pkt_desc_sz = 40, ++ .tx_buf_desc_sz = 16, ++ .rx_pkt_desc_sz = 24, ++ .rx_buf_desc_sz = 8, ++ .phy_efuse_size = 512, ++ .log_efuse_size = 512, ++ .ptct_efuse_size = 96 + 1, /* TODO or just 18? */ ++ .txff_size = 131072, ++ .rxff_size = 16128, ++ .rsvd_drv_pg_num = 9, ++ .txgi_factor = 1, ++ .is_pwr_by_rate_dec = true, ++ .max_power_index = 0x3f, ++ .csi_buf_pg_num = 0, ++ .band = RTW_BAND_2G | RTW_BAND_5G, ++ .page_size = 512, ++ .dig_min = 0x20, ++ .ht_supported = true, ++ .vht_supported = true, ++ .lps_deep_mode_supported = 0, ++ .sys_func_en = 0xFD, ++ .pwr_on_seq = card_enable_flow_8812a, ++ .pwr_off_seq = card_disable_flow_8812a, ++ .page_table = page_table_8812a, ++ .rqpn_table = rqpn_table_8812a, ++ .prioq_addrs = &prioq_addrs_8812a, ++ .intf_table = NULL, ++ .dig = rtw8812a_dig, ++ .rf_sipi_addr = {REG_LSSI_WRITE_A, REG_LSSI_WRITE_B}, ++ .ltecoex_addr = NULL, ++ .mac_tbl = &rtw8812a_mac_tbl, ++ .agc_tbl = &rtw8812a_agc_tbl, ++ .bb_tbl = &rtw8812a_bb_tbl, ++ .rf_tbl = {&rtw8812a_rf_a_tbl, &rtw8812a_rf_b_tbl}, ++ .rfe_defs = rtw8812a_rfe_defs, ++ .rfe_defs_size = ARRAY_SIZE(rtw8812a_rfe_defs), ++ .rx_ldpc = false, ++ .hw_feature_report = false, ++ .c2h_ra_report_size = 4, ++ .old_datarate_fb_limit = true, ++ .usb_tx_agg_desc_num = 1, ++ .iqk_threshold = 8, ++ .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, ++ .max_scan_ie_len = IEEE80211_MAX_DATA_LEN, ++ ++ .coex_para_ver = 0, /* no coex code in 8812au driver */ ++ .bt_desired_ver = 0, ++ .scbd_support = false, ++ .new_scbd10_def = false, ++ .ble_hid_profile_support = false, ++ .wl_mimo_ps_support = false, ++ .pstdma_type = COEX_PSTDMA_FORCE_LPSOFF, ++ .bt_rssi_type = COEX_BTRSSI_RATIO, ++ .ant_isolation = 15, ++ .rssi_tolerance = 2, ++ .wl_rssi_step = wl_rssi_step_8812a, ++ .bt_rssi_step = bt_rssi_step_8812a, ++ .table_sant_num = 0, ++ .table_sant = NULL, ++ .table_nsant_num = 0, ++ .table_nsant = NULL, ++ .tdma_sant_num = 0, ++ .tdma_sant = NULL, ++ .tdma_nsant_num = 0, ++ .tdma_nsant = NULL, ++ .wl_rf_para_num = ARRAY_SIZE(rf_para_tx_8812a), ++ .wl_rf_para_tx = rf_para_tx_8812a, ++ .wl_rf_para_rx = rf_para_rx_8812a, ++ .bt_afh_span_bw20 = 0x20, ++ .bt_afh_span_bw40 = 0x30, ++ .afh_5g_num = 0, ++ .afh_5g = NULL, ++ .coex_info_hw_regs_num = 0, ++ .coex_info_hw_regs = NULL, ++}; ++EXPORT_SYMBOL(rtw8812a_hw_spec); ++ ++MODULE_FIRMWARE("rtw88/rtw8812a_fw.bin"); ++ ++MODULE_AUTHOR("Realtek Corporation"); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812a driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812a.h +@@ -0,0 +1,10 @@ ++/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#ifndef __RTW8812A_H__ ++#define __RTW8812A_H__ ++ ++extern const struct rtw_chip_info rtw8812a_hw_spec; ++ ++#endif diff --git a/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch b/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch new file mode 100644 index 00000000000000..a37f131bab8ffe --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/044-v6.13-wifi-rtw88-Add-rtw8821au.c-and-rtw8812au.c.patch @@ -0,0 +1,80 @@ +From 8f82bb2cfaf7b8992e0e8493cb765138254f87c9 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:29:28 +0200 +Subject: [PATCH] wifi: rtw88: Add rtw8821au.c and rtw8812au.c + +These are the entry points for the new modules rtw88_8821au +(RTL8821AU/RTL8811AU) and rtw88_8812au (RTL8812AU). + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/91c495f8-a607-429b-8bc0-5a45d3c1393e@gmail.com +--- + .../net/wireless/realtek/rtw88/rtw8812au.c | 28 +++++++++++++++++++ + .../net/wireless/realtek/rtw88/rtw8821au.c | 28 +++++++++++++++++++ + 2 files changed, 56 insertions(+) + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8812au.c + create mode 100644 drivers/net/wireless/realtek/rtw88/rtw8821au.c + +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8812a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8812au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); ++ ++static struct usb_driver rtw_8812au_driver = { ++ .name = "rtw_8812au", ++ .id_table = rtw_8812au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8812au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8812au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); +--- /dev/null ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +@@ -0,0 +1,28 @@ ++// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause ++/* Copyright(c) 2024 Realtek Corporation ++ */ ++ ++#include ++#include ++#include "main.h" ++#include "rtw8821a.h" ++#include "usb.h" ++ ++static const struct usb_device_id rtw_8821au_id_table[] = { ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); ++ ++static struct usb_driver rtw_8821au_driver = { ++ .name = "rtw_8821au", ++ .id_table = rtw_8821au_id_table, ++ .probe = rtw_usb_probe, ++ .disconnect = rtw_usb_disconnect, ++}; ++module_usb_driver(rtw_8821au_driver); ++ ++MODULE_AUTHOR("Bitterblue Smith "); ++MODULE_DESCRIPTION("Realtek 802.11ac wireless 8821au/8811au driver"); ++MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch b/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch new file mode 100644 index 00000000000000..6a4a2aff6980d7 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/045-v6.13-wifi-rtw88-Enable-the-new-RTL8821AU-RTL8812AU-driver.patch @@ -0,0 +1,153 @@ +From 0e3e8284f8e1bf2fc0f7bf247194efe5cfc568c1 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Wed, 30 Oct 2024 20:31:28 +0200 +Subject: [PATCH] wifi: rtw88: Enable the new RTL8821AU/RTL8812AU drivers + +These are older Wifi 5 chips. RTL8821AU is 1x1, with or without +Bluetooth. RTL8812AU is 2x2, without Bluetooth. + +Beamforming is not implemented. It looks like these chips need a +different implementation than what is in bf.c. + +Speed tests with RTL8821AU: 137 Mbps download, 144 Mbps upload. +Speed tests with RTL8812AU: 344 Mbps download, 387 Mbps upload. + +Station mode and AP mode were tested. + +Bluetooth coexistence works. I used my Bluetooth headphones for +several days, listening to music and watching videos. There is only +a problem with the wifi speeds with one router: + +With ISP's HG6544C router: +Official driver: 3/5 Mbps. +rtw88: a bit more, but not steady at all. Not enough to watch a 1080p +Youtube video. + +With my D-Link Eagle R32 router running Openwrt, on the same channel: +Official driver: 6/10 Mbps. +rtw88: download starts around 30, climbs to 50 / upload is 10 Mbps. +I can watch a 1080p Youtube video. + +The music doesn't cut out during any speed tests. + +I also tested transferring files to and from my phone. I don't have +other types of Bluetooth devices to test. + +Signed-off-by: Bitterblue Smith +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/0b8e8093-8103-4999-86bf-0055ec52ea64@gmail.com +--- +Kconfig.local | 15 ++++++++ + drivers/net/wireless/realtek/rtw88/Kconfig | 40 ++++++++++++++++++++- + drivers/net/wireless/realtek/rtw88/Makefile | 15 ++++++++ + 3 files changed, 69 insertions(+), 1 deletion(-) + +--- a/Kconfig.local ++++ b/Kconfig.local +@@ -1144,6 +1144,15 @@ config BACKPORTED_RTW88_8723D + config BACKPORTED_RTW88_8821C + tristate + default RTW88_8821C ++config BACKPORTED_RTW88_88XXA ++ tristate ++ default RTW88_88XXA ++config BACKPORTED_RTW88_8821A ++ tristate ++ default RTW88_8821A ++config BACKPORTED_RTW88_8812A ++ tristate ++ default RTW88_8812A + config BACKPORTED_RTW88_8822BE + tristate + default RTW88_8822BE +@@ -1183,6 +1192,12 @@ config BACKPORTED_RTW88_8821CS + config BACKPORTED_RTW88_8821CU + tristate + default RTW88_8821CU ++config BACKPORTED_RTW88_8821AU ++ tristate ++ default RTW88_8821AU ++config BACKPORTED_RTW88_8812AU ++ tristate ++ default RTW88_8812AU + config BACKPORTED_RTW88_DEBUG + tristate + default RTW88_DEBUG +--- a/drivers/net/wireless/realtek/rtw88/Kconfig ++++ b/drivers/net/wireless/realtek/rtw88/Kconfig +@@ -54,6 +54,20 @@ config RTW88_8821C + tristate + depends on m + ++config RTW88_88XXA ++ tristate ++ depends on m ++ ++config RTW88_8821A ++ tristate ++ depends on m ++ select RTW88_88XXA ++ ++config RTW88_8812A ++ tristate ++ depends on m ++ select RTW88_88XXA ++ + config RTW88_8822BE + tristate "Realtek 8822BE PCI wireless network adapter" + depends on m +@@ -213,6 +227,30 @@ config RTW88_8821CU + + 802.11ac USB wireless network adapter + ++config RTW88_8821AU ++ tristate "Realtek 8821AU/8811AU USB wireless network adapter" ++ depends on m ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8821A ++ help ++ Select this option will enable support for 8821AU and 8811AU chipset ++ ++ 802.11ac USB wireless network adapter ++ ++config RTW88_8812AU ++ tristate "Realtek 8812AU USB wireless network adapter" ++ depends on m ++ depends on USB ++ select RTW88_CORE ++ select RTW88_USB ++ select RTW88_8812A ++ help ++ Select this option will enable support for 8812AU chipset ++ ++ 802.11ac USB wireless network adapter ++ + config RTW88_DEBUG + bool "Realtek rtw88 debug support" + depends on RTW88_CORE +--- a/drivers/net/wireless/realtek/rtw88/Makefile ++++ b/drivers/net/wireless/realtek/rtw88/Makefile +@@ -77,6 +77,21 @@ rtw88_8821cs-objs := rtw8821cs.o + obj-$(CPTCFG_RTW88_8821CU) += rtw88_8821cu.o + rtw88_8821cu-objs := rtw8821cu.o + ++obj-$(CPTCFG_RTW88_88XXA) += rtw88_88xxa.o ++rtw88_88xxa-objs := rtw88xxa.o ++ ++obj-$(CPTCFG_RTW88_8821A) += rtw88_8821a.o ++rtw88_8821a-objs := rtw8821a.o rtw8821a_table.o ++ ++obj-$(CPTCFG_RTW88_8812A) += rtw88_8812a.o ++rtw88_8812a-objs := rtw8812a.o rtw8812a_table.o ++ ++obj-$(CPTCFG_RTW88_8821AU) += rtw88_8821au.o ++rtw88_8821au-objs := rtw8821au.o ++ ++obj-$(CPTCFG_RTW88_8812AU) += rtw88_8812au.o ++rtw88_8812au-objs := rtw8812au.o ++ + obj-$(CPTCFG_RTW88_PCI) += rtw88_pci.o + rtw88_pci-objs := pci.o + diff --git a/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch b/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch new file mode 100644 index 00000000000000..a83094b3c3ee2b --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/046-wifi-rtw88-8821au-Add-additional-devices-to-the-USB_.patch @@ -0,0 +1,77 @@ +From ff5a1c94e53c0d24f610c2c30add82f75b728737 Mon Sep 17 00:00:00 2001 +From: Larry Finger +Date: Wed, 6 Nov 2024 15:55:31 +0200 +Subject: [PATCH 1/6] wifi: rtw88: 8821au: Add additional devices to the + USB_DEVICE list + +These are the entries that Nick Morrow provided. From +https://github.com/morrownr/8821au-20210708 + +Signed-off-by: Larry Finger +Signed-off-by: Bitterblue Smith +--- + .../net/wireless/realtek/rtw88/rtw8821au.c | 52 ++++++++++++++++++- + 1 file changed, 51 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8821au.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8821au.c +@@ -9,8 +9,58 @@ + #include "usb.h" + + static const struct usb_device_id rtw_8821au_id_table[] = { +- { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0820, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0821, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8822, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x0823, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0xa811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x0242, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x029b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0953, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* I-O DATA */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4007, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x400f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* ELECOM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9052, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Netgear */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0023, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* HAWKING */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3314, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3318, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab32, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Planex */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x804b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TRENDnet */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x011f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0120, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* TP Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x3823, 0x6249, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Obihai */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa811, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa813, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xb611, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8821a_hw_spec) }, /* Edimax */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8821au_id_table); diff --git a/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch b/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch new file mode 100644 index 00000000000000..a93f9219d9fcc2 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/047-wifi-rtw88-8812au-Add-more-device-IDs.patch @@ -0,0 +1,91 @@ +From d21ad2e4edfb64d3f32685607a457576eea3c5cd Mon Sep 17 00:00:00 2001 +From: Nick Morrow +Date: Wed, 6 Nov 2024 15:57:10 +0200 +Subject: [PATCH 2/6] wifi: rtw88: 8812au: Add more device IDs + +From https://github.com/morrownr/8812au-20210820. + +Signed-off-by: Nick Morrow +Signed-off-by: Bitterblue Smith +--- + .../net/wireless/realtek/rtw88/rtw8812au.c | 68 ++++++++++++++++++- + 1 file changed, 67 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8812au.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8812au.c +@@ -9,8 +9,74 @@ + #include "usb.h" + + static const struct usb_device_id rtw_8812au_id_table[] = { +- { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x8812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881a, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881b, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(RTW_USB_VENDOR_ID_REALTEK, 0x881c, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0409, 0x0408, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* NEC */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0411, 0x025d, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Buffalo */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x04bb, 0x0952, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* I-O DATA */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1106, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x050d, 0x1109, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Belkin */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0586, 0x3426, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ZyXEL */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0789, 0x016e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Logitec */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x07b8, 0x8812, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Abocom */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0846, 0x9051, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Netgear */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0b05, 0x17d2, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* ASUS */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0df6, 0x0074, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Sitecom */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x0e66, 0x0022, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Hawking */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1058, 0x0632, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* WD */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x13b1, 0x003f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Linksys */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x148f, 0x9097, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Amped Wireless */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x1740, 0x0100, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* EnGenius */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x330e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3313, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3315, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3316, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* D-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab30, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Planex */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805b, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TRENDnet */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0101, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0103, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010d, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010e, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x010f, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0122, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* TP-Link */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2604, 0x0012, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Tenda */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0xa822, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8812a_hw_spec) }, /* Edimax */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8812au_id_table); diff --git a/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch b/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch new file mode 100644 index 00000000000000..2ccefb98939022 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/048-wifi-rtw88-usb-Support-USB-3-with-RTL8812AU.patch @@ -0,0 +1,69 @@ +From 213dfa630285bb0241f3eaeb778db8ff128f10ba Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 8 Nov 2024 01:41:08 +0200 +Subject: [PATCH 3/6] wifi: rtw88: usb: Support USB 3 with RTL8812AU + +Add the function to automatically switch the RTL8812AU into USB 3 mode. + +Signed-off-by: Bitterblue Smith +--- + drivers/net/wireless/realtek/rtw88/usb.c | 34 ++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -929,6 +929,32 @@ static void rtw_usb_intf_deinit(struct r + usb_set_intfdata(intf, NULL); + } + ++static int rtw_usb_switch_mode_old(struct rtw_dev *rtwdev) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ enum usb_device_speed cur_speed = rtwusb->udev->speed; ++ u8 hci_opt; ++ ++ if (cur_speed == USB_SPEED_HIGH) { ++ hci_opt = rtw_read8(rtwdev, REG_HCI_OPT_CTRL); ++ ++ if ((hci_opt & (BIT(2) | BIT(3))) != BIT(3)) { ++ rtw_write8(rtwdev, REG_HCI_OPT_CTRL, 0x8); ++ rtw_write8(rtwdev, REG_SYS_SDIO_CTRL, 0x2); ++ rtw_write8(rtwdev, REG_ACLK_MON, 0x1); ++ rtw_write8(rtwdev, 0x3d, 0x3); ++ /* usb disconnect */ ++ rtw_write8(rtwdev, REG_SYS_PW_CTRL + 1, 0x80); ++ return 1; ++ } ++ } else if (cur_speed == USB_SPEED_SUPER) { ++ rtw_write8_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT(1)); ++ rtw_write8_clr(rtwdev, REG_ACLK_MON, BIT(0)); ++ } ++ ++ return 0; ++} ++ + static int rtw_usb_switch_mode_new(struct rtw_dev *rtwdev) + { + enum usb_device_speed cur_speed; +@@ -982,7 +1008,8 @@ static int rtw_usb_switch_mode(struct rt + { + u8 id = rtwdev->chip->id; + +- if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B) ++ if (id != RTW_CHIP_TYPE_8822C && id != RTW_CHIP_TYPE_8822B && ++ id != RTW_CHIP_TYPE_8812A) + return 0; + + if (!rtwdev->efuse.usb_mode_switch) { +@@ -997,7 +1024,10 @@ static int rtw_usb_switch_mode(struct rt + return 0; + } + +- return rtw_usb_switch_mode_new(rtwdev); ++ if (id == RTW_CHIP_TYPE_8812A) ++ return rtw_usb_switch_mode_old(rtwdev); ++ else /* RTL8822CU, RTL8822BU */ ++ return rtw_usb_switch_mode_new(rtwdev); + } + + int rtw_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) diff --git a/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch b/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch new file mode 100644 index 00000000000000..00775c0281e99b --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/049-wifi-rtw88-usb-Enable-RX-aggregation-for-8821au-8812.patch @@ -0,0 +1,65 @@ +From 2b38362bd3b8e0a3691f0a8e82444a54f702e384 Mon Sep 17 00:00:00 2001 +From: Bitterblue Smith +Date: Fri, 8 Nov 2024 01:43:50 +0200 +Subject: [PATCH 4/6] wifi: rtw88: usb: Enable RX aggregation for 8821au/8812au + +USB RX aggregation improves the RX speed on certain ARM systems, like +the NanoPi NEO Core2. With RTL8811AU, before: 30 Mbps, after: 224 Mbps. + +The out-of-tree driver uses aggregation size of 7 in USB 3 mode, but +that doesn't work here. rtw88 advertises support for receiving AMSDU +in AMPDU, so the AP sends larger frames, up to ~5100 bytes. With a size +of 7 RTL8812AU frequently tries to aggregate more frames than will fit +in 32768 bytes. Use a size of 6 instead. + +Signed-off-by: Bitterblue Smith +--- + drivers/net/wireless/realtek/rtw88/usb.c | 30 ++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/usb.c ++++ b/drivers/net/wireless/realtek/rtw88/usb.c +@@ -788,6 +788,32 @@ static void rtw_usb_dynamic_rx_agg_v1(st + rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); + } + ++static void rtw_usb_dynamic_rx_agg_v2(struct rtw_dev *rtwdev, bool enable) ++{ ++ struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev); ++ u8 size, timeout; ++ u16 val16; ++ ++ if (rtwusb->udev->speed == USB_SPEED_SUPER) { ++ size = 0x6; ++ timeout = 0x1a; ++ } else { ++ size = 0x5; ++ timeout = 0x20; ++ } ++ ++ if (!enable) { ++ size = 0x0; ++ timeout = 0x1; ++ } ++ ++ val16 = u16_encode_bits(size, BIT_RXDMA_AGG_PG_TH) | ++ u16_encode_bits(timeout, BIT_DMA_AGG_TO_V1); ++ ++ rtw_write16(rtwdev, REG_RXDMA_AGG_PG_TH, val16); ++ rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); ++} ++ + static void rtw_usb_dynamic_rx_agg(struct rtw_dev *rtwdev, bool enable) + { + switch (rtwdev->chip->id) { +@@ -796,6 +822,10 @@ static void rtw_usb_dynamic_rx_agg(struc + case RTW_CHIP_TYPE_8821C: + rtw_usb_dynamic_rx_agg_v1(rtwdev, enable); + break; ++ case RTW_CHIP_TYPE_8821A: ++ case RTW_CHIP_TYPE_8812A: ++ rtw_usb_dynamic_rx_agg_v2(rtwdev, enable); ++ break; + case RTW_CHIP_TYPE_8723D: + /* Doesn't like aggregation. */ + break; diff --git a/package/kernel/mac80211/patches/rtl/050-wifi-rtlwifi-rtl8821ae-phy-restore-removed-code-to-f.patch b/package/kernel/mac80211/patches/rtl/050-wifi-rtlwifi-rtl8821ae-phy-restore-removed-code-to-f.patch new file mode 100644 index 00000000000000..798a59351f7a0d --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/050-wifi-rtlwifi-rtl8821ae-phy-restore-removed-code-to-f.patch @@ -0,0 +1,32 @@ +From 927dcd0ab53f39ee00a2d1f204b5aac77e28fcf9 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 6 Nov 2024 15:46:42 +0000 +Subject: [PATCH 5/6] wifi: rtlwifi: rtl8821ae: phy: restore removed code to + fix infinite loop + +A previous clean-up fix removed the assignment of v2 inside a while loop +that turned it into an infinite loop. Fix this by restoring the assignment +of v2 from array[] so that v2 is updated inside the loop. + +Fixes: cda37445718d ("wifi: rtlwifi: rtl8821ae: phy: remove some useless code") +Signed-off-by: Colin Ian King +Tested-by: Ping-Ke Shih +Reviewed-by: Su Hui +--- + drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c ++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +@@ -2033,8 +2033,10 @@ static bool _rtl8821ae_phy_config_bb_wit + if (!_rtl8821ae_check_condition(hw, v1)) { + i += 2; /* skip the pair of expression*/ + v2 = array[i+1]; +- while (v2 != 0xDEAD) ++ while (v2 != 0xDEAD) { + i += 3; ++ v2 = array[i + 1]; ++ } + } + } + } diff --git a/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch b/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch new file mode 100644 index 00000000000000..e4e26c79751116 --- /dev/null +++ b/package/kernel/mac80211/patches/rtl/051-wifi-rtw88-Add-additional-USB-IDs-for-RTL8812BU.patch @@ -0,0 +1,31 @@ +From acadf3a63b39ad03167a633fa3cea8c0fc2ab87f Mon Sep 17 00:00:00 2001 +From: Nick Morrow +Date: Thu, 7 Nov 2024 08:28:46 +0800 +Subject: [PATCH 6/6] wifi: rtw88: Add additional USB IDs for RTL8812BU + +Add three additional USB IDs found in +https://github.com/morrownr/88x2bu-20210702 +to support more RTL8812BU devices. + +Signed-off-by: Nick Morrow +Signed-off-by: Zenm Chen +Signed-off-by: Mikhail Novosyolov +--- + drivers/net/wireless/realtek/rtw88/rtw8822bu.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/realtek/rtw88/rtw8822bu.c ++++ b/drivers/net/wireless/realtek/rtw88/rtw8822bu.c +@@ -67,6 +67,12 @@ static const struct usb_device_id rtw_88 + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* LiteOn */ + { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x808a, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-808UBM */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x20f4, 0x805a, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* TRENDnet TEW-805UBH */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x056e, 0x4011, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* ELECOM WDB-867DU3S */ ++ { USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0107, 0xff, 0xff, 0xff), ++ .driver_info = (kernel_ulong_t)&(rtw8822b_hw_spec) }, /* Mercusys MA30H */ + {}, + }; + MODULE_DEVICE_TABLE(usb, rtw_8822bu_id_table); diff --git a/package/kernel/mac80211/realtek.mk b/package/kernel/mac80211/realtek.mk index 4a6f10cddc51bb..6ac4b1aee9873c 100644 --- a/package/kernel/mac80211/realtek.mk +++ b/package/kernel/mac80211/realtek.mk @@ -4,6 +4,7 @@ PKG_DRIVERS += \ rtl8723bs rtl8821ae rtl8xxxu rtw88 rtw88-pci rtw88-usb rtw88-sdio rtw88-8821c \ rtw88-8822b rtw88-8822c rtw88-8723x rtw88-8723d rtw88-8821ce rtw88-8821cu \ rtw88-8822be rtw88-8822bu rtw88-8822ce rtw88-8822cu rtw88-8723de rtw88-8723ds \ + rtw88-88xxa rtw88-8821a rtw88-8812a rtw88-8821au rtw88-8812au \ rtw88-8723du rtw89 rtw89-pci rtw89-8851be rtw89-8852ae rtw89-8852b-common \ rtw89-8852be rtw89-8852ce rtw89-8922ae @@ -48,6 +49,11 @@ config-$(call config_package,rtw88-8723d) += RTW88_8723D config-$(call config_package,rtw88-8723de) += RTW88_8723DE config-$(call config_package,rtw88-8723ds) += RTW88_8723DS config-$(call config_package,rtw88-8723du) += RTW88_8723DU +config-$(call config_package,rtw88-88xxa) += RTW88_88XXA +config-$(call config_package,rtw88-8821a) += RTW88_8821A +config-$(call config_package,rtw88-8812a) += RTW88_8812A +config-$(call config_package,rtw88-8821au) += RTW88_8821AU +config-$(call config_package,rtw88-8812au) += RTW88_8812AU config-$(CONFIG_PACKAGE_RTW88_DEBUG) += RTW88_DEBUG config-$(CONFIG_PACKAGE_RTW88_DEBUGFS) += RTW88_DEBUGFS @@ -255,6 +261,33 @@ define KernelPackage/rtw88-usb HIDDEN:=1 endef +define KernelPackage/rtw88-88xxa + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812A/RTL8821A family support + DEPENDS+= +@DRIVER_11AC_SUPPORT +kmod-rtw88-usb + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_88xxa.ko + AUTOLOAD:=$(call AutoProbe,rtw88_88xxa) + HIDDEN:=1 +endef + +define KernelPackage/rtw88-8821a + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8821A family support + DEPENDS+= +kmod-rtw88-88xxa + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821a.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821a) + HIDDEN:=1 +endef + +define KernelPackage/rtw88-8812a + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812A family support + DEPENDS+= +kmod-rtw88-88xxa + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8812a.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8812a) + HIDDEN:=1 +endef + define KernelPackage/rtw88-8821c $(call KernelPackage/mac80211/Default) TITLE:=Realtek RTL8821C family support @@ -300,6 +333,22 @@ define KernelPackage/rtw88-8723d HIDDEN:=1 endef +define KernelPackage/rtw88-8821au + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8821AU support + DEPENDS+= +kmod-rtw88-8821a +rtl8821a-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8821au.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8821au) +endef + +define KernelPackage/rtw88-8812au + $(call KernelPackage/mac80211/Default) + TITLE:=Realtek RTL8812AU support + DEPENDS+= +kmod-rtw88-8812a +rtl8812a-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtw88/rtw88_8812au.ko + AUTOLOAD:=$(call AutoProbe,rtw88_8812au) +endef + define KernelPackage/rtw88-8821ce $(call KernelPackage/mac80211/Default) TITLE:=Realtek RTL8821CE support diff --git a/package/libs/gmp/Makefile b/package/libs/gmp/Makefile index 6bcee784ed8081..f2cacc942c66eb 100644 --- a/package/libs/gmp/Makefile +++ b/package/libs/gmp/Makefile @@ -11,9 +11,9 @@ PKG_NAME:=gmp PKG_VERSION:=6.3.0 PKG_RELEASE:=1 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)$(PKG_REVISION).tar.xz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/gmp/ -PKG_HASH:=a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898 +PKG_HASH:=e56fd59d76810932a0555aa15a14b61c16bed66110d3c75cc2ac49ddaa9ab24c PKG_BUILD_PARALLEL:=1 PKG_INSTALL:=1 diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile index a4400c9516eca6..95f1f6f7d11e09 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=netifd -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2024-11-08 -PKG_SOURCE_VERSION:=34eb11eb6f5c62de480d6192f0ca840093127fee -PKG_MIRROR_HASH:=c4c2bc626426d2cd73c9ece54b22ada6ed6254afa992f51b8725312aca240cfd +PKG_SOURCE_DATE:=2024-11-27 +PKG_SOURCE_VERSION:=768027c5a7640137857f412f554227abd6160cdd +PKG_MIRROR_HASH:=5f74dc10470c64b42caa2d1fda3b80672293cf39676aa5c0b9f8c89880a15270 PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 diff --git a/package/network/config/netifd/files/etc/init.d/network b/package/network/config/netifd/files/etc/init.d/network index dc208c4ce0a1f5..86340b77e53c6e 100755 --- a/package/network/config/netifd/files/etc/init.d/network +++ b/package/network/config/netifd/files/etc/init.d/network @@ -30,12 +30,12 @@ reload_service() { init_switch ubus call network reload || rv=1 - /sbin/wifi reload_legacy + [ -x /sbin/wifi ] && /sbin/wifi reload_legacy return $rv } stop_service() { - /sbin/wifi down + [ -x /sbin/wifi ] && /sbin/wifi down ifdown -a sleep 1 } diff --git a/package/network/config/wifi-scripts/Config.in b/package/network/config/wifi-scripts/Config.in new file mode 100644 index 00000000000000..92e661246491e7 --- /dev/null +++ b/package/network/config/wifi-scripts/Config.in @@ -0,0 +1,3 @@ +config WIFI_SCRIPTS_UCODE + bool "Use new ucode based scripts" + default n diff --git a/package/network/config/wifi-scripts/Makefile b/package/network/config/wifi-scripts/Makefile index ae41f749498624..52edd1b56764da 100644 --- a/package/network/config/wifi-scripts/Makefile +++ b/package/network/config/wifi-scripts/Makefile @@ -13,17 +13,22 @@ PKG_RELEASE:=1 PKG_LICENSE:=GPL-2.0 PKG_MAINTAINER:=Felix Fietkau +PKG_CONFIG_DEPENDS:=CONFIG_WIFI_SCRIPTS_UCODE include $(INCLUDE_DIR)/package.mk define Package/wifi-scripts SECTION:=utils CATEGORY:=Base system - DEPENDS:=+netifd +ucode +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uci + DEPENDS:=+netifd +ucode +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uci +ucode-mod-digest TITLE:=Wi-Fi configuration scripts PKGARCH:=all endef +define Package/wifi-scripts/config + source "$(SOURCE)/Config.in" +endef + define Package/wifi-scripts/description A set of scripts that handle setup and configuration of Wi-Fi devices. endef @@ -40,6 +45,9 @@ endef define Package/wifi-scripts/install $(INSTALL_DIR) $(1) $(CP) ./files/* $(1)/ +ifeq ($(CONFIG_WIFI_SCRIPTS_UCODE),y) + $(CP) ./files-ucode/* $(1)/ +endif endef $(eval $(call BuildPackage,wifi-scripts)) diff --git a/package/network/config/wifi-scripts/files-ucode/lib/netifd/wireless/mac80211.sh b/package/network/config/wifi-scripts/files-ucode/lib/netifd/wireless/mac80211.sh new file mode 100755 index 00000000000000..8b55d01e7a8b51 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/lib/netifd/wireless/mac80211.sh @@ -0,0 +1,350 @@ +#!/usr/bin/ucode + +'use strict'; + +import { set_default, log } from 'wifi.common'; +import { validate, dump_options } from 'wifi.validate'; +import * as supplicant from 'wifi.supplicant'; +import * as hostapd from 'wifi.hostapd'; +import * as netifd from 'wifi.netifd'; +import * as iface from 'wifi.iface'; +import * as fs from 'fs'; + +global.radio = ARGV[2]; + +const mesh_param_list = [ + "mesh_retry_timeout", "mesh_confirm_timeout", "mesh_holding_timeout", "mesh_max_peer_links", + "mesh_max_retries", "mesh_ttl", "mesh_element_ttl", "mesh_hwmp_max_preq_retries", + "mesh_path_refresh_time", "mesh_min_discovery_timeout", "mesh_hwmp_active_path_timeout", + "mesh_hwmp_preq_min_interval", "mesh_hwmp_net_diameter_traversal_time", "mesh_hwmp_rootmode", + "mesh_hwmp_rann_interval", "mesh_gate_announcements", "mesh_sync_offset_max_neighor", + "mesh_rssi_threshold", "mesh_hwmp_active_path_to_root_timeout", "mesh_hwmp_root_interval", + "mesh_hwmp_confirmation_interval", "mesh_awake_window", "mesh_plink_timeout", + "mesh_auto_open_plinks", "mesh_fwding", "mesh_power_mode" +]; + +function phy_suffix(radio, sep) { + if (radio == null || radio < 0) + return ""; + return sep + radio; +} + +function reset_config(phy, radio) { + let name = phy + phy_suffix(radio, "."); + let prev_config = `/var/run/hostapd-${name}.conf`; + + global.ubus.call('hostapd', 'config_set', { phy, radio, config: '', prev_config }); + global.ubus.call('wpa_supplicant', 'config_set', { phy, radio, config: []}); + + name = phy + phy_suffix(radio, ":"); + system(`ucode /usr/share/hostap/wdev.uc ${name} set_config '{}'`); +} + +function phy_filename(phy, name) { + return `/sys/class/ieee80211/${phy}/${name}`; +} + +function phy_file(phy, name) { + return fs.readfile(phy_filename(phy, name)); +} + +function phy_index(phy) { + return +phy_file(phy, "index"); +} + +function phy_path_match(phy, path) { + let phy_path = fs.realpath(phy_filename(phy, "device")); + return substr(phy_path, -length(path)) == path; +} + +function find_phy_by_path(phys, path) { + if (!path) + return null; + + path = split(path, "+"); + phys = filter(phys, (phy) => phy_path_match(phy, path[0])); + phys = sort(phys, (a, b) => phy_index(a) - phy_index(b)); + + return phys[+path[1]]; +} + +function find_phy_by_macaddr(phys, macaddr) { + macaddr = lc(macaddr); + return filter(phys, (phy) => phy_file(phy, "macaddr") == macaddr)[0]; +} + +function find_phy_by_name(phys, name) { + return index(phys, name) < 0 ? null : name; +} + +function find_phy(config) { + let phys = fs.lsdir("/sys/class/ieee80211"); + + return find_phy_by_path(phys, config.path) ?? + find_phy_by_macaddr(phys, config.macaddr) ?? + find_phy_by_name(phys, config.phy); +} + +function get_channel_frequency(band, channel) { + if (channel < 1) + return null; + + switch (band) { + case '2g': + if (channel == 14) + return 2484; + return 2407 + channel * 5; + case '5g': + if (channel >= 182 && channel <= 196) + return 4000 + channel * 5; + return 5000 + channel * 5; + case '6g': + if (channel == 2) + return 5935; + return 5950 + channel * 5; + case '60g': + return 56160 + channel * 2160; + } +} + +function setup_phy(phy, config, data) { + if (config.channel == "auto") + config.channel = 0; + config.channel = +config.channel; + config.frequency = get_channel_frequency(config.band, config.channel); + + if (config.country) { + log(`Setting country code to ${config.country}`); + system(`iw reg set ${config.country}`); + } + + set_default(config, 'rxantenna', 0xffffffff); + set_default(config, 'txantenna', 0xffffffff); + + if (config.txantenna == 'all') + config.txantenna = 0xffffffff; + if (config.rxantenna == 'all') + config.rxantenna = 0xffffffff; + + if (config.txantenna != data?.txantenna || config.rxantenna != data?.rxantenna) + reset_config(phy, config.radio); + + netifd.set_data({ + phy, + radio: config.radio, + txantenna: config.txantenna, + rxantenna: config.rxantenna + }); + + if (config.txpower) + config.txpower = 'fixed ' + config.txpower + '00'; + else + config.txpower = 'auto'; + + log(`Configuring '${phy}' txantenna: ${config.txantenna}, rxantenna: ${config.rxantenna} distance: ${config.distance}`); + system(`iw phy ${phy} set antenna ${config.txantenna} ${config.rxantenna}`); + system(`iw phy ${phy} set distance ${config.distance}`); + + if (config.frag) + system(`iw phy ${phy} set frag ${frag}`); + if (config.rts) + system(`iw phy ${phy} set rts ${rts}`); +} + +function iw_htmode(config) { + let suffix = substr(config.htmode, 3); + if (suffix == "40+" || suffix == "40-") + return "HT" + suffix; + + switch (config.htmode ?? "NONE") { + case "HT20": + case "VHT20": + case "HE20": + case "EHT20": + return "HT20"; + case "VHT80": + case "HE80": + case "EHT80": + case "HE160": + case "EHT160": + case "EHT320": + return "80MHZ"; + case "NONE": + case "NOHT": + return "NOHT"; + } + + if (substr(config.htmode, 2) == "40") { + switch (config.band) { + case "2g": + if (+config.channel < 7) + return "HT40+"; + else + return "HT40-"; + default: + return ((+config.channel / 4) % 2) ? "HT40+" : "HT40-"; + } + } + + return null; +} + +function config_add(config, name, val) { + if (val != null) + config[name] = val; +} + +function config_add_mesh_params(config, data) { + for (let param in mesh_param_list) + config_add(config, param, data[param]); +} + +function setup() { + let data = json(ARGV[3]); + + data.phy = find_phy(data.config); + if (!data.phy) { + log('Bug: PHY is undefined for device'); + netifd.set_retry(false); + return 1; + } + data.phy_suffix = phy_suffix(data.config.radio, ":"); + data.vif_phy_suffix = phy_suffix(data.config.radio, "."); + data.ifname_prefix = data.config.ifname_prefix; + if (!data.ifname_prefix) + data.ifname_prefix = data.phy + data.vif_phy_suffix + "-"; + let active_ifnames = []; + + log('Starting'); + + validate('device', data.config); + setup_phy(data.phy, data.config, data.data); + + let supplicant_mesh; + let has_ap = false; + let idx = {}; + let supplicant_data = []; + let wdev_data = {}; + + for (let k, v in data.interfaces) { + let mode = v.config.mode; + idx[mode] ??= 0; + let mode_idx = idx[mode]++; + + if (!v.config.ifname) + v.config.ifname = data.ifname_prefix + mode + mode_idx; + push(active_ifnames, v.config.ifname); + + if (v.config.encryption == 'owe' && v.config.owe_transition) { + mode_idx = idx[mode]++; + v.config.owe_transition_ifname = data.ifname_prefix + mode + mode_idx; + push(active_ifnames, v.config.ifname); + } + + switch (mode) { + case 'ap': + has_ap = true; + // fallthrough + case 'sta': + case 'adhoc': + case 'mesh': + if (mode != "ap") + data.config.noscan = true; + validate('iface', v.config); + iface.prepare(v.config, data.phy + data.phy_suffix, data.config.num_global_macaddr); + netifd.set_vif(k, v.config.ifname); + break; + } + + switch (mode) { + case 'adhoc': + if (config.frequency && !v.config.wpa) + break; + // fallthrough + case 'mesh': + supplicant_mesh ??= !system("wpa_supplicant -vmesh"); + if (mode == "mesh" && !supplicant_mesh) + break; + // fallthrough + case 'sta': + let config = supplicant.generate(supplicant_data, data, v); + if (mode == "mesh") + config_add_mesh_params(config, v.config); + continue; + case 'monitor': + break; + default: + continue; + } + + // fallback to wdev setup + let config = { + mode, + ssid: v.config.ssid, + }; + + if (!v.config.default_macaddr) + config.macaddr = v.config.macaddr; + + config_add(config, "htmode", wdev_htmode(data.config)); + if (mode != "monitor") { + config_add(config, "basic-rates", supplicant.ratelist(data.config.basic_rate)); + config_add(config, "mcast-rate", supplicant.ratestr(v.config.mcast_rate)); + config_add(config, "beacon-interval", data.config.beacon_int); + if (mode == "mesh") { + config_add(config, "ssid", v.config.mesh_id); + config_add_mesh_params(config, v.config); + } + } + + wdev_data[v.config.ifname] = config; + } + + if (length(supplicant_data) > 0) + supplicant.setup(supplicant_data, data); + + if (has_ap) + hostapd.setup(data); + + system(`ucode /usr/share/hostap/wdev.uc ${data.phy}${data.phy_suffix} set_config '${printf("%J", wdev_data)}' ${join(' ', active_ifnames)}`); + + if (length(supplicant_data) > 0) + supplicant.start(data); + + netifd.set_up(); + + return 0 +} + +function teardown() { + let data = json(ARGV[3]); + + if (!data.data?.phy) { + log('Bug: PHY is undefined for device'); + return 1; + } + + log(`Tearing down ${data.data.phy}`); + + reset_config(data.data.phy, data.data.radio); + + return 0; +} + +let ret = 1; + +switch(ARGV[1]) { +case 'dump': + ret = dump_options(); + break; + +case 'setup': + ret = setup(); + break; + +case 'teardown': + ret = teardown(); + break; +} + +exit(ret); diff --git a/package/network/config/wifi-scripts/files-ucode/usr/bin/iwinfo b/package/network/config/wifi-scripts/files-ucode/usr/bin/iwinfo new file mode 100755 index 00000000000000..01285eb385d6de --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/bin/iwinfo @@ -0,0 +1,156 @@ +#!/usr/bin/ucode + +'use strict'; + +import * as iwinfo from 'iwinfo'; + +function print_assoclist(stations) { + for (let mac, station in stations) { + printf(`${station.mac} ${station.signal} dBm / ${station.noise} dBm (SNR ${station.snr}) ${station.inactive_time} ms ago\n`); + for (let k in [ 'rx', 'tx' ]) { + let bitrate = station[k]; + let flags = join(', ', bitrate.flags); + + printf(`\t${uc(k)}: ${bitrate.bitrate} MBit/s`); + if (length(bitrate.flags)) + printf(', %s', flags); + printf('%10d Pkts.\n', bitrate.packets); + } + printf(`\texpected throughput: ${station.expected_throughput}\n\n`); + } +} + +function print_countrylist(list) { + for (let k, v in list.countries) + printf(`${k == list.active ? '*' : ' '} ${k} "${v}"\n`); +} + +function print_freqlist(channels) { + for (let channel in channels) { + printf(`${channel.active ? '*' : ' '} ${channel.freq} GHz (Band: ${channel.band} GHz, Channel ${channel.channel})`); + if (length(channel.flags)) + printf(` [${join(', ', channel.flags)}]`); + printf('\n'); + } +} + +function print_htmodelist(htmode) { + printf('%s\n', join(' ', htmode)); +} + +function print_info(list) { + let padding = ' '; + + for (let bss in list) { + printf(`${bss.iface} ESSID: "${bss.ssid}"\n`); + printf(`${padding}Access Point: ${bss.mac}\n`); + printf(`${padding}Mode: ${bss.mode} Channel: ${bss.channel} (${bss.freq} GHz) HT Mode: ${bss.htmode}\n`); + printf(`${padding}Center Channel 1: ${bss.center_freq1} 2: ${bss.center_freq2}\n`); + printf(`${padding}Tx-Power: ${bss.txpower} dBm Link Quality: ${bss.quality}/70\n`); + printf(`${padding}Signal: ${bss.signal} Noise: ${bss.noise}\n`); + printf(`${padding}Bit Rate: ${bss.bitrate ?? 'unknown'} MBit/s\n`); + printf(`${padding}Encryption: ${bss.encryption}\n`); + printf(`${padding}Type: nl80211 HW Mode(s): 802.11${bss.hwmode}\n`); + printf(`${padding}Hardware: ${bss.hw_type} [${bss.hw_id}]\n`); + printf(`${padding}TX power offset: ${bss.power_offset}\n`); + printf(`${padding}Channel offset: ${bss.channel_offset}\n`); + printf(`${padding}Supports VAPs: ${bss.vaps} PHY name: ${bss.phy}\n`); + if (bss.owe_transition_ifname) + printf(`${padding}OWE partner: ${bss.owe_transition_ifname}\n`); + printf('\n'); + } + return 0; +} + +function print_scan(cells) { + let idx = 1; + + for (let cell in cells) { + printf('Cell %02d - Address: %s\n', idx++, cell.bssid); + printf('\t Mode: %s Frequency: %s GHz Band: %s GHz Channel: %d\n', cell.mode, cell.frequency, cell.band, cell.channel); + printf('\t Signal: %d dBm Quality: %2d/70\n', cell.dbm, cell.quality); + + if (!length(cell.crypto.key_mgmt)) + printf('\t Encryption: NONE\n'); + else + printf('\t Encryption: %s (%s)\n', join(' / ', cell.crypto.key_mgmt), join(' / ', cell.crypto.pair)); + + if (cell.ht) { + printf('\t HT Operation:\n'); + printf('\t\tPrimary Channel: %d\n', cell.ht.primary_channel); + printf('\t\tSecondary Channel Offset: %s\n', cell.ht.secondary_chan_off); + printf('\t\tChannel Width: %s\n', cell.ht.chan_width); + } + + if (cell.vht) { + printf('\t VHT Operation:\n'); + printf('\t\tCenter Frequency 1: %d\n', cell.vht.center_chan_1); + printf('\t\tCenter Frequency 2: %s\n', cell.vht.center_chan_2); + printf('\t\tChannel Width: %s\n', cell.vht.chan_width); + } + + printf('\n'); + } +} + +function print_txpowerlist(list) { + for (let power in list) + printf('%s %2d dbm (%4d mW)\n', power.active ? '*' : ' ', power.dbm, power.mw); +} + +let pretty = true; +if (ARGV[0] == '-j') { + pretty = false; + shift(ARGV); +} + +if (!length(ARGV)) { + let info = iwinfo.info(); + if (pretty) + print_info(info); + else + printf('%.J\n', info); + return 0; +} + +const commands = { + assoclist: [ iwinfo.assoclist, print_assoclist ], + countrylist: [ iwinfo.countrylist, print_countrylist ], + freqlist: [ iwinfo.freqlist, print_freqlist ], + htmodelist: [ iwinfo.htmodelist, print_htmodelist ], + info: [ iwinfo.info, print_info ], + scan: [ iwinfo.scan, print_scan ], + txpowerlist: [ iwinfo.txpowerlist, print_txpowerlist ], +}; + +if (length(ARGV) == 2 && iwinfo.ifaces[ARGV[0]]) + for (let cmd, cb in commands) + if (substr(cmd, 0, length(ARGV[1])) == ARGV[1]) { + let ret = cb[0](ARGV[0]); + + if (pretty) + cb[1](ret); + else + printf('%.J\n', ret); + return 0; + } + +switch(ARGV[0]) { +case 'phy': + printf('%.J\n', iwinfo.phys); + return 0; + +case 'iface': + printf('%.J\n', iwinfo.ifaces); + return 0; +} + +printf('Usage:\n' + + '\tiwinfo info\n' + + '\tiwinfo scan\n' + + '\tiwinfo txpowerlist\n' + + '\tiwinfo freqlist\n' + + '\tiwinfo assoclist\n' + + '\tiwinfo countrylist\n' + + '\tiwinfo htmodelist\n' + + '\tiwinfo phyname
\n'); diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/iso3166.json b/package/network/config/wifi-scripts/files-ucode/usr/share/iso3166.json new file mode 100644 index 00000000000000..ecd0b653839855 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/iso3166.json @@ -0,0 +1,249 @@ +{ + "00": "World", + "AD": "Andorra", + "AE": "United Arab Emirates", + "AF": "Afghanistan", + "AG": "Antigua and Barbuda", + "AI": "Anguilla", + "AL": "Albania", + "AM": "Armenia", + "AN": "Netherlands Antilles", + "AO": "Angola", + "AQ": "Antarctica", + "AR": "Argentina", + "AS": "American Samoa", + "AT": "Austria", + "AU": "Australia", + "AW": "Aruba", + "AX": "Aland Islands", + "AZ": "Azerbaijan", + "BA": "Bosnia and Herzegovina", + "BB": "Barbados", + "BD": "Bangladesh", + "BE": "Belgium", + "BF": "Burkina Faso", + "BG": "Bulgaria", + "BH": "Bahrain", + "BI": "Burundi", + "BJ": "Benin", + "BL": "Saint Barthelemy", + "BM": "Bermuda", + "BN": "Brunei Darussalam", + "BO": "Bolivia", + "BR": "Brazil", + "BS": "Bahamas", + "BT": "Bhutan", + "BV": "Bouvet Island", + "BW": "Botswana", + "BY": "Belarus", + "BZ": "Belize", + "CA": "Canada", + "CC": "Cocos (Keeling) Islands", + "CD": "Congo", + "CF": "Central African Republic", + "CG": "Congo", + "CH": "Switzerland", + "CI": "Cote d'Ivoire", + "CK": "Cook Islands", + "CL": "Chile", + "CM": "Cameroon", + "CN": "China", + "CO": "Colombia", + "CR": "Costa Rica", + "CU": "Cuba", + "CV": "Cape Verde", + "CX": "Christmas Island", + "CY": "Cyprus", + "CZ": "Czech Republic", + "DE": "Germany", + "DJ": "Djibouti", + "DK": "Denmark", + "DM": "Dominica", + "DO": "Dominican Republic", + "DZ": "Algeria", + "EC": "Ecuador", + "EE": "Estonia", + "EG": "Egypt", + "EH": "Western Sahara", + "ER": "Eritrea", + "ES": "Spain", + "ET": "Ethiopia", + "FI": "Finland", + "FJ": "Fiji", + "FK": "Falkland Islands", + "FM": "Micronesia", + "FO": "Faroe Islands", + "FR": "France", + "GA": "Gabon", + "GB": "United Kingdom", + "GD": "Grenada", + "GE": "Georgia", + "GF": "French Guiana", + "GG": "Guernsey", + "GH": "Ghana", + "GI": "Gibraltar", + "GL": "Greenland", + "GM": "Gambia", + "GN": "Guinea", + "GP": "Guadeloupe", + "GQ": "Equatorial Guinea", + "GR": "Greece", + "GS": "South Georgia", + "GT": "Guatemala", + "GU": "Guam", + "GW": "Guinea-Bissau", + "GY": "Guyana", + "HK": "Hong Kong", + "HM": "Heard and McDonald Islands", + "HN": "Honduras", + "HR": "Croatia", + "HT": "Haiti", + "HU": "Hungary", + "ID": "Indonesia", + "IE": "Ireland", + "IL": "Israel", + "IM": "Isle of Man", + "IN": "India", + "IO": "Chagos Islands", + "IQ": "Iraq", + "IR": "Iran", + "IS": "Iceland", + "IT": "Italy", + "JE": "Jersey", + "JM": "Jamaica", + "JO": "Jordan", + "JP": "Japan", + "KE": "Kenya", + "KG": "Kyrgyzstan", + "KH": "Cambodia", + "KI": "Kiribati", + "KM": "Comoros", + "KN": "Saint Kitts and Nevis", + "KP": "North Korea", + "KR": "South Korea", + "KW": "Kuwait", + "KY": "Cayman Islands", + "KZ": "Kazakhstan", + "LA": "Laos", + "LB": "Lebanon", + "LC": "Saint Lucia", + "LI": "Liechtenstein", + "LK": "Sri Lanka", + "LR": "Liberia", + "LS": "Lesotho", + "LT": "Lithuania", + "LU": "Luxembourg", + "LV": "Latvia", + "LY": "Libyan Arab Jamahiriya", + "MA": "Morocco", + "MC": "Monaco", + "MD": "Moldova", + "ME": "Montenegro", + "MF": "Saint Martin (French part)", + "MG": "Madagascar", + "MH": "Marshall Islands", + "MK": "Macedonia", + "ML": "Mali", + "MM": "Myanmar", + "MN": "Mongolia", + "MO": "Macao", + "MP": "Northern Mariana Islands", + "MQ": "Martinique", + "MR": "Mauritania", + "MS": "Montserrat", + "MT": "Malta", + "MU": "Mauritius", + "MV": "Maldives", + "MW": "Malawi", + "MX": "Mexico", + "MY": "Malaysia", + "MZ": "Mozambique", + "NA": "Namibia", + "NC": "New Caledonia", + "NE": "Niger", + "NF": "Norfolk Island", + "NG": "Nigeria", + "NI": "Nicaragua", + "NL": "Netherlands", + "NO": "Norway", + "NP": "Nepal", + "NR": "Nauru", + "NU": "Niue", + "NZ": "New Zealand", + "OM": "Oman", + "PA": "Panama", + "PE": "Peru", + "PF": "French Polynesia", + "PG": "Papua New Guinea", + "PH": "Philippines", + "PK": "Pakistan", + "PL": "Poland", + "PM": "Saint Pierre and Miquelon", + "PN": "Pitcairn", + "PR": "Puerto Rico", + "PS": "Palestinian Territory", + "PT": "Portugal", + "PW": "Palau", + "PY": "Paraguay", + "QA": "Qatar", + "RE": "Reunion", + "RO": "Romania", + "RS": "Serbia", + "RU": "Russian Federation", + "RW": "Rwanda", + "SA": "Saudi Arabia", + "SB": "Solomon Islands", + "SC": "Seychelles", + "SD": "Sudan", + "SE": "Sweden", + "SG": "Singapore", + "SH": "St. Helena and Dependencies", + "SI": "Slovenia", + "SJ": "Svalbard and Jan Mayen", + "SK": "Slovakia", + "SL": "Sierra Leone", + "SM": "San Marino", + "SN": "Senegal", + "SO": "Somalia", + "SR": "Suriname", + "ST": "Sao Tome and Principe", + "SV": "El Salvador", + "SY": "Syrian Arab Republic", + "SZ": "Swaziland", + "TC": "Turks and Caicos Islands", + "TD": "Chad", + "TF": "French Southern Territories", + "TG": "Togo", + "TH": "Thailand", + "TJ": "Tajikistan", + "TK": "Tokelau", + "TL": "Timor-Leste", + "TM": "Turkmenistan", + "TN": "Tunisia", + "TO": "Tonga", + "TR": "Turkey", + "TT": "Trinidad and Tobago", + "TV": "Tuvalu", + "TW": "Taiwan", + "TZ": "Tanzania", + "UA": "Ukraine", + "UG": "Uganda", + "UM": "U.S. Minor Outlying Islands", + "US": "United States", + "UY": "Uruguay", + "UZ": "Uzbekistan", + "VA": "Vatican City State", + "VC": "St. Vincent and Grenadines", + "VE": "Venezuela", + "VG": "Virgin Islands, British", + "VI": "Virgin Islands, U.S.", + "VN": "Viet Nam", + "VU": "Vanuatu", + "WF": "Wallis and Futuna", + "WS": "Samoa", + "YE": "Yemen", + "YT": "Mayotte", + "ZA": "South Africa", + "ZM": "Zambia", + "ZW": "Zimbabwe" +} diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-device.json b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-device.json new file mode 100644 index 00000000000000..0588401c99e639 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-device.json @@ -0,0 +1,721 @@ +{ + "$id": "https://openwrt.org/wifi.device.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "OpenWrt WiFi Device Schema", + "type": "object", + "properties": { + "acs_chan_bias": { + "description": "Can be used to increase (or decrease) the likelihood of a specific channel to be selected by the ACS algorithm", + "type": "string" + }, + "acs_exclude_dfs": { + "description": "Exclude DFS channels from ACS", + "type": "boolean", + "default": false + }, + "airtime_mode": { + "description": "Set the airtime policy operating mode", + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 3 + }, + "antenna_gain": { + "description": "Reduction in antenna gain from regulatory maximum in dBi", + "type": "number", + "default": 0 + }, + "assoc_sa_query_max_timeout": { + "description": "Association SA Query maximum timeout", + "type": "number" + }, + "assoc_sa_query_retry_timeout": { + "description": "Association SA Query retry timeout", + "type": "number" + }, + "auth_cache": { + "type": "alias", + "default": "okc" + }, + "background_radar": { + "type": "alias", + "default": "enable_background_radar" + }, + "band": { + "description": "The wireless band thatthe radio shall operate on", + "type": "string", + "enum": [ + "2g", + "5g", + "6g", + "60g" + ] + }, + "basic_rate": { + "type": "alias", + "default": "basic_rates" + }, + "basic_rates": { + "description": "Set the supported basic rates. Each basic_rate is measured in kb/s. This option only has an effect on ap and adhoc wifi-ifaces. ", + "type": "array", + "items": { + "type": "number" + } + }, + "beacon_int": { + "description": "Set the beacon interval. This is the time interval between beacon frames, measured in units of 1.024 ms. hostapd permits this to be set between 15 and 65535. This option only has an effect on ap and adhoc wifi-ifaces", + "type": "number", + "default": 100, + "minimum": 15, + "maximum": 65535 + }, + "beacon_rate": { + "description": "Beacon frame TX rate configuration", + "type": "string" + }, + "beamformee_antennas": { + "description": "Beamformee antenna override", + "type": "number", + "default": 4 + }, + "beamformer_antennas": { + "description": "Beamformer antenna override", + "type": "number", + "default": 4 + }, + "bssid": { + "description": "Overrides the MAC address used for the Wi-Fi interface. Warning: if the MAC address specified is a multicast address, this override will fail silently. To avoid this problem, ensure that the mac address specified is a valid unicast mac address", + "type": "string" + }, + "cell_density": { + "description": "Configures data rates based on the coverage cell density. Normal configures basic rates to 6, 12, 24 Mbps if legacy_rates is 0, else to 5.5, 11 Mbps. High configures basic rates to 12, 24 Mbps if legacy_rates is 0, else to the 11 Mbps rate. Very High configures 24 Mbps as the basic rate. Supported rates lower than the minimum basic rate are not offered. The basic_rate and supported_rates options overrides this option. 0 = Disabled, 1 = Normal, 2 = High, 3 = Very High", + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 3 + }, + "chanbw": { + "description": "Specifies a narrow channel width in MHz, possible values are: 5, 10, 20", + "type": "number", + "enum": [ 5, 10, 20 ] + }, + "channel": { + "description": "Specifies the wireless channel. “auto” defaults to the lowest available channel, or utilizes the ACS algorithm depending on hardware/driver support", + "type": "string" + }, + "channels": { + "type": "alias", + "default": "chanlist" + }, + "channel_list": { + "type": "alias", + "default": "chanlist" + }, + "chanlist": { + "description": "Use specific channels, when channel is in “auto” mode. This option allows hostapd to select one of the provided channels when a channel should be automatically selected. Channels can be provided as range using hyphen ('-') or individual channels can be specified by space (' ') separated values", + "type": "array", + "items": { + "type": "number" + } + }, + "country": { + "type": "alias", + "default": "country_code" + }, + "country3": { + "description": "The third octet of the Country String (dot11CountryString)", + "type": "string" + }, + "country_code": { + "description": "Specifies the country code, affects the available channels and transmission powers. For types mac80211 and broadcom a two letter country code is used (EN or DE). The madwifi driver expects a numeric code", + "type": "string" + }, + "country_ie": { + "type": "alias", + "default": "ieee80211d" + }, + "disabled": { + "description": "When set to 1, wireless network is disabled", + "type": "boolean", + "default": false + }, + "distance": { + "description": "Distance between the ap and the furthest client in meters", + "type": "number", + "default": 0 + }, + "doth": { + "type": "alias", + "default": "ieee80211h" + }, + "dsss_cck_40": { + "description": "DSSS/CCK Mode in 40 MHz allowed in Beacon, Measurement Pilot and Probe Response frames", + "type": "boolean", + "default": true + }, + "enable_background_radar": { + "description": "This feature allows CAC to be run on dedicated radio RF chains", + "type": "boolean" + }, + "frag": { + "description": "Fragmentation threshold", + "type": "number" + }, + "greenfield": { + "description": "Receive Greenfield - treats pre-80211n traffic as noise", + "type": "boolean", + "default": false + }, + "he_bss_color": { + "description": "BSS color to be announced", + "type": "number", + "minimum": 1, + "maximum": 128, + "default": 128 + }, + "he_bss_color_enabled": { + "description": "Enable BSS color", + "type": "boolean", + "default": true + }, + "he_default_pe_duration": { + "description": "The duration of PE field in an HE PPDU in us", + "type": "number", + "default": 4, + "enum": [ 4, 8, 12, 16 ] + }, + "he_mu_beamformer": { + "description": "HE multiple user beamformer support", + "type": "boolean", + "default": true + }, + "he_mu_edca_ac_be_aci": { + "type": "number", + "default": 0 + }, + "he_mu_edca_ac_be_aifsn": { + "type": "number", + "default": 8 + }, + "he_mu_edca_ac_be_ecwmax": { + "type": "number", + "default": 10 + }, + "he_mu_edca_ac_be_ecwmin": { + "type": "number", + "default": 9 + }, + "he_mu_edca_ac_be_timer": { + "type": "number", + "default": 255 + }, + "he_mu_edca_ac_bk_aci": { + "type": "number", + "default": 1 + }, + "he_mu_edca_ac_bk_aifsn": { + "type": "number", + "default": 15 + }, + "he_mu_edca_ac_bk_ecwmax": { + "type": "number", + "default": 10 + }, + "he_mu_edca_ac_bk_ecwmin": { + "type": "number", + "default": 9 + }, + "he_mu_edca_ac_bk_timer": { + "type": "number", + "default": 255 + }, + "he_mu_edca_ac_vi_aci": { + "type": "number", + "default": 2 + }, + "he_mu_edca_ac_vi_aifsn": { + "type": "number", + "default": 5 + }, + "he_mu_edca_ac_vi_ecwmax": { + "type": "number", + "default": 7 + }, + "he_mu_edca_ac_vi_ecwmin": { + "type": "number", + "default": 5 + }, + "he_mu_edca_ac_vi_timer": { + "type": "number", + "default": 255 + }, + "he_mu_edca_ac_vo_aci": { + "type": "number", + "default": 3 + }, + "he_mu_edca_ac_vo_aifsn": { + "type": "number", + "default": 5 + }, + "he_mu_edca_ac_vo_ecwmax": { + "type": "number", + "default": 7 + }, + "he_mu_edca_ac_vo_ecwmin": { + "type": "number", + "default": 5 + }, + "he_mu_edca_ac_vo_timer": { + "type": "number", + "default": 255 + }, + "he_mu_edca_qos_info_param_count": { + "type": "number", + "default": 0 + }, + "he_mu_edca_qos_info_q_ack": { + "type": "number", + "default": 0 + }, + "he_mu_edca_qos_info_queue_request": { + "type": "number", + "default": 0 + }, + "he_mu_edca_qos_info_txop_request": { + "type": "number", + "default": 0 + }, + "he_oper_centr_freq_seg0_idx": { + "description": "", + "type": "string" + }, + "he_oper_chwidth": { + "description": "", + "type": "string" + }, + "he_6ghz_reg_pwr_type": { + "description": "This config is to set the 6 GHz Access Point type.", + "type": "number", + "minimum": 0, + "maximum": 4, + "default": 0 + }, + "he_rts_threshold": { + "description": "Duration of STA transmission", + "type": "number", + "default": 1023 + }, + "he_spr_non_srg_obss_pd_max_offset": { + "description": "", + "type": "number" + }, + "he_spr_psr_enabled": { + "description": "", + "type": "boolean", + "default": false + }, + "he_spr_sr_control": { + "description": "", + "type": "number", + "default": 3 + }, + "he_su_beamformee": { + "description": "", + "type": "boolean", + "default": true + }, + "he_su_beamformer": { + "description": "", + "type": "boolean", + "default": true + }, + "he_twt_required": { + "description": "", + "type": "boolean", + "default": false + }, + "hostapd_options": { + "type": "array", + "items": { + "type": "string" + } + }, + "ht_coex": { + "description": "Disable honoring 40 MHz intolerance in coexistence flags of stations", + "type": "boolean", + "default": false + }, + "htc_vht": { + "description": "STA supports receiving a VHT variant HT Control field", + "type": "boolean", + "default": true + }, + "htmode": { + "description": "Specifies the high throughput mode", + "type": "string", + "enum": [ + "NOHT", "HT20", "HT40-", "HT40+", "HT40", + "VHT20", "VHT40", "VHT80", "VHT160", + "HE20", "HE40", "HE80", "HE160", + "EHT20", "EHT40", "EHT80", "EHT160", "EHT320" ] + }, + "hwmode": { + "type": "alias", + "default": "hw_mode" + }, + "hw_mode": { + "description": "Legacy way, use the band property instead", + "type": "string", + "enum": [ "11a", "11b", "11g", "11ad" ] + }, + "ieee80211d": { + "description": "Enables IEEE 802.11d country IE (information element) advertisement in beacon and probe response frames. This IE contains the country code and channel/power map. Requires country", + "type": "boolean", + "default": true + }, + "ieee80211h": { + "description": "This enables radar detection and DFS support", + "type": "boolean", + "default": true + }, + "ieee80211w": { + "description": "Whether management frame protection (MFP) is enabled", + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "ieee80211w_max_timeout": { + "type": "alias", + "default": "assoc_sa_query_max_timeout" + }, + "ieee80211w_mgmt_cipher": { + "description": "Cypher used for MFP", + "type": "string" + }, + "ieee80211w_retry_timeout": { + "type": "alias", + "default": "assoc_sa_query_retry_timeout" + }, + "ifname_prefix": { + "description": "Default ifname prefix for this radio", + "type": "string" + }, + "iface_max_num_sta": { + "description": "Limits the maximum allowed number of associated clients", + "type": "number" + }, + "ldpc": { + "description": " LDPC (Low-Density Parity-Check code) capability ", + "type": "boolean", + "default": true + }, + "legacy_rates": { + "description": "Allow legacy 802.11b data rates (used by cell_density)", + "type": "boolean", + "default": false + }, + "local_pwr_constraint": { + "description": "Add Power Constraint element to Beacon and Probe Response frame", + "type": "number", + "minimum": 0, + "maximum": 255 + }, + "log_80211": { + "description": "Enable IEEE 802.11 logging", + "type": "boolean", + "default": true + }, + "log_8021x": { + "description": "Enable IEEE 802.1X logging", + "type": "boolean", + "default": true + }, + "log_driver": { + "description": "Enable driver interface logging", + "type": "boolean", + "default": true + }, + "log_iapp": { + "description": "Enable iapp logging", + "type": "boolean", + "default": true + }, + "log_level": { + "description": "Log severity", + "type": "number", + "default": 2, + "minimum": 0, + "maximum": 4 + }, + "log_mlme": { + "description": "Enable MLME logging", + "type": "boolean", + "default": true + }, + "log_radius": { + "description": "Enable Radius logging", + "type": "boolean", + "default": true + }, + "log_wpa": { + "description": "Enable WPA logging", + "type": "boolean", + "default": true + }, + "logger_stdout": { + "description": "Log to stdout", + "type": "boolean", + "default": true + }, + "logger_stdout_level": { + "description": "Log severity", + "type": "number", + "default": 2, + "minimum": 0, + "maximum": 4 + }, + "logger_syslog": { + "description": "Log to syslog", + "type": "boolean", + "default": true + }, + "logger_syslog_level": { + "description": "Syslog severity", + "type": "number", + "default": 2, + "minimum": 0, + "maximum": 4 + }, + "macaddr": { + "type": "alias", + "default": "bssid" + }, + "max_amsdu": { + "description": "Maximum A-MSDU length of 7935 octects (3839 octets if option set to 0)", + "type": "boolean", + "default": true + }, + "maxassoc": { + "type": "alias", + "default": "iface_max_num_sta" + }, + "mbssid": { + "description": "Multiple BSSID Advertisement in IEEE 802.11ax IEEE Std 802.11ax-2021 added a feature where instead of multiple interfaces on a common radio transmitting individual Beacon frames, those interfaces can form a set with a common Beacon frame transmitted for all Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection", + "type": "number", + "default": 0, + "minimum": 0, + "maximum": 2 + }, + "min_tx_power": { + "description": "Set minimum permitted max TX power (in dBm) for ACS and DFS channel selection", + "type": "number", + "default": 0 + }, + "mu_beamformee": { + "description": "Supports operation as an MU beamformee", + "type": "boolean", + "default": true + }, + "mu_beamformer": { + "description": " Supports operation as an MU beamformer", + "type": "boolean", + "default": true + }, + "multiple_bssid": { + "type": "alias", + "default": "mbssid" + }, + "num_global_macaddr": { + "description": "The number of MACs that this radio can use", + "type": "number", + "default": 1 + }, + "no_probe_resp_if_max_sta": { + "description": "Do not answer probe requests if iface_max_num_sta was reached", + "type": "boolean" + }, + "noscan": { + "description": "Do not scan for overlapping BSSs in HT40+/- mode.", + "type": "boolean", + "default": false + }, + "okc": { + "description": "Enable Opportunistic Key Caching", + "type": "boolean" + }, + "path": { + "description": "Alternative to phy used to identify the device based paths in /sys/devices", + "type": "string" + }, + "radio": { + "description": "Index of the phy radio (for multi-radio PHYs)", + "type": "number", + "default": -1 + }, + "reg_power_type": { + "type": "alias", + "default": "he_6ghz_reg_pwr_type" + }, + "require_mode": { + "description": "Sets the minimum client capability level mode that connecting clients must support to be allowed to connect", + "type": "string", + "enum": [ "ht", "ac", "ax" ] + }, + "rnr_beacon": { + "description": "", + "type": "string" + }, + "rsn_preauth": { + "description": "Enable IEEE 802.11i/RSN/WPA2 pre-authentication", + "type": "boolean" + }, + "rssi_ignore_probe_request": { + "description": "Ignore Probe Request frames if RSSI is below given threshold (in dBm)", + "type": "number", + "default": 0 + }, + "rssi_reject_assoc_rssi": { + "description": "Reject STA association if RSSI is below given threshold (in dBm)", + "type": "number", + "default": 0 + }, + "rts": { + "description": "Override the RTS/CTS threshold", + "type": "number" + }, + "rts_threshold": { + "description": "RTS/CTS threshold", + "type": "number", + "minimum": -1, + "maximum": 65535 + }, + "rx_antenna_pattern": { + "description": "Rx antenna pattern does not change during the lifetime of an association", + "type": "boolean", + "default": true + }, + "rx_stbc": { + "description": "Supports reception of PPDUs using STBC", + "type": "number", + "default": 3, + "minimum": 0, + "maximum": 4 + }, + "rxantenna": { + "description": "Specifies the antenna for receiving, the value may be driver specific, usually it is 1 for the first and 2 for the second antenna. Specifying 0 enables automatic selection by the driver if supported. This option has no effect if diversity is enabled", + "type": "number" + }, + "rxldpc": { + "description": "Supports receiving LDPC coded pkts", + "type": "boolean", + "default": true + }, + "short_gi_160": { + "description": "Short GI for 160 MHz", + "type": "boolean", + "default": true + }, + "short_gi_20": { + "description": "Short GI for 20 MHz", + "type": "boolean", + "default": true + }, + "short_gi_40": { + "description": "Short GI for 40 MHz", + "type": "boolean", + "default": true + }, + "short_gi_80": { + "description": "Short GI for 80 MHz", + "type": "boolean" + }, + "spectrum_mgmt_required": { + "description": "Set Spectrum Management subfield in the Capability Information field", + "type": "boolean", + "default": false + }, + "stationary_ap": { + "description": "Stationary AP config indicates that the AP doesn't move hence location data can be considered as always up to date.", + "type": "boolean", + "default": true + }, + "su_beamformee": { + "description": "Single user beamformee", + "type": "boolean", + "default": true + }, + "su_beamformer": { + "description": "Single user beamformer", + "type": "boolean", + "default": true + }, + "supported_rates": { + "description": "Set the supported data rates. Each supported rate is measured in kb/s. This option only has an effect on ap and adhoc wifi-ifaces. This must be a superset of the rates set in basic_rate. The minimum basic rate should also be the minimum supported rate. It is recommended to use the cell_density option instead", + "type": "array", + "items": { + "type": "number" + } + }, + "tx_antenna_pattern": { + "description": "Tx antenna pattern does not change during the lifetime of an association", + "type": "boolean", + "default": true + }, + "tx_burst": { + "type": "alias", + "default": "tx_queue_data2_burst" + }, + "tx_queue_data2_burst": { + "description": "", + "type": "number" + }, + "tx_stbc": { + "description": "Transmit STBC (Space-Time Block Coding)", + "type": "boolean", + "default": true + }, + "tx_stbc_2by1": { + "description": "Supports transmission of at least 2×1 STBC", + "type": "boolean", + "default": true + }, + "txantenna": { + "description": "Specifies the antenna for transmitting, values are identical to rxantenna", + "type": "number" + }, + "txpower": { + "description": "Specifies the maximum desired transmission power in dBm. The actual txpower used depends on regulatory requirements", + "type": "number" + }, + "vht160": { + "description": "Supported channel widths. 0 == 160MHz and 80+80 MHz not supported, 1 == 160 MHz supported, 2 == 160MHz and 80+80 MHz supported", + "type": "number", + "minimum": 0, + "maximum": 2, + "default": 2 + }, + "vht_link_adapt": { + "description": "TA supports link adaptation using VHT variant HT Control field", + "type": "number", + "minimum": 0, + "maximum": 3 + }, + "vht_max_a_mpdu_len_exp": { + "description": "Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv", + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "vht_max_mpdu": { + "description": "Maximum MPDU length", + "type": "number", + "enum": [ 3895, 7991, 11454 ], + "default": 11454 + }, + "vht_txop_ps": { + "description": "VHT TXOP PS mode", + "type": "boolean", + "default": true + } + } +} diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-iface.json b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-iface.json new file mode 100644 index 00000000000000..3964098b5712dd --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-iface.json @@ -0,0 +1,1157 @@ +{ + "$id": "https://openwrt.org/wifi.iface.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "OpenWrt WiFi Interface Schema", + "type": "object", + "properties": { + "access_network_type": { + "description": "Interworking Access Network Type", + "type": "number", + "minimum": 0, + "maximum": 15 + }, + "acct_interval": { + "type": "alias", + "default": "radius_acct_interim_interval" + }, + "acct_port": { + "type": "alias", + "default": "acct_server_port" + }, + "acct_secret": { + "type": "alias", + "default": "acct_server_shared_secret" + }, + "acct_server": { + "type": "alias", + "default": "acct_server_addr" + }, + "acct_server_addr": { + "description": "RADIUS accounting server to handle client authentication", + "type": "array", + "items": { + "type": "string" + } + }, + "acct_server_port": { + "description": "RADIUS accounting port", + "type": "number", + "default": 1813 + }, + "acct_server_shared_secret": { + "description": "Shared accounting RADIUS secret", + "type": "string" + }, + "airtime_bss_limit": { + "description": "Whether the current BSS should be limited (when airtime_mode=3)", + "type": "boolean" + }, + "airtime_bss_weight": { + "description": "Per-BSS airtime weight. In multi-BSS mode, set for each BSS and hostapd will configure station weights to enforce the correct ratio between BSS weights depending on the number of active stations", + "type": "number" + }, + "airtime_sta_weight": { + "description": "Static configuration of station weights (when airtime_mode=1). Kernel default weight is 256", + "type": "array", + "items": { + "type": "string" + } + }, + "altsubject_match": { + "description": "Semicolon separated string of entries to be matched against the alternative subject name of the authentication server certificate", + "type": "array", + "items": { + "type": "string" + } + }, + "altsubject_match2": { + "type": "array" + }, + "anonymous_identity": { + "description": "Anonymous identity string for EAP", + "type": "string" + }, + "anqp_3gpp_cell_net": { + "description": "3GPP Cellular Network information", + "type": "array", + "items": { + "type": "string" + } + }, + "anqp_domain_id": { + "description": "An identifier for a set of APs in an ESS that share the same common ANQP information", + "type": "number", + "minimum": 0, + "maximum": 65535, + "default": 0 + }, + "ap_isolate": { + "description": "Isolates wireless clients from each other, only applicable in ap mode", + "type": "boolean", + "default": false + }, + "ap_max_inactivity": { + "description": "Station inactivity limit in seconds: If a station does not send anything in ap_max_inactivity seconds, an empty data frame is sent to it in order to verify whether it is still in range. If this frame is not ACKed, the station will be disassociated and then deauthenticated", + "type": "number" + }, + "ap_pin": { + "description": "Static access point PIN for WPS", + "type": "string" + }, + "ap_setup_locked": { + "description": "AP can be configured into a locked state where new WPS Registrar are not accepted", + "type": "boolean" + }, + "anqp_elem": { + "description": "Arbitrary ANQP-element configuration", + "type": "array", + "items": { + "type": "string" + } + }, + "asra": { + "description": "Additional Step Required for Access", + "type": "boolean", + "default": false + }, + "assoc_sa_query_max_timeout": { + "description": "Specifies the 802.11w Association SA Query maximum timeout.", + "type": "number", + "minimum": 1, + "maximum": 4294967295 + }, + "assoc_sa_query_retry_timeout": { + "description": "Association SA Query retry timeout", + "type": "number", + "minimum": 1, + "maximum": 4294967295 + }, + "auth": { + "description": "Defines the phase 2 (inner) authentication method, only applicable if eap_type is peap or ttl", + "type": "string" + }, + "auth_cache": { + "type": "alias", + "default": "okc" + }, + "auth_port": { + "type": "alias", + "default": "auth_server_port" + }, + "auth_secret": { + "type": "alias", + "default": "auth_server_shared_secret" + }, + "auth_server": { + "type": "alias", + "default": "auth_server_addr" + }, + "auth_server_addr": { + "description": "RADIUS authentication server to handle client authentication", + "type": "array", + "items": { + "type": "string" + } + }, + "auth_server_port": { + "description": "RADIUS authentication port", + "type": "number", + "default": 1812 + }, + "auth_server_shared_secret": { + "description": "Shared authentication RADIUS secret", + "type": "string" + }, + "basic_rate": { + "type": "array" + }, + "bss_load_update_period": { + "description": "BSS Load update period (in BUs)", + "type": "number", + "default": 60 + }, + "bss_transition": { + "description": "BSS Transition Management", + "type": "boolean" + }, + "bssid": { + "description": "Override the BSSID of the network", + "type": "string" + }, + "bssid_blacklist": { + "type": "array" + }, + "bssid_whitelist": { + "type": "array" + }, + "ca_cert": { + "description": "Specifies the path the CA certificate used for authentication", + "type": "string" + }, + "ca_cert2_usesystem": { + "type": "boolean" + }, + "ca_cert_usesystem": { + "type": "boolean" + }, + "chan_util_avg_period": { + "description": "Channel utilization averaging period (in BUs)", + "type": "number", + "default": 600 + }, + "civic": { + "description": "The content of a location civic measurement subelement", + "type": "string" + }, + "client_cert": { + "description": "File path to client certificate file (PEM/DER)", + "type": "string" + }, + "dae_client": { + "type": "alias", + "default": "radius_das_client" + }, + "dae_port": { + "type": "alias", + "default": "radius_das_port" + }, + "dae_secret": { + "type": "alias", + "default": "radius_das_secret" + }, + "default_disabled": { + "type": "alias", + "default": "disabled" + }, + "device_name": { + "description": "Primary Device Name used by WPS", + "type": "string", + "default": "OpenWrt AP" + }, + "device_type": { + "description": "Primary Device Type used by WPS", + "type": "string", + "default": "6-0050F204-1" + }, + "disabled": { + "description": "Do not bring the interface up automatically", + "type": "boolean" + }, + "disable_dgaf": { + "description": "Disable Downstream Group-Addressed Forwarding", + "type": "boolean", + "default": false + }, + "disassoc_low_ack": { + "description": "Disassociate stations based on excessive transmission failures or other indications of connection loss. This depends on the driver capabilities and may not be available with all drivers.", + "type": "boolean", + "default": true + }, + "domain_match": { + "type": "array", + "items": { + "type": "string" + } + }, + "domain_match2": { + "type": "array" + }, + "domain_name" : { + "type": "array", + "items": { + "type": "string" + } + }, + "domain_suffix_match": { + "type": "array", + "items": { + "type": "string" + } + }, + "domain_suffix_match2": { + "type": "array" + }, + "dtim_period": { + "description": "Set the DTIM (delivery traffic information message) period. There will be one DTIM per this many beacon frames. This may be set between 1 and 255. This option only has an effect on ap wifi-ifaces.", + "type": "number", + "default": 2, + "minimum": 1, + "maximum": 255 + }, + "dynamic_ownip": { + "type": "alias", + "default": "dynamic_own_ip_addr" + }, + "dynamic_own_ip_addr": { + "type": "boolean" + }, + "dynamic_vlan": { + "description": "Allow RADIUS authentication server to decide which VLAN is used for the stations", + "type": "boolean" + }, + "eap_reauth_period": { + "description": "EAP reauthentication period in seconds", + "type": "number" + }, + "eap_server": { + "description": "Use integrated EAP server instead of external RADIUS authentication server", + "type": "boolean" + }, + "eap_type": { + "type": "string" + }, + "eap_user_file": { + "description": "Path for EAP server user database", + "type": "string" + }, + "eapol_version": { + "description": "IEEE 802.1X/EAPOL version", + "type": "number", + "enum": [ 1, 2 ] + }, + "enable": { + "description": "Enable the interface", + "type": "boolean", + "default": true + }, + "encryption": { + "type": "string" + }, + "esr": { + "description": "Emergency services reachable", + "type": "boolean", + "default": false + }, + "ext_registrar": { + "description": "WPS UPnP interface", + "type": "boolean" + }, + "fils": { + "description": "Enable FILS", + "type": "boolean" + }, + "fils_dhcp": { + "description": "DHCP server for FILS HLP. Set to '*' for automatic lookup.", + "type": "string" + }, + "ft_over_ds": { + "description": "Whether to enable FT-over-DS", + "type": "boolean", + "default": false + }, + "ft_psk_generate_local": { + "description": "Whether to generate FT response locally for PSK networks. This avoids use of PMK-R1 push/pull from other APs with FT-PSK networks as the required information (PSK and other session data) is already locally available.", + "type": "boolean" + }, + "ftm_responder": { + "description": "Publish fine timing measurement (FTM) responder functionality", + "type": "boolean" + }, + "gas_address3": { + "type": "string" + }, + "hidden": { + "type": "alias", + "default": "ignore_broadcast_ssid" + }, + "hessid": { + "description": "Homogeneous ESS identifier", + "type": "string" + }, + "hostapd_bss_options": { + "description": "Additional raw options to be added", + "type": "array", + "items": { + "type": "string" + } + }, + "hs20": { + "description": "Enable Hotspot 2.0 support", + "type": "boolean" + }, + "hs20_conn_capab": { + "description": "Connection Capability", + "type": "array", + "items": { + "type": "string" + } + }, + "hs20_deauth_req_timeout": { + "description": "Deauthentication request timeout", + "type": "number", + "default": 60 + }, + "hs20_oper_friendly_name": { + "description": "Operator Friendly Name", + "type": "array", + "items": { + "type": "string" + } + }, + "hs20_operating_class": { + "description": "Operating Class Indication", + "type": "string" + }, + "hs20_t_c_filename": { + "description": "Terms and Conditions information", + "type": "string" + }, + "hs20_t_c_server_url": { + "description": "Terms and Conditions server", + "type": "string" + }, + "hs20_t_c_timestamp": { + "description": "Terms and Conditions timestamp", + "type": "string" + }, + "hs20_wan_metrics": { + "description": "WAN Metrics", + "type": "string" + }, + "identity": { + "description": "Identity string for EAP", + "type": "string" + }, + "ieee80211k": { + "description": "Enables Radio Resource Measurement (802.11k) support", + "type": "boolean", + "default": true + }, + "ieee80211r": { + "description": "Enables fast BSS transition (802.11r) support.", + "type": "boolean" + }, + "ieee80211w": { + "description": "Enables MFP (802.11w) support (0 = disabled, 1 = optional, 2 = required). Requires the 'full' version of wpad/hostapd and support from the Wi-Fi driver", + "type": "number", + "enum": [ 0, 1, 2 ], + "default": 0 + }, + "ieee80211w_max_timeout": { + "type": "alias", + "default": "assoc_sa_query_max_timeout" + }, + "ieee80211w_mgmt_cipher": { + "description": "Group Management cypher", + "type": "string" + }, + "ieee80211w_retry_timeout": { + "type": "alias", + "default": "assoc_sa_query_retry_timeout" + }, + "ifname": { + "description": "Specifies a custom name for the Wi-Fi interface, which is otherwise automatically named. Maximum length: 15 characters", + "type": "string" + }, + "ignore_broadcast_ssid": { + "description": "Disables the broadcasting of beacon frames if set to 1 and, in doing so, hides the ESSID. Where the ESSID is hidden, clients may fail to roam and airtime efficiency may be significantly reduced.", + "type": "boolean", + "default": false + }, + "internet": { + "description": "Whether the network provides connectivity to the Internet", + "type": "boolean", + "default": true + }, + "isolate": { + "type": "alias", + "default": "ap_isolate" + }, + + "iw_access_network_type": { + "type": "alias", + "default": "access_network_type" + }, + "iw_anqp_3gpp_cell_net": { + "type": "alias", + "default": "anqp_3gpp_cell_net" + }, + "iw_anqp_elem": { + "type": "alias", + "default": "anqp_elem" + }, + "iw_asra": { + "type": "alias", + "default": "asra" + }, + "iw_domain_name": { + "type": "alias", + "default": "domain_name" + }, + "iw_enabled": { + "type": "boolean", + "default": false + }, + "iw_esr": { + "type": "alias", + "default": "esr" + }, + "iw_gas_address3": { + "type": "alias", + "default": "gas_address3" + }, + "iw_hessid": { + "type": "alias", + "default": "hessid" + }, + "iw_internet": { + "type": "alias", + "default": "internet" + }, + "iw_ipaddr_type_availability": { + "type": "number" + }, + "iw_nai_realm": { + "type": "alias", + "default": "nai_realm" + }, + "iw_network_auth_type": { + "type": "alias", + "default": "network_auth_type" + }, + "iw_qos_map_set": { + "type": "alias", + "default": "qos_map_set" + }, + "roaming_consortium": { + "type": "alias", + "default": "roaming_consortium" + }, + "iw_uesa": { + "type": "alias", + "default": "uesa" + }, + "iw_venue_group": { + "type": "alias", + "default": "venue_group" + }, + "iw_venue_name": { + "type": "alias", + "default": "venue_name" + }, + "iw_venue_type": { + "type": "alias", + "default": "venue_type" + }, + "iw_venue_url": { + "type": "alias", + "default": "venue_url" + }, + "key": { + "description": "Encryption key", + "type": "string" + }, + "lci": { + "description": "The content of a LCI measurement subelement", + "type": "string" + }, + "macaddr": { + "description": "Override the BSSID of the network", + "type": "string" + }, + "macfile": { + "description": "File containing a list MACs used by the macfilter", + "type": "string" + }, + "macfilter": { + "description": "Allow/deny associations based on the clients MAC", + "type": "string", + "enum": [ "allow", "deny" ] + }, + "maclist": { + "description": "List of MACs used by the macfilter option", + "type": "array", + "items": { + "type": "string" + } + }, + "manufacturer": { + "description": "Manufacturer used by WPS", + "type": "string", + "default": "www.openwrt.org" + }, + "max_inactivity": { + "type": "alias", + "default": "ap_max_inactivity" + }, + "max_listen_int": { + "type": "alias", + "default": "max_listen_interval" + }, + "max_listen_interval": { + "description": "How many Beacon periods STAs are allowed to remain asleep", + "type": "number" + }, + "max_num_sta": { + "description": "Maximum number of stations allowed in station table", + "type": "number" + }, + "maxassoc": { + "type": "alias", + "default": "max_num_sta" + }, + "mbo": { + "description": "Multiband Operation", + "type": "boolean" + }, + "mcast_rate": { + "description": "Allowed multicast rates", + "type": "array", + "items": { + "type": "number" + } + }, + "mesh_auto_open_plinks": { + "type": "boolean" + }, + "mesh_awake_window": { + "type": "number" + }, + "mesh_confirm_timeout": { + "type": "number" + }, + "mesh_element_ttl": { + "type": "number" + }, + "mesh_fwding": { + "description": "Enable 802.11s layer-2 routing and forwarding", + "type": "boolean" + }, + "mesh_gate_announcements": { + "type": "number" + }, + "mesh_holding_timeout": { + "type": "number" + }, + "mesh_hwmp_active_path_timeout": { + "type": "number" + }, + "mesh_hwmp_active_path_to_root_timeout": { + "type": "number" + }, + "mesh_hwmp_confirmation_interval": { + "type": "number" + }, + "mesh_hwmp_max_preq_retries": { + "type": "number" + }, + "mesh_hwmp_net_diameter_traversal_time": { + "type": "number" + }, + "mesh_hwmp_preq_min_interval": { + "type": "number" + }, + "mesh_hwmp_rann_interval": { + "type": "number" + }, + "mesh_hwmp_root_interval": { + "type": "number" + }, + "mesh_hwmp_rootmode": { + "type": "number" + }, + "mesh_id": { + "type": "string" + }, + "mesh_max_peer_links": { + "type": "number" + }, + "mesh_max_retries": { + "type": "number" + }, + "mesh_min_discovery_timeout": { + "type": "number" + }, + "mesh_path_refresh_time": { + "type": "number" + }, + "mesh_plink_timeout": { + "type": "number" + }, + "mesh_power_mode": { + "type": "string" + }, + "mesh_retry_timeout": { + "type": "number" + }, + "mesh_rssi_threshold": { + "type": "number" + }, + "mesh_sync_offset_max_neighor": { + "type": "number" + }, + "mesh_ttl": { + "type": "number" + }, + "mobility_domain": { + "description": "DID is used to indicate a group of APs between which a STA can use Fast BSS Transition.", + "type": "string" + }, + "mode": { + "type": "string" + }, + "multi_ap": { + "description": "Enable Multi-AP functionality", + "type": "number" + }, + "multi_ap_backhaul_key": { + "type": "string" + }, + "multi_ap_backhaul_ssid": { + "description": "Multi-AP backhaul BSS SSID", + "type": "string" + }, + "multicast_to_unicast": { + "description": "Request that the AP will do multicast-to-unicast conversion for ARP, IPv4, and IPv6 frames ", + "type": "boolean" + }, + "multicast_to_unicast_all": { + "type": "alias", + "default": "multicast_to_unicast" + }, + "nas_identifier": { + "description": "NAS-Identifier string for RADIUS messages", + "type": "string" + }, + "nai_realm": { + "description": "NAI Realm information", + "type": "array", + "items": { + "type": "string" + } + }, + "nasid": { + "type": "alias", + "default": "nas_identifier" + }, + "network_auth_type": { + "description": "Network Authentication Type", + "type": "string" + }, + "ocv": { + "description": "Operating Channel Validation", + "type": "number", + "minimum": 0, + "maximum": 15 + }, + "okc": { + "description": "PMKSA and Opportunistic Key Caching", + "type": "boolean" + }, + "operator_icon": { + "type": "array" + }, + "osen": { + "description": "OSU Server-Only Authenticated L2 Encryption Network", + "type": "boolean", + "default": false + }, + "osu_provider": { + "type": "array", + "items": { + "type": "string" + } + }, + "osu_ssid": { + "type": "string" + }, + "owe_transition": { + "description": "Indicate that an OWE BSS shall automatically add an unencrypted transition interface", + "type": "boolean" + }, + "owe_transition_bssid": { + "description": "Pointer to the matching open/OWE BSS", + "type": "string" + }, + "owe_transition_ifname": { + "description": "Alternatively, OWE transition mode BSSID/SSID can be configured with a reference to a BSS operated by this hostapd process.", + "type": "string" + }, + "owe_transition_ssid": { + "description": "The SSID used by the OWE transition device", + "type": "string" + }, + "ownip": { + "type": "alias", + "default": "own_ip_addr" + }, + "own_ip_addr": { + "description": "The own IP address of the access point", + "type": "string" + }, + "password:wpakey": { + "type": "string" + }, + "pbc_in_m1": { + "description": "WPS capability discovery workaround for PBC with Windows 7", + "type": "boolean" + }, + "per_sta_vif": { + "description": "Per-Station AP_VLAN interface mode", + "type": "boolean" + }, + "pmk_r1_push": { + "description": "Whether PMK-R1 push is enabled at R0KH", + "type": "boolean", + "default": false + }, + "port:port": { + "type": "number" + }, + "powersave": { + "type": "boolean" + }, + "ppsk": { + "description": "Lookup PSK2 Keys up via a Radius server", + "type": "boolean" + }, + "preamble": { + "description": "Short Preamble", + "type": "boolean", + "default": true + }, + "priv_key": { + "type": "string" + }, + "priv_key_pwd": { + "type": "string" + }, + "private_key": { + "description": "Private key matching with the server certificate for EAP-TLS/PEAP/TTLS", + "type": "string" + }, + "private_key_passwd": { + "description": "Passphrase for private key", + "type": "string" + }, + "proxy_arp": { + "description": "Proxy ARP", + "type": "boolean" + }, + "qos_map_set": { + "description": "QoS Map Set configuration", + "type": "string", + "default": "0,0,2,16,1,1,255,255,18,22,24,38,40,40,44,46,48,56" + }, + "r0_key_lifetime": { + "description": "Default lifetime of the PMK-R0 in seconds", + "type": "number" + }, + "r0kh": { + "description": "List of R0KHs in the same Mobility Domain", + "type": "array", + "items": { + "type": "string" + } + }, + "r1_key_holder": { + "description": "PMK-R1 Key Holder identifier", + "type": "string" + }, + "r1kh": { + "description": "List of R1KHs in the same Mobility Domain", + "type": "array", + "items": { + "type": "string" + } + }, + "radius_acct_interim_interval": { + "description": "Interim accounting update interval", + "type": "number" + }, + "radius_acct_req_attr": { + "description": "Additional Accounting-Request attributes", + "type": "array", + "items": { + "type": "string" + } + }, + "radius_auth_req_attr": { + "description": "Additional Access-Request attributes", + "type": "array", + "items": { + "type": "string" + } + }, + "radius_client_addr": { + "description": "RADIUS client forced local IP address for the access point", + "type": "string" + }, + "radius_das_client": { + "description": "DAS client (the host that can send Disconnect/CoA requests)", + "type": "string" + }, + "radius_das_port": { + "description": "Dynamic Authorization Extensions port", + "type": "number" + }, + "radius_das_secret": { + "description": "Dynamic Authorization Extensions secret", + "type": "string" + }, + "radius_request_cui" :{ + "description": "Request Chargeable-User-Identity (RFC 4372)", + "type": "boolean" + }, + "reassociation_deadline": { + "description": "Reassociation deadline in time units", + "type": "number", + "minimum": 1000, + "maximum": 65535, + "default": 1000 + }, + "request_cui": { + "type": "alias", + "default": "radius_request_cui" + }, + "rrm_beacon_report": { + "description": "Enable beacon report via radio measurements", + "type": "boolean", + "default": true + }, + "rrm_neighbor_report": { + "description": "Enable neighbor report via radio measurements", + "type": "boolean", + "default": true + }, + "rnr": { + "description": "Enable reduced neighbor reporting", + "type": "boolean", + "default": true + }, + "roaming_consortium": { + "description": "Roaming Consortium List", + "type": "array", + "items": { + "type": "string" + } + }, + "rsn_preauth": { + "type": "boolean" + }, + "sae_pwe": { + "description": "SAE mechanism for PWE derivation", + "type": "number", + "enum": [ 0, 1, 2 ] + }, + "sae_require_mfp": { + "description": "Require MFP for all associations using SAE", + "type": "boolean" + }, + "server:host": { + "type": "string" + }, + "server_cert": { + "description": "Server certificate (PEM or DER file) for EAP-TLS/PEAP/TTLS", + "type": "string" + }, + "server_id": { + "description": "Server identity", + "type": "string" + }, + "short_preamble": { + "type": "alias", + "default": "preamble" + }, + "skip_inactivity_poll": { + "description": "The inactivity polling can be disabled to disconnect stations based on inactivity timeout so that idle stations are more likely to be disconnected even if they are still in range of the AP", + "type": "boolean", + "default": false + }, + "ssid": { + "type": "string" + }, + "ssid:string": { + "type": "string" + }, + "start_disabled": { + "type": "number" + }, + "subject_match": { + "description": "Substring to be matched against the subject of the authentication server certificate", + "type": "string" + }, + "subject_match2": { + "type": "string" + }, + "supported_rates": { + "type": "array" + }, + "tdls_prohibit": { + "description": "Prohibit use of TDLS in this BSS", + "type": "boolean" + }, + "time_advertisement": { + "description": "Time advertisement", + "type": "number", + "enum": [ 0, 2 ] + }, + "time_zone": { + "description": "Local time zone as specified in 8.3 of IEEE Std 1003.1-2004", + "type": "string" + }, + "uapsd": { + "type": "alias", + "default": "uapsd_advertisement_enabled" + }, + "uapsd_advertisement_enabled": { + "description": "WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD]", + "type": "boolean", + "default": true + }, + "uesa": { + "description": "Unauthenticated emergency service accessible", + "type": "boolean", + "default": false + }, + "utf8_ssid": { + "description": "Whether the SSID is to be interpreted using UTF-8 encoding", + "type": "boolean", + "default": true + }, + "vendor_elements": { + "description": "Additional vendor specific elements for Beacon and Probe Response frames", + "type": "array", + "items": { + "type": "string" + } + }, + "venue_group": { + "type": "string" + }, + "venue_name": { + "description": "Venue Name information", + "type": "array", + "items": { + "type": "string" + } + }, + "venue_type": { + "type": "string" + }, + "venue_url": { + "description": "Venue URL information", + "type": "array", + "items": { + "type": "string" + } + }, + "vlan_bridge": { + "description": "Bridge (prefix) to add the wifi and the tagged interface to.", + "type": "string" + }, + "vlan_file": { + "type": "string" + }, + "vlan_naming": { + "description": "When hostapd creates a VLAN interface on vlan_tagged_interfaces, it needs to know how to name it.", + "type": "boolean", + "default": true + }, + "vlan_no_bridge": { + "description": "To not setup a bridge for dynamic vlans", + "type": "boolean" + }, + "vlan_tagged_interface": { + "type": "string" + }, + "wds": { + "type": "boolean" + }, + "wds_bridge": { + "description": "If bridge parameter is set, the WDS STA interface will be added to the same bridge by default", + "type": "string" + }, + "wds_sta": { + "description": "If bridge parameter is set, the WDS STA interface will be added to the same bridge by default", + "type": "boolean" + }, + "wmm": { + "type": "alias", + "default": "wmm_enabled" + }, + "wmm_enabled": { + "description": "Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e)", + "type": "boolean", + "default": true + }, + "wnm_sleep_mode": { + "description": "WNM-Sleep Mode (extended sleep mode for stations)", + "type": "boolean" + }, + "wnm_sleep_mode_no_keys": { + "description": "WNM-Sleep Mode GTK/IGTK workaround", + "type": "boolean" + }, + "wpa_disable_eapol_key_retries": { + "description": "Workaround for key reinstallation attacks", + "type": "boolean", + "default": false + }, + "wpa_gmk_rekey": { + "description": "Time interval for rekeying GMK (master key used internally to generate GTKs)", + "type": "number" + }, + "wpa_group_rekey": { + "description": "Time interval for rekeying GTK (broadcast/multicast encryption keys)", + "type": "number" + }, + "wpa_master_rekey": { + "type": "alias", + "default": "wpa_gmk_rekey" + }, + "wpa_pair_rekey": { + "type": "alias", + "default": "wpa_ptk_rekey" + }, + "wpa_psk_file": { + "description": "External file conatining VLAN PSK MAC address triplets", + "type": "string" + }, + "wpa_ptk_rekey": { + "description": "Maximum lifetime for PTK in seconds", + "type": "number" + }, + "wpa_strict_rekey": { + "description": "Rekey GTK when any STA that possesses the current GTK is leaving the BSS", + "type": "boolean" + }, + "wps_ap_setup_locked": { + "type": "alias", + "default": "ap_setup_locked" + }, + "wps_device_name": { + "type": "alias", + "default": "device_name" + }, + "wps_device_type": { + "type": "alias", + "default": "device_type" + }, + "wps_independent": { + "description": "Whether to manage this interface independently from other WPS interfaces", + "type": "number", + "default": true + }, + "wps_label": { + "description": "Support WPS labels", + "type": "boolean" + }, + "wps_manufacturer": { + "type": "alias", + "default": "manufacturer" + }, + "wps_pbc_in_m1": { + "type": "alias", + "default": "pbc_in_m1" + }, + "wps_pin": { + "type": "alias", + "default": "ap_pin" + }, + "wps_pushbutton": { + "description": "Support WPS pushbutton", + "type": "boolean" + } + } +} diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-station.json b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-station.json new file mode 100644 index 00000000000000..dbad47abf4b0a7 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-station.json @@ -0,0 +1,20 @@ +{ + "$id": "https://openwrt.org/wifi.station.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "OpenWrt WiFi Station Schema", + "type": "object", + "properties": { + "mac": { + "description": "The stations MAC", + "type": "string" + }, + "key": { + "description": "The passphrase that shall be used", + "type": "string" + }, + "vid": { + "description": "The VLAN Id used by the station", + "type": "string" + } + } +} diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-vlan.json b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-vlan.json new file mode 100644 index 00000000000000..a06c8dabf0b78a --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/schema/wireless.wifi-vlan.json @@ -0,0 +1,16 @@ +{ + "$id": "https://openwrt.org/wifi.vlan.json", + "$schema": "http://json-schema.org/draft-07/schema#", + "description": "OpenWrt WiFi VLAN Schema", + "type": "object", + "properties": { + "name": { + "description": "VLAN name", + "type": "string" + }, + "vid": { + "description": "VLAN ID", + "type": "string" + } + } +} diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/iwinfo.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/iwinfo.uc new file mode 100644 index 00000000000000..a266092bea3ad6 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/iwinfo.uc @@ -0,0 +1,602 @@ +'use strict'; + +import * as nl80211 from 'nl80211'; +import * as libubus from 'ubus'; +import { readfile, stat } from "fs"; + +let wifi_devices = json(readfile('/usr/share/wifi_devices.json')); +let countries = json(readfile('/usr/share/iso3166.json')); +let board_data = json(readfile('/etc/board.json')); + +export let phys = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, nl80211.const.NLM_F_DUMP, { split_wiphy_dump: true }); +let interfaces = nl80211.request(nl80211.const.NL80211_CMD_GET_INTERFACE, nl80211.const.NLM_F_DUMP); + +let ubus = libubus.connect(); +let wireless_status = ubus.call('network.wireless', 'status'); + +function find_phy(wiphy) { + for (let k, phy in phys) + if (phy.wiphy == wiphy) + return phy; + return null; +} + +function get_noise(iface) { + for (let phy in phys) { + let channels = nl80211.request(nl80211.const.NL80211_CMD_GET_SURVEY, nl80211.const.NLM_F_DUMP, { dev: iface.ifname }); + for (let k, channel in channels) + if (channel.survey_info.frequency == iface.wiphy_freq) + return channel.survey_info.noise; + } + + return -100; +} + +function get_country(iface) { + let reg = nl80211.request(nl80211.const.NL80211_CMD_GET_REG, 0, { dev: iface.ifname }); + + return reg.reg_alpha2 ?? ''; +} + +function get_max_power(iface) { + let phy = find_phy(iface.wiphy); + + for (let k, band in phy.wiphy_bands) + if (band) + for (let freq in band.freqs) + if (freq.freq == iface.wiphy_freq) + return freq.max_tx_power;; + return 0; +} + +function get_hardware_id(iface) { + let hw = { + type: 'nl80211', + id: 'Generic MAC80211', + power_offset: 0, + channel_offset: 0, + }; + + let path = `/sys/class/ieee80211/phy${iface.wiphy}/device/`; + if (stat(path + 'vendor')) { + let data = []; + for (let lookup in [ 'vendor', 'device', 'subsystem_vendor', 'subsystem_device' ]) + push(data, trim(readfile(path + lookup), '\n')); + + for (let device in wifi_devices.pci) { + let match = 0; + for (let i = 0; i < 4; i++) + if (lc(data[i]) == lc(device[i])) + match++; + if (match == 4) { + hw.type = `${data[0]}:${data[1]} ${data[2]}:${data[3]}`; + hw.power_offset = device[4]; + hw.channel_offset = device[5]; + hw.id = `${device[6]} ${device[7]}`; + } + } + } + + let compatible = trim(readfile(`/sys/class/net/${iface.ifname}/device/of_node/compatible`), '\n'); + if (compatible && wifi_devices.compatible[compatible]) { + hw.id = wifi_devices.compatible[compatible][0] + ' ' + wifi_devices.compatible[compatible][1]; + hw.compatible = compatible; + hw.type = 'embedded'; + } + + return hw; +} + +const iftypes = [ + 'Unknown', 'Ad-Hoc', 'Client', 'Master', 'Master (VLAN)', + 'WDS', 'Monitor', 'Mesh Point', 'P2P Client', 'P2P Go', +]; + +export let ifaces = {}; +for (let k, v in interfaces) { + let iface = ifaces[v.ifname] = v; + + iface.mode = iftypes[iface.iftype] ?? 'unknonw', + iface.noise = get_noise(iface); + iface.country = get_country(iface); + iface.max_power = get_max_power(iface); + iface.assoclist = nl80211.request(nl80211.const.NL80211_CMD_GET_STATION, nl80211.const.NLM_F_DUMP, { dev: v.ifname }) ?? []; + iface.hardware = get_hardware_id(iface); + + iface.bss_info = ubus.call('hostapd', 'bss_info', { iface: v.ifname }); + if (!iface.bss_info) + iface.bss_info = ubus.call('wpa_supplicant', 'bss_info', { iface: v.ifname }); +} + +for (let radio, data in wireless_status) + for (let k, v in data.interfaces) { + if (!v.ifname || !ifaces[v.ifname]) + continue; + + ifaces[v.ifname].ssid = v.config.ssid || v.config.mesh_id; + ifaces[v.ifname].radio = data.config; + + let bss_info = ifaces[v.ifname].bss_info; + let owe_transition_ifname = bss_info?.owe_transition_ifname; + + if (v.config.owe_transition && ifaces[owe_transition_ifname]) { + ifaces[v.ifname].owe_transition_ifname = owe_transition_ifname; + ifaces[owe_transition_ifname].ssid = v.config.ssid; + ifaces[owe_transition_ifname].radio = data.config; + ifaces[owe_transition_ifname].owe_transition_ifname = v.ifname + } + } + +function format_channel(freq) { + if (freq < 1000) + return 0; + if (freq == 2484) + return 14; + if (freq == 5935) + return 2; + if (freq < 2484) + return (freq - 2407) / 5; + if (freq >= 4910 && freq <= 4980) + return (freq - 4000) / 5; + if (freq < 5950) + return (freq - 5000) / 5; + if (freq <= 45000) + return (freq - 5950) / 5; + if (freq >= 58320 && freq <= 70200) + return (freq - 56160) / 2160; + + return 'unknown'; +} + +function format_band(freq) { + if (freq == 5935) + return '6'; + if (freq < 2484) + return '2.4'; + if (freq < 5950) + return '5'; + if (freq <= 45000) + return '6'; + + return '60'; +} + +function format_frequency(freq) { + return freq ? sprintf('%.03f', freq / 1000.0) : 'unknown'; +} + +function format_rate(rate) { + return rate ? sprintf('%.01f', rate / 10.0) : 'unknown'; +} + +function format_mgmt_key(key) { + switch(+key) { + case 1: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + return '802.1x'; + + case 2: + return 'WPA PSK'; + + case 4: + return 'FT PSK'; + + case 6: + return 'WPA PSK2'; + + case 8: + return 'SAE'; + + case 18: + return 'OWE'; + } + + return null; +} + +function assoc_flags(data) { + const assoc_mhz = { + width_40: 40, + width_80: 80, + width_80p80: '80+80', + width_160: 160, + width_320: 320, + width_10: 10, + width_5: 5 + }; + + let mhz = 'unknown'; + for (let k, v in assoc_mhz) + if (data[k]) + mhz = v; + + const assoc_flags = { + mcs: { + mcs: 'MCS', + }, + vht_mcs: { + vht_mcs: 'VHT-MCS', + vht_nss: 'VHT-NSS', + }, + he_mcs: { + he_mcs: 'HE-MCS', + he_nss: 'HE-NSS', + he_gi: 'HE-GI', + he_dcm: 'HE-DCM', + }, + eht_mcs: { + eht_mcs: 'EHT-MCS', + eht_nss: 'EHT-NSS', + eht_gi: 'EHT-GI', + }, + }; + + let flags = []; + for (let k, v in assoc_flags) { + if (!data[k]) + continue; + + let first = 0; + for (let name, flag in v) { + if (data[name] == null) + continue; + push(flags, `${flag} ${data[name]}`); + if (!first++) + push(flags, `${mhz}MHz`); + } + } + + return flags; +} + +function dbm2mw(dbm) { + const LOG10_MAGIC = 1.25892541179; + let res = 1.0; + let ip = dbm / 10; + let fp = dbm % 10; + + for (let k = 0; k < ip; k++) + res *= 10; + for (let k = 0; k < fp; k++) + res *= LOG10_MAGIC; + + return int(res); +} + +function dbm2quality(dbm) { + let quality = dbm; + + if (quality < -110) + quality = -110; + else if (quality > -40) + quality = -40; + quality += 110; + + return quality; +} + +function hwmodelist(name) { + const mode = { 'HT*': 'n', 'VHT*': 'ac', 'HE*': 'ax' }; + let iface = ifaces[name]; + let phy = board_data.wlan?.['phy' + iface.wiphy]; + if (!phy) + return ''; + let htmodes = phy.info.bands[uc(iface.radio.band)].modes; + let list = []; + if (iface.radio.band == '2g' && 'NOHT' in htmodes) + push(list, 'g/b'); + for (let k, v in mode) + for (let htmode in htmodes) + if (wildcard(htmode, k)) + push(list, v); + + return join('/', reverse(uniq(list))); +} + +export function assoclist(dev) { + let stations = ifaces[dev].assoclist; + let ret = {}; + + for (let station in stations) { + let sta = { + mac: uc(station.mac), + signal: station.sta_info.signal_avg, + noise: ifaces[dev].noise, + snr: station.sta_info.signal_avg - ifaces[dev].noise, + inactive_time: station.sta_info.inactive_time, + rx: { + bitrate: format_rate(station.sta_info.rx_bitrate.bitrate), + bitrate_raw: station.sta_info.rx_bitrate.bitrate, + packets: station.sta_info.rx_packets, + flags: assoc_flags(station.sta_info.rx_bitrate), + }, + tx: { + bitrate: format_rate(station.sta_info.tx_bitrate.bitrate), + bitrate_raw: station.sta_info.tx_bitrate.bitrate, + packets: station.sta_info.tx_packets, + flags: assoc_flags(station.sta_info.tx_bitrate), + }, + expected_throughput: station.sta_info.expected_throughput ?? 'unknown', + }; + ret[sta.mac] = sta; + } + + return ret; +}; + +export function freqlist(name) { + const freq_flags = { + no_10mhz: 'NO_10MHZ', + no_20mhz: 'NO_20MHZ', + no_ht40_minus: 'NO_HT40-', + no_ht40_plus: 'NO_HT40+', + no_80mhz: 'NO_80MHZ', + no_160mhz: 'NO_160MHZ', + indoor_only: 'INDOOR_ONLY', + no_ir: 'NO_IR', + no_he: 'NO_HE', + radar: 'RADAR_DETECTION', + }; + + let iface = ifaces[name]; + let phy = find_phy(iface.wiphy); + let channels = []; + + for (let k, band in phy.wiphy_bands) { + if (!band) + continue; + + let band_name = format_band(band.freqs[0].freq); + for (let freq in band.freqs) { + if (freq.disabled) + continue; + + let channel = { + freq: format_frequency(freq.freq), + band: band_name, + channel: format_channel(freq.freq), + flags: [], + active: iface.wiphy_freq == freq.freq, + }; + + for (let k, v in freq_flags) + if (freq[k]) + push(channel.flags, v); + + push(channels, channel); + } + } + + return channels; +}; + +export function info(name) { + let order = []; + for (let iface, data in ifaces) + push(order, iface); + + let list = []; + for (let iface in sort(order)) { + if (name && iface != name) + continue; + let data = ifaces[iface]; + let dev = { + iface, + ssid: data.ssid, + mac: data.mac, + mode: data.mode, + channel: format_channel(data.wiphy_freq), + freq: format_frequency(data.wiphy_freq), + htmode: data.radio.htmode, + center_freq1: format_channel(data.center_freq1) || 'unknown', + center_freq2: format_channel(data.center_freq2) || 'unknown', + txpower: data.wiphy_tx_power_level / 100, + noise: data.noise, + signal: 0, + bitrate: 0, + encryption: 'unknown', + hwmode: hwmodelist(iface), + phy: 'phy' + data.wiphy, + vaps: 'no', + hw_type: data.hardware.type, + hw_id: data.hardware.id, + power_offset: data.hardware.power_offset || 'none', + channel_offset: data.hardware.channel_offset || 'none', + }; + + let phy = find_phy(data.wiphy); + for (let limit in phy.interface_combinations[0]?.limits) + if (limit.types?.ap && limit.max > 1) + dev.vaps = 'yes'; + + if (data.bss_info) { + if (data.bss_info.wpa_key_mgmt && data.bss_info.wpa_pairwise) + dev.encryption = `${replace(data.bss_info.wpa_key_mgmt, ' ', ' / ')} (${data.bss_info.wpa_pairwise})`; + else if (data.owe_transition_ifname) + dev.encryption = 'none (OWE transition)'; + else + dev.encryption = 'none'; + } + + let stations = assoclist(iface); + for (let k, station in stations) { + dev.signal += station.signal; + dev.bitrate += station.tx.bitrate_raw; + } + dev.signal /= length(data.assoclist) || 1; + dev.bitrate /= length(data.assoclist) || 1; + dev.bitrate = format_rate(dev.bitrate); + dev.quality = dbm2quality(dev.signal); + + if (data.owe_transition_ifname) + dev.owe_transition_ifname = data.owe_transition_ifname; + + push(list, dev); + } + + return list; +}; + +export function htmodelist(name) { + let iface = ifaces[name]; + let phy = board_data.wlan?.['phy' + iface.wiphy]; + if (!phy) + return []; + + return filter(phy.info.bands[uc(iface.radio.band)].modes, (v) => v != 'NOHT'); +}; + +export function txpowerlist(name) { + let iface = ifaces[name]; + let max_power = iface.max_power / 100; + let match = iface.wiphy_tx_power_level / 100; + let list = []; + + for (let power = 0; power <= max_power; power++) { + let txpower = { + dbm: power, + mw: dbm2mw(power), + active: power == match, + }; + push(list, txpower); + } + + return list; +}; + +export function countrylist(dev) { + let iface = ifaces[dev]; + + let list = { + active: iface.country, + countries, + }; + + return list; +}; + +export function scan(dev) { + const rsn_cipher = [ 'NONE', 'WEP-40', 'TKIP', 'WRAP', 'CCMP', 'WEP-104', 'AES-OCB', 'CKIP', 'GCMP', 'GCMP-256', 'CCMP-256' ]; + const ht_chan_offset = [ 'no secondary', 'above', '[reserved]', 'below' ]; + const vht_chan_width = [ '20 or 40 MHz', '80 MHz', '80+80 MHz', '160 MHz' ]; + const ht_chan_width = [ '20 MHz', '40 MHz or higher' ]; + const SCAN_FLAG_AP = (1<<2); + + let params = { + dev, + scan_flags: SCAN_FLAG_AP, + scan_ssids: [ '' ], + }; + + let res = nl80211.request(nl80211.const.NL80211_CMD_TRIGGER_SCAN, 0, params); + if (res === false) { + printf("Unable to trigger scan: " + nl80211.error() + "\n"); + exit(1); + } + + res = nl80211.waitfor([ + nl80211.const.NL80211_CMD_NEW_SCAN_RESULTS, + nl80211.const.NL80211_CMD_SCAN_ABORTED + ], 5000); + + if (!res) { + printf("Netlink error while awaiting scan results: " + nl80211.error() + "\n"); + exit(1); + } else if (res.cmd == nl80211.const.NL80211_CMD_SCAN_ABORTED) { + printf("Scan aborted by kernel\n"); + exit(1); + } + + let scan = nl80211.request(nl80211.const.NL80211_CMD_GET_SCAN, nl80211.const.NLM_F_DUMP, { dev }); + + let cells = []; + for (let k, bss in scan) { + bss = bss.bss; + let cell = { + bssid: uc(bss.bssid), + frequency: format_frequency(bss.frequency), + band: format_band(bss.frequency), + channel: format_channel(bss.frequency), + dbm: bss.signal_mbm / 100, + + }; + + if (bss.capability & (1 << 1)) + cell.mode = 'Ad-Hoc'; + else if (bss.capability & (1 << 0)) + cell.mode = 'Master'; + else + cell.mode = 'Mesh Point'; + + cell.quality = dbm2quality(cell.dbm); + + for (let ie in bss.information_elements) + switch(ie.type) { + case 0: + case 114: + cell.ssid = ie.data; + break; + + case 7: + cell.country = substr(ie.data, 0, 2); + break; + + case 48: + cell.crypto = { + group: rsn_cipher[ord(ie.data, 5)] ?? '', + pair: [], + key_mgmt: [], + }; + + let offset = 6; + let count = ord(ie.data, offset); + offset += 2; + + for (let i = 0; i < count; i++) { + let key = rsn_cipher[ord(ie.data, offset + 3)]; + if (key) + push(cell.crypto.pair, key); + offset += 4; + } + + count = ord(ie.data, offset); + offset += 2; + + for (let i = 0; i < count; i++) { + let key = format_mgmt_key(ord(ie.data, offset + 3)); + if (key) + push(cell.crypto.key_mgmt, key); + offset += 4; + } + break; + + case 61: + cell.ht = { + primary_channel: ord(ie.data, 0), + secondary_chan_off: ht_chan_offset[ord(ie.data, 1) & 0x3], + chan_width: ht_chan_width[(ord(ie.data, 1) & 0x4) >> 2], + }; + break; + + case 192: + cell.vht = { + chan_width: vht_chan_width[ord(ie.data, 0)], + center_chan_1: ord(ie.data, 1), + center_chan_2: ord(ie.data, 2), + }; + break; + }; + + + + push(cells, cell); + } + + return cells; +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/ap.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/ap.uc new file mode 100644 index 00000000000000..8db3fc34b31530 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/ap.uc @@ -0,0 +1,481 @@ +'use strict'; + +import * as libuci from 'uci'; +import { md5 } from 'digest'; +import * as fs from 'fs'; + +import { append, append_raw, append_value, append_vars, comment, push_config, set_default, touch_file } from 'wifi.common'; +import * as netifd from 'wifi.netifd'; +import * as iface from 'wifi.iface'; + +function iface_setup(config) { + switch(config.fixup) { + case 'owe': + config.ignore_broadcast_ssid = true; + config.ssid = config.ssid + 'OWE'; + break; + + case 'owe-transition': + let ifname = config.ifname; + config.ifname = config.owe_transition_ifname; + config.owe_transition_ifname = ifname; + config.owe_transition_ssid = config.ssid + 'OWE'; + config.encryption = 'none'; + config.ignore_broadcast_ssid = false; + iface.prepare(config); + break; + } + + comment('Setup interface: ' + config.ifname); + + config.bridge = config.network_bridge; + config.snoop_iface = config.network_ifname; + if (!config.wds) + config.wds_bridge = null; + else + config.wds_sta = true; + + if (!config.idx) + append('interface', config.ifname); + else + append('bss', config.ifname); + + if (config.multicast_to_unicast || config.proxy_arp) + config.ap_isolate = 1; + + append('bssid', config.macaddr); + +append_vars(config, [ + 'ctrl_interface', 'ap_isolate', 'max_num_sta', 'ap_max_inactivity', 'airtime_bss_weight', + 'airtime_bss_limit', 'airtime_sta_weight', 'bss_load_update_period', 'chan_util_avg_period', + 'disassoc_low_ack', 'skip_inactivity_poll', 'ignore_broadcast_ssid', 'uapsd_advertisement_enabled', + 'utf8_ssid', 'multi_ap', 'ssid', 'tdls_prohibit', 'bridge', 'wds_sta', 'wds_bridge', + 'snoop_iface', 'vendor_elements', 'nas_identifier', 'radius_acct_interim_interval', + 'ocv', 'multicast_to_unicast', 'preamble', 'wmm_enabled', 'proxy_arp', 'per_sta_vif', 'mbo', + 'bss_transition', 'wnm_sleep_mode', 'wnm_sleep_mode_no_keys', 'qos_map_set', 'max_listen_int', + 'dtim_period', + ]); +} + +function iface_authentication_server(config) { + for (let server in config.auth_server_addr) { + append('auth_server_addr', server); + append_vars(config, [ 'auth_server_port', 'auth_server_shared_secret' ]); + } + + append_vars(config, [ 'radius_auth_req_attr' ]); +} + +function iface_accounting_server(config) { + for (let server in config.acct_server_addr) { + append('acct_server_addr', server); + append_vars(config, [ 'acct_server_port', 'acct_server_shared_secret' ]); + } + + append_vars(config, [ 'radius_acct_req_attr' ]); +} + +function iface_auth_type(config) { + iface.parse_encryption(config); + + if (config.auth_type in [ 'sae', 'owe', 'eap2', 'eap192' ]) { + config.ieee80211w = 2; + config.sae_require_mfp = 1; + config.sae_pwe = 2; + } + + if (config.auth_type in [ 'psk-sae', 'eap-eap2' ]) { + config.ieee80211w = 1; + config.sae_require_mfp = 1; + config.sae_pwe = 2; + } + + if (config.own_ip_addr) + config.dynamic_own_ip_addr = null; + + if (!config.wpa) + config.wpa_disable_eapol_key_retries = null; + + switch(config.auth_type) { + case 'none': + case 'owe': + config.wps_possible = 1; + config.wps_state = 1; + + if (config.owe_transition_ssid) + config.owe_transition_ssid = `"${config.owe_transition_ssid}"`; + + append_vars(config, [ + 'owe_transition_ssid', 'owe_transition_bssid', 'owe_transition_ifname', + ]); + break; + + case 'psk': + case 'psk2': + case 'sae': + case 'psk-sae': + config.vlan_possible = 1; + config.wps_possible = 1; + + if (config.auth_type == 'psk' && config.ppsk) { + iface_authentication_server(config); + config.macaddr_acl = 2; + config.wpa_psk_radius = 2; + } else if (length(config.key) == 64) { + config.wpa_psk = key; + } else if (length(config.key) >= 8) { + config.wpa_passphrase = config.key; + } else if (!config.wpa_psk_file) { + netifd.setup_failed('INVALID_WPA_PSK'); + } + + set_default(config, 'wpa_psk_file', `/var/run/hostapd-${config.ifname}.psk`); + touch_file(config.wpa_psk_file); + set_default(config, 'dynamic_vlan', 0); + break; + + case 'eap': + case 'eap2': + case 'eap-eap2': + case 'eap192': + config.vlan_possible = 1; + + if (config.fils) { + set_default(config, 'erp_domain', substr(md5(config.ssid), 0, 4)); + set_default(config, 'fils_realm', config.erp_domain); + set_default(config, 'erp_send_reauth_start', 1); + set_default(config, 'fils_cache_id', substr(md5(config.fils_realm), 0, 4)); + } + + if (!config.eap_server) { + iface_authentication_server(config); + iface_accounting_server(config); + } + + if (config.radius_das_client && config.radius_das_secret) { + set_default(config, 'radius_das_port', 3799); + set_default(config, 'radius_das_client', `${config.radius_das_client} ${config.radius_das_secret}`); + } + + set_default(config, 'eapol_version', config.wpa & 1); + if (!config.eapol_version) + config.eapol_version = null; + append('eapol_key_index_workaround', '1'); + append('ieee8021x', '1'); + + break; + } + + append_vars(config, [ + 'sae_require_mfp', 'sae_pwe', 'time_advertisement', 'time_zone', + 'wpa_group_rekey', 'wpa_ptk_rekey', 'wpa_gmk_rekey', 'wpa_strict_rekey', + 'macaddr_acl', 'wpa_psk_radius', 'wpa_psk', 'wpa_passphrase', 'wpa_psk_file', + 'eapol_version', 'dynamic_vlan', 'radius_request_cui', 'eap_reauth_period', + 'radius_das_client', 'radius_das_port', 'own_ip_addr', 'dynamic_own_ip_addr', + 'wpa_disable_eapol_key_retries', 'auth_algs', 'wpa', 'wpa_pairwise', + 'erp_domain', 'fils_realm', 'erp_send_reauth_start', 'fils_cache_id' + ]); +} + +function iface_ppsk(config) { + if (!(config.auth_type in [ 'none', 'owe', 'psk', 'sae', 'psk-sae', 'wep' ]) || !config.auth_server_addr) + return; + + iface_authentication_server(config); + append('macaddr_acl', '2'); +} + +function iface_wps(config) { + push_config(config, 'config_methods', 'wps_pushbutton', 'push_button'); + push_config(config, 'config_methods', 'wps_label', 'label'); + + if (config.multi_ap == 1) + config.wps_possible = false; + + if (config.wps_possible && length(config.config_methods)) { + config.eap_server = 1; + set_default(config, 'wps_state', 2); + + if (config.ext_registrar && config.network_bridge) + set_default(config, 'upnp_iface', config.network_bridge); + + if (config.multi_ap && config.multi_ap_backhaul_ssid) { + append_vars(config, [ 'multi_ap_backhaul_ssid' ]); + if (length(config.multi_ap_backhaul_key) == 64) + append('multi_ap_backhaul_wpa_psk', config.multi_ap_backhaul_key); + else if (length(config.multi_ap_backhaul_key) > 8) + append('multi_ap_backhaul_wpa_passphrase', config.multi_ap_backhaul_key); + else + netifd.setup_failed('INVALID_WPA_PSK'); + } + + append_vars(config, [ + 'wps_state', 'device_type', 'device_name', 'config_methods', 'wps_independent', 'eap_server', + 'ap_pin', 'ap_setup_locked', 'upnp_iface' + ]); + } +} + +function iface_rrm(config) { + set_default(config, 'rrm_neighbor_report', config.ieee80211k); + set_default(config, 'rrm_beacon_report', config.ieee80211k); + + append_vars(config, [ + 'rrm_neighbor_report', 'rrm_beacon_report', 'rnr', 'ftm_responder', + ]); +} + +function iface_ftm(config, phy_features) { + if (!phy_features.ftm_responder || !config.ftm_responder) + return; + + append_vars(config, [ + 'ftm_responder', 'lci', 'civic' + ]); +} + +function iface_macfilter(config) { + let path = `/var/run/hostapd-${config.ifname}.maclist`; + + switch(config.macfilter) { + case 'allow': + append('accept_mac_file', path); + append('macaddr_acl', 1); + config.vlan_possible = 1; + break; + + case 'deny': + append('deny_mac_file', path); + append('macaddr_acl', 0); + break; + + default: + return; + } + + let file = fs.open(path, 'w'); + if (!file) { + warn(`Failed to open ${path}`); + return; + } + + if (config.maclist) + file.write(join('\n', config.maclist)); + + let macfile = fs.readfile(config.macfile); + if (macfile) + file.write(macfile); + file.close(); +} + +function iface_vlan(interface, config, vlans) { + let path = `/var/run/hostapd-${config.ifname}.vlan`; + + let file = fs.open(path, 'w'); + for (let k, vlan in vlans) + if (vlan.config.name && vlan.config.vid) { + let ifname = `${config.ifname}-${vlan.config.name}`; + file.write(`${vlan.config.vid} ${ifname}\n`); + netifd.set_vlan(interface, k, ifname); + } + file.close(); + + set_default(config, 'vlan_file', path); + append_vars(config, [ 'vlan_file' ]); + + if (!config.vlan_possible || !config.dynamic_vlan) + return; + + config.vlan_no_bridge = !config.vlan_bridge; + + append_vars(config, [ + 'dynamic_vlan', 'vlan_naming', 'vlan_bridge', 'vlan_no_bridge', + 'vlan_tagged_interface' + ]); +} + +function iface_stations(config, stas) { + if (!length(stas)) + return; + + let path = `/var/run/hostapd-${config.ifname}.psk`; + + let file = fs.open(path, 'w'); + for (let k, sta in stas) + if (sta.config.mac && sta.config.key) { + let station = `${sta.config.mac} ${sta.config.key}\n`; + if (sta.config.vid) + station = `vlanid=${sta.config.vid} ` + station; + file.write(station); + } + file.close(); + + set_default(config, 'wpa_psk_file', path); +} + +function iface_eap_server(config) { + if (!config.eap_server) + return; + + set_default(config, 'eap_server', true); + set_default(config, 'eap_server_erp', true); + + append_vars(config, [ + 'eap_server', 'eap_server_erp', 'eap_user_file', 'ca_cert', 'server_cert', + 'private_key', 'private_key_passwd', 'server_id', + ]); +} + +function iface_roaming(config) { + if (!config.ieee80211r || config.wpa < 2) + return; + + set_default(config, 'mobility_domain', substr(md5(config.ssid), 0, 4)); + set_default(config, 'ft_psk_generate_local', config.auth_type == 'psk'); + set_default(config, 'ft_iface', config.network_ifname); + + if (!config.ft_psk_generate_local) { + if (!config.r0kh || !config.r1kh) { + if (!config.auth_secret && !config.key) + netifd.setup_failed('FT_KEY_CANT_BE_DERIVED'); + + let ft_key = md5(`${config.mobility_domain}/${config.auth_secret ?? config.key}`); + + set_default(config, 'r0kh', 'ff:ff:ff:ff:ff:ff * ' + ft_key); + set_default(config, 'r1kh', '00:00:00:00:00:00 00:00:00:00:00:00 ' + ft_key); + } + + append_vars(config, [ + 'r0kh', 'r1kh', 'r1_key_holder', 'r0_key_lifetime', 'pmk_r1_push' + ]); + } + + append_vars(config, [ + 'mobility_domain', 'ft_psk_generate_local', 'ft_over_ds', 'reassociation_deadline', + 'ft_iface' + ]); +} + +function iface_mfp(config) { + if (!config.ieee80211w || config.wpa < 2) { + append('ieee80211w', 0); + return; + } + + if (config.auth_type == 'eap192') + config.group_mgmt_cipher = 'BIP-GMAC-256'; + else + config.group_mgmt_cipher = config.ieee80211w_mgmt_cipher ?? 'AES-128-CMAC'; + + append_vars(config, [ + 'ieee80211w', 'group_mgmt_cipher', 'assoc_sa_query_max_timeout', 'assoc_sa_query_retry_timeout' + ]); +} + +function iface_key_caching(config) { + if (config.wpa < 2) + return; + + if (config.network_bridge && config.rsn_preauth) { + set_default(config, 'okc', true); + config.rsn_preauth_interfaces = config.network_bridge; + + append_vars(config, [ + 'rsn_preauth', 'rsn_preauth_interfaces' + ]); + } else { + set_default(config, 'okc', (config.auth_type in [ 'sae', 'psk-sae', 'owe' ])); + } + + if (!config.okc && !config.fils) + config.disable_pmksa_caching = 1; + + append_vars(config, [ + 'okc', 'disable_pmksa_caching' + ]); +} + +function iface_hs20(config) { + if (!config.hs20) + return; + + let uci = libuci.cursor(); + let icons = uci.get_all('wireless'); + for (let k, icon in icons) + if (icon['.type'] == 'hs20-icon') + append('hs20_icon', `${icon.width}:${icon.heigth}:${icon.lang}:${icon.type}:${k}:${icon.path}`); + + append_vars(config, [ + 'hs20', 'disable_dgaf', 'osen', 'anqp_domain_id', 'hs20_deauth_req_timeout', 'osu_ssid', + 'hs20_wan_metrics', 'hs20_operating_class', 'hs20_t_c_filename', 'hs20_t_c_timestamp', + 'hs20_t_c_server_url', 'hs20_oper_friendly_name', 'hs20_conn_capab', 'osu_provider', + 'operator_icon' + ]); +} + +function iface_interworking(config) { + if (!config.iw_enabled) + return; + + config.interworking = true; + + if (config.domain_name) + config.domain_name = join(',', config.domain_name); + + if (config.anqp_3gpp_cell_net) + config.domain_name = join(',', config.anqp_3gpp_cell_net); + + append_vars(config, [ + 'interworking', 'internet', 'asra', 'uesa', 'access_network_type', 'hessid', 'venue_group', + 'venue_type', 'network_auth_type', 'gas_address3', 'roaming_consortium', 'anqp_elem', 'nai_realm', + 'venue_name', 'venue_url', 'domain_name', 'anqp_3gpp_cell_net', + ]); +} + +export function generate(interface, config, vlans, stas, phy_features) { + config.ctrl_interface = '/var/run/hostapd'; + + iface_stations(config, stas); + + iface_setup(config); + + iface_auth_type(config); + + iface_accounting_server(config); + + iface_ppsk(config); + + iface_wps(config); + + iface_rrm(config); + + iface_ftm(config, phy_features); + + iface_macfilter(config); + + iface_vlan(interface, config, vlans); + + iface_eap_server(config); + + iface_roaming(config); + + iface_mfp(config); + + iface_key_caching(config); + + iface_hs20(config); + + iface_interworking(config); + + iface.wpa_key_mgmt(config); + append_vars(config, [ + 'wpa_key_mgmt' + ]); + + /* raw options */ + for (let raw in config.hostapd_options) + append_raw(raw); + + if (config.default_macaddr) + append_raw('#default_macaddr'); +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/common.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/common.uc new file mode 100644 index 00000000000000..a4d7eb3ed75892 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/common.uc @@ -0,0 +1,124 @@ +'use strict'; + +import * as libubus from 'ubus'; +import * as fs from 'fs'; + +global.ubus = libubus.connect(); + +let config_data = ''; +let network_data = ''; + +export function log(msg) { + printf(`wifi-scripts: ${msg}\n`); +}; + +export function append_raw(value) { + config_data += value + '\n'; +}; + +export function append(key, value) { + if (value == null) + return; + + switch (type(value)) { + case 'array': + value = join(' ', value); + break; + case 'bool': + value = value ? 1 : 0; + break; + } + + append_raw(key + '=' + value); +}; + +export function append_vars(dict, keys) { + for (let key in keys) + append(key, dict[key]); +}; + +export function network_append_raw(value) { + network_data += value + '\n'; +}; + +export function network_append(key, value) { + if (value == null) + return; + + switch (type(value)) { + case 'array': + value = join(' ', value); + break; + case 'bool': + value = value ? 1 : 0; + break; + } + + network_append_raw('\t' + key + '=' + value); +}; + +export function network_append_vars(dict, keys) { + for (let key in keys) + network_append(key, dict[key]); +}; + +export function set_default(dict, key, value) { + if (dict[key] == null) + dict[key] = value; +}; + +export function push_config(dict, key, option, value) { + if (!dict[option]) + return; + + dict[key] ??= []; + push(dict[key], value); +}; + +export function touch_file(filename) { + let file = fs.open(filename, "a"); + if (file) + file.close(); + else + log('Failed to touch ' + filename); +}; + +export function append_value(config, key, value) { + if (!config[key]) + config[key] = value; + else + config[key] += ' ' + value; +}; + +export function comment(comment) { + append_raw('\n# ' + comment); +}; + +export function dump_config(file) { + if (file) + fs.writefile(file, config_data); + + return config_data; +}; + +export function dump_network(file) { + config_data += 'network={\n'; + config_data += network_data;; + config_data += '}\n'; + + if (file) + fs.writefile(file, config_data); + + printf('%s\n', config_data); + + return config_data; +}; + +export function flush_config() { + config_data = ''; +}; + +export function flush_network() { + config_data = ''; + network_data = ''; +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/hostapd.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/hostapd.uc new file mode 100644 index 00000000000000..78b38ff63334fb --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/hostapd.uc @@ -0,0 +1,577 @@ +'use strict'; + +import { append, append_raw, append_vars, dump_config, flush_config, set_default } from 'wifi.common'; +import { validate } from 'wifi.validate'; +import * as netifd from 'wifi.netifd'; +import * as iface from 'wifi.iface'; +import * as nl80211 from 'nl80211'; +import * as ap from 'wifi.ap'; +import * as fs from 'fs'; + +const NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 33; +const NL80211_EXT_FEATURE_RADAR_BACKGROUND = 61; + +let phy_features = {}; +let phy_capabilities = {}; + +/* make sure old style UCI and hwmode and newer band properties are correctly resolved */ +function set_device_defaults(config) { + /* validate the hw mode */ + if (config.hwmode in [ '11a', '11b', '11g', '11ad' ]) + config.hw_mode = substr(config.hwmode, 2); + else if (config.channel > 14) + config.hw_mode = 'a'; + else + config.hw_mode = 'g'; + + /* validate band */ + if (config.band == '2g') + config.hw_mode = 'g'; + else if (config.band in [ '5g', '6g', '60g' ]) + config.hw_mode = 'a'; + else + switch (config.hw_mode) { + case 'a': + config.band = '5g'; + break; + + case 'ad': + config.band = '60g'; + break; + + default: + config.band = '2g'; + break; + } +} + +/* setup sylog / stdout */ +function device_log_append(config) { + let log_mask = 0; + + for (let k in [ 'log_mlme', 'log_iapp', 'log_driver', 'log_wpa', 'log_radius', 'log_8021x', 'log_80211' ]) { + log_mask <<= 1; + log_mask |= config[k] ? 1 : 0; + } + + append('logger_syslog', log_mask); + append('logger_syslog_level', config.log_level); + append('logger_stdout', log_mask); + append('logger_stdout_level', config.log_level); +} + +/* setup country code */ +function device_country_code(config) { + let status = global.ubus.call('network.wireless', 'status'); + for (let name, radio in status) { + if (!radio.config.country) + continue; + config.country_code = radio.config.country; + } + + if (!exists(config, 'country_code')) + return; + + if (config.hw_mode != 'a') + delete config.ieee80211h; + append_vars(config, [ 'country_code', 'country3', 'ieee80211h' ]); + if (config.ieee80211d) + append_vars(config, [ 'ieee80211d', 'local_pwr_constraint', 'spectrum_mgmt_required' ]); +} + + +/* setup cell density */ +function device_cell_density_append(config) { + switch (config.hw_mode) { + case 'b': + if (config.cell_density == 1) { + config.supported_rates = [ 5500, 11000 ]; + config.basic_rates = [ 5500, 11000 ]; + } else if (config.cell_density > 2) { + config.supported_rates = [ 11000 ]; + config.basic_rates = [ 11000 ]; + } + ;; + case 'g': + if (config.cell_density in [ 0, 1 ]) { + if (!config.legacy_rates) { + config.supported_rates = [ 6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 6000, 12000, 24000 ]; + } else if (config.cell_density == 1) { + config.supported_rates = [ 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 5500, 11000 ]; + } + } else if (config.cell_density == 2 || (config.cell_density > 3 && config.legacy_rates)) { + if (!config.legacy_rates) { + config.supported_rates = [ 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 12000, 24000 ]; + } else { + config.supported_rates = [ 11000, 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 11000 ]; + } + } else if (config.cell_density > 2) { + config.supported_rates = [ 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 24000 ]; + } + ;; + case 'a': + switch (config.cell_density) { + case 1: + config.supported_rates = [ 6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 6000, 12000, 24000 ]; + break; + + case 2: + config.supported_rates = [ 12000, 18000, 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 12000, 24000 ]; + break; + + case 3: + config.supported_rates = [ 24000, 36000, 48000, 54000 ]; + config.basic_rates = [ 24000 ]; + break; + } + } +} + +function device_rates(config) { + for (let key in [ 'supported_rates', 'basic_rates' ]) + config[key] = map(config[key], x => x / 100); + + append_vars(config, [ 'beacon_rate', 'supported_rates', 'basic_rates' ]); +} + +function device_htmode_append(config) { + config.channel_offset = config.band == '6g' ? 1 : 0; + + /* 802.11n */ + config.ieee80211n = 0; + if (config.band != '6g') { + if (config.htmode in [ 'VHT20', 'HT20', 'HE20', 'EHT20' ]) + config.ieee80211n = 1; + if (config.htmode in [ 'HT40', 'HT40+', 'HT40-', 'VHT40', 'VHT80', 'VHT160', 'HE40', 'HE80', 'HE160', 'EHT40', 'EHT80', 'EHT160' ]) { + config.ieee80211n = 1; + if (!config.channel) + config.ht_capab = '[HT40+]'; + else + switch (config.hw_mode) { + case 'a': + switch (((config.channel / 4) + config.channel_offset) % 2) { + case 0: + config.ht_capab = '[HT40-]'; + break; + + case 1: + config.ht_capab = '[HT40+]'; + break; + } + break; + + default: + switch (config.htmode) { + case 'HT40+': + case 'HT40-': + config.ht_capab = '[' + config.htmode + ']'; + break; + + default: + if (config.channel < 7) + config.ht_capab = '[HT40+]'; + else + config.ht_capab = '[HT40-]'; + break; + } + } + } + + if (config.ieee80211n) { + let ht_capab = phy_capabilities.ht_capa; + + if (ht_capab & 0x1 && config.ldpc) + config.ht_capab += '[LDPC]'; + if (ht_capab & 0x10 && config.greenfield) + config.ht_capab += '[GF]'; + if (ht_capab & 0x20 && config.short_gi_20) + config.ht_capab += '[SHORT-GI-20]'; + if (ht_capab & 0x40 && config.short_gi_40) + config.ht_capab += '[SHORT-GI-40]'; + if (ht_capab & 0x80 && config.tx_stbc) + config.ht_capab += '[TX-STBC]'; + if (ht_capab & 0x800 && config.max_amsdu) + config.ht_capab += '[MAX-AMSDU-7935]'; + if (ht_capab & 0x1000 && config.dsss_cck_40) + config.ht_capab += '[DSSS_CCK-40]'; + let rx_stbc = [ '', '[RX-STBC1]', '[RX-STBC12]', '[RX-STBC123]' ]; + config.ht_capab += rx_stbc[min(config.rx_stbc, (ht_capab >> 8) & 3)]; + + append_vars(config, [ 'ieee80211n', 'ht_coex', 'ht_capab' ]); + } + } + + /* 802.11ac */ + config.ieee80211ac = 1; + config.vht_oper_centr_freq_seg0_idx = 0; + config.vht_oper_chwidth = 0; + + switch (config.htmode) { + case 'VHT20': + case 'HE20': + case 'EHT20': + break; + + case 'VHT40': + case 'HE40': + case 'EHT40': + config.vht_oper_centr_freq_seg0_idx = config.channel + (((config.channel / 4) + config.channel_offset) % 2 ? 2 : -2); + break; + + case 'VHT80': + case 'HE80': + case 'EHT80': + let delta = [ -6, 6, 2, -2 ]; + config.vht_oper_centr_freq_seg0_idx = config.channel + delta[((config.channel / 4) + config.channel_offset) % 4]; + config.vht_oper_chwidth = 1; + break; + + case 'VHT160': + case 'HE160': + case 'EHT160': + let vht_oper_centr_freq_seg0_idx_map = [[ 64, 50 ], [ 128, 114 ], [ 177, 163 ]]; + if (config.band == '6g') + vht_oper_centr_freq_seg0_idx_map = [ + [ 29, 15 ], [ 61, 47 ], [ 93, 79 ], [ 125, 111 ], + [ 157, 143 ], [ 189, 175 ], [ 221, 207 ]]; + for (let k, v in vht_oper_centr_freq_seg0_idx_map) + if (v[0] <= config.channel) { + config.vht_oper_centr_freq_seg0_idx = v[1]; + break; + } + config.vht_oper_chwidth = 2; + break; + + default: + config.ieee80211ac = 0; + break; + } + + config.eht_oper_chwidth = config.vht_oper_chwidth; + config.eht_oper_centr_freq_seg0_idx = config.vht_oper_centr_freq_seg0_idx; + + if (config.band == '6g') { + config.ieee80211ac = 0; + + switch(config.htmode) { + case 'HE20': + case 'EHT20': + config.op_class = 131; + break; + + case 'EHT320': + let eht_center_seg0_map = [ + [ 61, 31 ], [ 125, 95 ], [ 189, 159 ], [ 221, 191 ] + ]; + + for (let k, v in eht_center_seg0_map) + if (v[0] <= config.channel) { + config.eht_oper_centr_freq_seg0_idx = v[1]; + break; + } + config.op_class = 137; + config.eht_oper_chwidth = 7; + break; + + case 'HE40': + case 'HE80': + case 'HE160': + case 'EHT40': + case 'EHT80': + case 'EHT160': + config.op_class = 132 + config.eht_oper_chwidth; + break; + } + + append_vars(config, [ 'op_class' ]); + } + + if (config.ieee80211ac && config.hw_mode == 'a') { + /* VHT capab */ + if (config.vht_oper_chwidth < 2) { + config.vht160 = 0; + config.short_gi_160 = 0; + } + + config.tx_queue_data2_burst = '2.0'; + + let vht_capab = phy_capabilities.vht_capa; + + config.vht_capab = ''; + if (vht_capab & 0x10 && config.rxldpc) + config.vht_capab += '[RXLDPC]'; + if (vht_capab & 0x20 && config.short_gi_80) + config.vht_capab += '[SHORT-GI-80]'; + if (vht_capab & 0x40 && config.short_gi_160) + config.vht_capab += '[SHORT-GI-160]'; + if (vht_capab & 0x80 && config.tx_stbc_2by1) + config.vht_capab += '[TX-STBC-2BY1]'; + if (vht_capab & 0x800 && config.su_beamformer) + config.vht_capab += '[SU-BEAMFORMER]'; + if (vht_capab & 0x1000 && config.su_beamformee) + config.vht_capab += '[SU-BEAMFORMEE]'; + if (vht_capab & 0x80000 && config.mu_beamformer) + config.vht_capab += '[MU-BEAMFORMER]'; + if (vht_capab & 0x100000 && config.mu_beamformee) + config.vht_capab += '[MU-BEAMFORMEE]'; + if (vht_capab & 0x200000 && config.vht_txop_ps) + config.vht_capab += '[VHT-TXOP-PS]'; + if (vht_capab & 0x400000 && config.htc_vht) + config.vht_capab += '[HTC-VHT]'; + if (vht_capab & 0x10000000 && config.rx_antenna_pattern) + config.vht_capab += '[RX-ANTENNA-PATTERN]'; + if (vht_capab & 0x20000000 && config.tx_antenna_pattern) + config.vht_capab += '[TX-ANTENNA-PATTERN]'; + let rx_stbc = [ '', '[RX-STBC1]', '[RX-STBC12]', '[RX-STBC123]', '[RX-STBC-1234]' ]; + config.vht_capab += rx_stbc[min(config.rx_stbc, (vht_capab >> 8) & 7)]; + + if (vht_capab & 0x800 && config.su_beamformer) + config.vht_capab += '[SOUNDING-DIMENSION-' + min(((vht_capab >> 16) & 3) + 1, config.beamformer_antennas) + ']'; + if (vht_capab & 0x1000 && config.su_beamformee) + config.vht_capab += '[BF-ANTENNA-' + min(((vht_capab >> 13) & 3) + 1, config.beamformer_antennas) + ']'; + + /* supported Channel widths */ + if (vht_capab & 0xc == 8 && config.vht160 <= 2) + config.vht_capab += '[VHT160-80PLUS80]'; + else if (vht_capab & 0xc == 4 && config.vht160 <= 1) + config.vht_capab += '[VHT160]'; + + /* maximum MPDU length */ + if (vht_capab & 3 > 1 && config.vht_max_mpdu > 11454) + config.vht_capab += '[MAX-MPDU-11454]'; + else if (vht_capab & 3 && config.vht_max_mpdu > 7991) + config.vht_capab += '[MAX-MPDU-7991]'; + + /* maximum A-MPDU length exponent */ + let max_a_mpdu_len_exp = (vht_capab >> 20) & 0x38; + for (let exp = 7; exp; exp--) + if (max_a_mpdu_len_exp >= (0x8 * exp) && exp <= config.vht_max_a_mpdu_len_exp) { + config.vht_capab += '[MAX-A-MPDU-LEN-EXP' + exp + ']'; + break; + } + + /* whether or not the STA supports link adaptation using VHT variant */ + let vht_link_adapt = vht_capab & 0xC000000; + if (vht_link_adapt >= 0xC000000 && config.vht_link_adapt > 3) + config.vht_capab += '[VHT-LINK-ADAPT-3]'; + if (vht_link_adapt >= 0x8000000 && config.vht_link_adapt > 2) + config.vht_capab += '[VHT-LINK-ADAPT-2]'; + + append_vars(config, [ + 'ieee80211ac', 'vht_oper_chwidth', 'vht_oper_centr_freq_seg0_idx', + 'vht_capab' + ]); + } + + /* 802.11ax */ + if (wildcard(config.htmode, 'HE*') || wildcard(config.htmode, 'EHT*')) { + let he_phy_cap = phy_capabilities.he_phy_cap; + let he_mac_cap = phy_capabilities.he_mac_cap; + + config.ieee80211ax = true; + + if (config.hw_mode == 'a') { + config.he_oper_chwidth = config.vht_oper_chwidth; + config.he_oper_centr_freq_seg0_idx = config.vht_oper_centr_freq_seg0_idx; + } + + if (config.he_bss_color_enabled) { + if (config.he_spr_non_srg_obss_pd_max_offset) + config.he_spr_sr_control |= 1 << 2; + if (!config.he_spr_psr_enabled) + config.he_spr_sr_control |= 1; + append_vars(config, [ 'he_bss_color', 'he_spr_non_srg_obss_pd_max_offset', 'he_spr_sr_control' ]); + } + + if (!(he_phy_cap[3] & 0x80)) + config.he_su_beamformer = false; + if (!(he_phy_cap[4] & 0x1)) + config.he_su_beamformee = false; + if (!(he_phy_cap[4] & 0x2)) + config.he_mu_beamformer = false; + if (!(he_phy_cap[7] & 0x1)) + config.he_spr_psr_enabled = false; + if (!(he_mac_cap[0] & 0x1)) + config.he_twt_required= false; + + append_vars(config, [ + 'ieee80211ax', 'he_oper_chwidth', 'he_oper_centr_freq_seg0_idx', + 'he_su_beamformer', 'he_su_beamformee', 'he_mu_beamformer', 'he_twt_required', + 'he_default_pe_duration', 'he_rts_threshold', 'he_mu_edca_qos_info_param_count', + 'he_mu_edca_qos_info_q_ack', 'he_mu_edca_qos_info_queue_request', 'he_mu_edca_qos_info_txop_request', + 'he_mu_edca_ac_be_aifsn', 'he_mu_edca_ac_be_aci', 'he_mu_edca_ac_be_ecwmin', + 'he_mu_edca_ac_be_ecwmax', 'he_mu_edca_ac_be_timer', 'he_mu_edca_ac_bk_aifsn', + 'he_mu_edca_ac_bk_aci', 'he_mu_edca_ac_bk_ecwmin', 'he_mu_edca_ac_bk_ecwmax', + 'he_mu_edca_ac_bk_timer', 'he_mu_edca_ac_vi_ecwmin', 'he_mu_edca_ac_vi_ecwmax', + 'he_mu_edca_ac_vi_aifsn', 'he_mu_edca_ac_vi_aci', 'he_mu_edca_ac_vi_timer', + 'he_mu_edca_ac_vo_aifsn', 'he_mu_edca_ac_vo_aci', 'he_mu_edca_ac_vo_ecwmin', + 'he_mu_edca_ac_vo_ecwmax', 'he_mu_edca_ac_vo_timer', + ]); + } + + if (wildcard(config.htmode, 'EHT*')) { + config.ieee80211be = true; + append_vars(config, [ 'ieee80211be' ]); + + if (config.hw_mode == 'a') + append_vars(config, [ 'eht_oper_chwidth', 'eht_oper_centr_freq_seg0_idx' ]); + + if (config.band == "6g") { + config.stationary_ap = true; + append_vars(config, [ 'he_6ghz_reg_pwr_type', ]); + } + } + + append_vars(config, [ 'tx_queue_data2_burst', 'stationary_ap' ]); +} + +function device_extended_features(data, flag) { + return !!(data[flag / 8] | (1 << (flag % 8))); +} + +function device_capabilities(phy) { + let idx = +substr(phy, 3, 1);; + let phys = nl80211.request(nl80211.const.NL80211_CMD_GET_WIPHY, nl80211.const.NLM_F_DUMP, { wiphy: idx, split_wiphy_dump: true }); + + for (let phy in phys) { + if (!phy || phy.wiphy != idx) + continue; + for (let band in phy.wiphy_bands) { + if (!band) + continue; + phy_capabilities.ht_capa = band.ht_capa ?? 0; + phy_capabilities.vht_capa = band.vht_capa ?? 0; + for (let iftype in band.iftype_data) { + if (!iftype.iftypes.ap) + continue; + phy_capabilities.he_mac_cap = iftype.he_cap_mac; + phy_capabilities.he_phy_cap = iftype.he_cap_phy; + } + break; + } + + phy_features.ftm_responder = device_extended_features(phy.extended_features, NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER); + phy_features.radar_background = device_extended_features(phy.extended_features, NL80211_EXT_FEATURE_RADAR_BACKGROUND); + break; + } +} + +function generate(config) { + if (!config.phy) + die(`${config.path} is an unknown phy`); + + device_capabilities(config.phy); + + append('driver', 'nl80211'); + + set_device_defaults(config); + + device_log_append(config); + + device_country_code(config); + + device_cell_density_append(config); + + device_rates(config); + + /* beacon */ + append_vars(config, [ 'beacon_int', 'beacon_rate', 'rnr_beacon', 'mbssid' ]); + + /* wpa_supplicant co-exist */ + append_vars(config, [ 'noscan' ]); + + /* airtime */ + append_vars(config, [ 'airtime_mode' ]); + + /* assoc/thresholds */ + append_vars(config, [ 'rssi_reject_assoc_rssi', 'rssi_ignore_probe_request', 'iface_max_num_sta', 'no_probe_resp_if_max_sta' ]); + + /* ACS / Radar*/ + if (!phy_features.radar_background || config.band != '5g') + delete config.enable_background_radar; + else + set_default(config, 'enable_background_radar', phy_features.radar_background); + + append_vars(config, [ 'acs_chan_bias', 'acs_exclude_dfs', 'enable_background_radar' ]); + + /* TX Power */ + append_vars(config, [ 'min_tx_power' ]); + + /* hwmode, channel, op_class, ... */ + append_vars(config, [ 'hw_mode', 'channel', 'rts_threshold', 'chanlist' ]); + if (config.hw_mode in [ 'a', 'g' ] && config.require_mode in [ 'n', 'ac', 'ax' ]) { + let require_mode = { n: 'require_ht', ac: 'require_vht', ax: 'require_he' }; + + config.legacy_rates = false; + append(require_mode[config.require_mode], 1); + } + device_htmode_append(config); + + /* 6G power mode */ + if (config.band != '6g') + append_vars(config, [ 'reg_power_type' ]); + + /* raw options */ + for (let raw in config.hostapd_options) + append_raw(raw); +} + +let iface_idx = 0; +function setup_interface(interface, config, vlans, stas, phy_features, fixup) { + config = { ...config, fixup }; + + config.idx = iface_idx++; + ap.generate(interface, config, vlans, stas, phy_features); +} + +export function setup(data) { + let file_name = `/var/run/hostapd-${data.phy}${data.vif_phy_suffix}.conf`; + + flush_config(); + + if (fs.stat(file_name)) + fs.rename(file_name, file_name + '.prev'); + + data.config.phy = data.phy; + + generate(data.config); + + if (data.config.num_global_macaddr) + append('\n#num_global_macaddr', data.config.num_global_macaddr); + + for (let k, interface in data.interfaces) { + if (interface.config.mode != 'ap') + continue; + + interface.config.network_bridge = interface.bridge; + interface.config.network_ifname = interface['bridge-ifname']; + + let owe = interface.config.encryption == 'owe' && interface.config.owe_transition; + + setup_interface(k, interface.config, interface.vlans, interface.stas, phy_features, owe ? 'owe' : null ); + if (owe) + setup_interface(k, interface.config, interface.vlans, interface.stas, phy_features, 'owe-transition'); + } + + let config = dump_config(file_name); + + let msg = { + phy: data.phy, + radio: data.config.radio, + config: file_name, + prev_config: file_name + '.prev' + }; + let ret = global.ubus.call('hostapd', 'config_set', msg); + + if (ret) + netifd.add_process('/usr/sbin/hostapd', ret.pid, true, true); + else + netifd.setup_failed('HOSTAPD_START_FAILED'); +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/iface.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/iface.uc new file mode 100644 index 00000000000000..3c15d87d003f84 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/iface.uc @@ -0,0 +1,194 @@ +'use strict'; + +import { append_value, log } from 'wifi.common'; +import * as fs from 'fs'; + +export function parse_encryption(config) { + let encryption = split(config.encryption, '+', 2); + + config.wpa_pairwise = (config.hwmode == 'ad') ? 'GCMP' : 'CCMP'; + + switch(encryption[1]){ + case 'tkip+aes': + case 'tkip+ccmp': + case 'aes+tkip': + case 'ccmp+tkip': + config.wpa_pairwise = 'CCMP TKIP'; + break; + + case 'ccmp256': + config.wpa_pairwise = 'CCMP-256'; + break; + + case 'aes': + case 'ccmp': + config.wpa_pairwise = 'CCMP'; + break; + + case 'tkip': + config.wpa_pairwise = 'TKIP'; + break; + + case 'gcmp256': + config.wpa_pairwise = 'GCMP-256'; + break; + + case 'gcmp': + config.wpa_pairwise = 'GCMP'; + break; + + default: + if (config.encryption == 'wpa3-192') + config.wpa_pairwise = 'GCMP-256'; + break; + } + + config.wpa = 0; + for (let k, v in { 'wpa2*': 2, 'wpa3*': 2, '*psk2*': 2, 'psk3*': 2, 'sae*': 2, + 'owe*': 2, 'wpa*mixed*': 3, '*psk*mixed*': 3, 'wpa*': 1, '*psk*': 1, }) + if (wildcard(config.encryption, k)) { + config.wpa = v; + break; + } + if (!config.wpa) + config.wpa_pairwise = null; + + config.auth_type = encryption[0] ?? 'none'; + switch(config.auth_type) { + case 'owe': + config.auth_type = 'owe'; + break; + + case 'wpa3-192': + config.auth_type = 'eap192'; + break; + + case 'wpa3-mixed': + config.auth_type = 'eap-eap2'; + break; + + case 'wpa3': + config.auth_type = 'eap2'; + break; + + case 'sae-mixed': + config.auth_type = 'psk-sae'; + break; + + case 'wpa': + case 'wpa2': + config.auth_type = 'eap'; + break; + } +}; + +export function wpa_key_mgmt(config) { + if (!config.wpa) + return; + + switch(config.auth_type) { + case 'psk': + case 'psk2': + append_value(config, 'wpa_key_mgmt', 'WPA-PSK'); + if (config.wpa >= 2 && config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-PSK'); + if (config.ieee80211w) + append_value(config, 'wpa_key_mgmt', 'WPA-PSK-SHA256'); + break; + + case 'eap': + append_value(config, 'wpa_key_mgmt', 'WPA-EAP'); + if (config.wpa >= 2 && config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-EAP'); + if (config.ieee80211w) + append_value(config, 'wpa_key_mgmt', 'WPA-EAP--SHA256'); + break; + + case 'eap192': + append_value(config, 'wpa_key_mgmt', 'WPA-EAP-SUITE-B-192'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-EAP-SHA384'); + break; + + case 'eap-eap2': + append_value(config, 'wpa_key_mgmt', 'WPA-EAP'); + append_value(config, 'wpa_key_mgmt', 'WPA-EAP-SHA256'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-EAP'); + break; + + case 'eap2': + append_value(config, 'wpa_key_mgmt', 'WPA-EAP-SHA256'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-EAP'); + break; + + case 'sae': + append_value(config, 'wpa_key_mgmt', 'SAE'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-SAE'); + break; + + case 'psk-sae': + append_value(config, 'wpa_key_mgmt', 'WPA-PSK'); + append_value(config, 'wpa_key_mgmt', 'SAE'); + if (config.ieee80211w) + append_value(config, 'wpa_key_mgmt', 'WPA-PSK-SHA256'); + if (config.ieee80211r) { + append_value(config, 'wpa_key_mgmt', 'FT-PSK'); + append_value(config, 'wpa_key_mgmt', 'FT-SAE'); + } + break; + + case 'owe': + append_value(config, 'wpa_key_mgmt', 'OWE'); + break; + } + + if (config.fils) { + switch(config.auth_type) { + case 'eap192': + append_value(config, 'wpa_key_mgmt', 'FILS-SHA384'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-FILS-SHA384'); + break; + + case 'eap-eap2': + case 'eap2': + case 'eap': + append_value(config, 'wpa_key_mgmt', 'FILS-SHA256'); + if (config.ieee80211r) + append_value(config, 'wpa_key_mgmt', 'FT-FILS-SHA256'); + break; + } + } + + config.key_mgmt = config.wpa_key_mgmt; +}; + +function macaddr_random() { + let f = open("/dev/urandom", "r"); + let addr = f.read(6); + + addr = map(split(addr, ""), (v) => ord(v)); + addr[0] &= ~1; + addr[0] |= 2; + + return join(":", map(addr, (v) => sprintf("%02x", v))); +} + +let mac_idx = 0; +export function prepare(data, phy, num_global_macaddr) { + if (!data.macaddr) { + let pipe = fs.popen(`ucode /usr/share/hostap/wdev.uc ${phy} get_macaddr id=${mac_idx} num_global=${num_global_macaddr} mbssid=${data.mbssid ?? 0}`); + + data.macaddr = trim(pipe.read("all"), '\n'); + pipe.close(); + + data.default_macaddr = true; + mac_idx++; + } else if (data.macaddr == 'random') + data.macaddr = macaddr_random(); + + log(`Preparing interface: ${data.ifname} with MAC: ${data.macaddr}`); +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/netifd.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/netifd.uc new file mode 100644 index 00000000000000..5a4a9fafb37f25 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/netifd.uc @@ -0,0 +1,49 @@ +'use strict'; + +import { log } from 'wifi.common'; +import * as fs from 'fs'; + +const CMD_UP = 0; +const CMD_SET_DATA = 1; +const CMD_PROCESS_ADD = 2; +const CMD_PROCESS_KILL_ALL = 3; +const CMD_SET_RETRY = 4; + +export function notify(command, params, data) { + params ??= {}; + data ??= {}; + + global.ubus.call('network.wireless', 'notify', { command, device: global.radio, ...params, data }); +}; + +export function set_up() { + notify(CMD_UP); +}; + +export function set_data(data) { + notify(CMD_SET_DATA, null, data); +}; + +export function add_process(exe, pid, required, keep) { + exe = fs.realpath(exe); + + notify(CMD_PROCESS_ADD, null, { pid, exe, required, keep }); +}; + +export function set_retry(retry) { + notify(CMD_SET_RETRY, null, { retry }); +}; + +export function set_vif(interface, ifname) { + notify(CMD_SET_DATA, { interface }, { ifname }); +}; + +export function set_vlan(interface, ifname, vlan) { + notify(CMD_SET_DATA, { interface, vlan }, { ifname }); +}; + +export function setup_failed(reason) { + log(`Device setup failed: ${reason}`); + printf('%s\n', reason); + set_retry(false); +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/supplicant.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/supplicant.uc new file mode 100644 index 00000000000000..04d7f216aa68a7 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/supplicant.uc @@ -0,0 +1,237 @@ +'use strict'; + +import { append, append_raw, append_vars, network_append, network_append_raw, network_append_vars, + set_default, dump_network, flush_network } from 'wifi.common'; +import * as netifd from 'wifi.netifd'; +import * as iface from 'wifi.iface'; +import * as fs from 'fs'; + +function set_fixed_freq(data, config) { + if (!data.frequency) + return; + + set_default(config, 'fixed_freq', 1); + set_default(config, 'frequency', data.frequency); + + if (data.htmode in [ 'VHT80', 'HE80' ]) + set_default(config, 'max_oper_chwidth', 1); + else if (data.htmode in [ 'VHT160', 'HE160' ]) + set_default(config, 'max_oper_chwidth', 2); + else if (data.htmode in [ 'VHT20', 'VHT40', 'HE20', 'HE40' ]) + set_default(config, 'max_oper_chwidth', 0); + else + set_default(config, 'disable_vht', true); + + if (data.htmode in [ 'NOHT' ]) + set_default(config, 'disable_ht', true); + else if (data.htmode in [ 'HT20', 'VHT20', 'HE20' ]) + set_default(config, 'disable_ht40', true); + else if (data.htmode in [ 'VHT40', 'VHT80', 'VHT160', 'HE40', 'HE80', 'HE160' ]) + set_default(config, 'ht40', true); + + if (wildcard(data.htmode, 'VHT*')) + set_default(config, 'vht', 1); +} + +export function ratestr(rate) { + if (rate == null) + return rate; + + let rem = (rate / 100) % 10; + rate = int(rate / 1000); + if (rem > 0) + rate += "." + rem; + + return "" + rate; +}; + +export function ratelist(rates) { + if (length(rates) < 1) + return null; + + return join(",", map(rates, (rate) => ratestr(rate))); +}; + +function setup_sta(data, config) { + iface.parse_encryption(config); + + if (config.auth_type in [ 'sae', 'owe', 'eap2', 'eap192' ]) + set_default(config, 'ieee80211w', 2); + else if (config.auth_type in [ 'psk-sae' ]) + set_default(config, 'ieee80211w', 1); + + set_default(config, 'ieee80211r', 0); + set_default(config, 'multi_ap', 0); + set_default(config, 'default_disabled', 0); + +//multiap_flag_file="${_config}.is_multiap" + config.scan_ssid = 1; + + switch(config.mode) { + case 'sta': + set_default(config, 'multi_ap_backhaul_sta', config.multi_ap); + break; + + case 'adhoc': + config.ap_scan = 2; + config.scan_ssid = 0; + network_append('mode', 1); + set_fixed_freq(data, config); + break; + + case 'mesh': + config.ssid = config.mesh_id; + config.scan_ssid = null; + network_append('mode', 5); + + set_fixed_freq(data, config); + + if (config.encryption && config.encryption != 'none') + config.key_mgmt = 'SAE'; + + config.ieee80211w = null; + break; + } + + if (config.mode != 'mesh' ) { + switch(config.wpa) { + case 1: + config.proto = 'WPA'; + break; + + case 2: + config.proto = 'RSN'; + break; + } + } + + switch(config.auth_type) { + case 'none': + break; + + case 'owe': + iface.wpa_key_mgmt(config); + break; + + case 'psk': + case 'psk2': + case 'sae': + case 'psk-sae': + if (config.mode != 'mesh') + iface.wpa_key_mgmt(config); + + if (config.mode == 'mesh' || config.auth_type == 'sae') + config.sae_password = `"${config.key}"`; + else + config.psk = `"${config.key}"`; + + break; + + case 'eap': + case 'eap2': + case 'eap192': + iface.wpa_key_mgmt(config); + set_default(config, 'erp', config.fils); + + if (config.ca_cert_usesystem && fs.stat('/etc/ssl/certs/ca-certificates.crt')) + config.ca_cert = '/etc/ssl/certs/ca-certificates.crt'; + + switch(config.eap_type) { + case 'fast': + case 'peap': + case 'ttls': + set_default(config, 'auth', 'MSCHAPV2'); + if (config.auth == 'EAP-TLS') { + if (config.ca_cert2_usesystem && fs.stat('/etc/ssl/certs/ca-certificates.crt')) + config.ca_cert2 = '/etc/ssl/certs/ca-certificates.crt'; + } + break; + } + + } + + if (config.wpa_pairwise == 'GCMP') { + config.pairwise = 'GCMP'; + config.group = 'GCMP'; + } + + config.basic_rate = ratelist(config.basic_rate); + config.mcast_rate = ratestr(config.mcast_rate); + config.ssid = `"${config.ssid}"`; + + network_append_vars(config, [ + 'scan_ssid', 'noscan', 'disabled', 'multi_ap_backhaul_sta', + 'ocv', 'key_mgmt', 'psk', 'sae_password', 'pairwise', 'group', 'bssid', + 'proto', 'mesh_fwding', 'mesh_rssi_threshold', 'frequency', 'fixed_freq', + 'disable_ht', 'disable_ht40', 'disable_vht', 'vht', 'max_oper_chwidth', + 'ht40', 'ssid', 'beacon_int', 'ieee80211w', 'basic_rate', 'mcast_rate', + 'bssid_blacklist', 'bssid_whitelist', 'erp', 'ca_cert', 'identity', + 'anonymous_identity', 'client_cert', 'private_key', 'private_key_passwd', + 'subject_match', 'altsubject_match', 'domain_match', 'domain_suffix_match', + 'ca_cert2', 'client_cert2', 'private_key2', 'private_key2_passwd', 'password' + ]); +} + +export function generate(config_list, data, interface) { + flush_network(); + + if (interface.bridge && + (interface.config.mode == 'adhoc' || + (interface.config.mode == 'sta' && !interface.config.wds && !interface.config.multi_ap))){ + netifd.setup_failed('BRIDGE_NOT_ALLOWED'); + return 1; + } + + interface.config.country = data.config.country; + interface.config.beacon_int = data.config.beacon_int; + + setup_sta(data.config, interface.config); + + let file_name = `/var/run/wpa-supplicant-${interface.config.ifname}.conf`; + if (fs.stat(file_name)) + fs.rename(file_name, file_name + '.prev'); + dump_network(file_name); + + let config = { + mode: interface.config.mode, + ctrl: '/var/run/wpa_supplicant', + iface: interface.config.ifname, + config: file_name, + '4addr': !!interface.config.wds, + powersave: false + }; + + if (!interface.config.default_macaddr) + config.macaddr = interface.config.macaddr; + + if (interface.config.wds) + config.bridge = interface.bridge; + + push(config_list, config); + + return config; +}; + +export function setup(config, data) { + let ret = global.ubus.call('wpa_supplicant', 'config_set', { + phy: data.phy, + radio: data.config.radio, + config, + defer: true, + num_global_macaddr: data.config.num_global_macaddr, + }); + + if (ret) + netifd.add_process('/usr/sbin/wpa_supplicant', ret.pid, true, true); + else + netifd.setup_failed('SUPPLICANT_START_FAILED'); +}; + + +export function start(data) { + global.ubus.call('wpa_supplicant', 'config_set', { + phy: data.phy, + radio: data.config.radio, + num_global_macaddr: data.config.num_global_macaddr, + }); +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/validate.uc b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/validate.uc new file mode 100644 index 00000000000000..e675b7a6ca0893 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/ucode/wifi/validate.uc @@ -0,0 +1,121 @@ +'use strict'; + +import { log } from 'wifi.common'; +import * as fs from 'fs'; + +const schemas = { + device: json(fs.readfile('/usr/share/schema/wireless.wifi-device.json')).properties, + iface: json(fs.readfile('/usr/share/schema/wireless.wifi-iface.json')).properties, + vlan: json(fs.readfile('/usr/share/schema/wireless.wifi-vlan.json')).properties, + station: json(fs.readfile('/usr/share/schema/wireless.wifi-station.json')).properties, +}; + +const types = { + "array": 1, + "string": 3, + "number": 5, + "boolean": 7, +}; + +function dump_option(schema, key) { + let _key = (schema[key].type == 'alias') ? schema[key].default : key; + + return [ + key, + types[schema[_key].type] + ]; +} + +export function dump_options() { + let dump = { + "name": "mac80211", + }; + + for (let k, v in schemas) { + dump[k] = []; + for (let option in v) + push(dump[k], dump_option(v, option)); + }; + + printf('%J\n', dump); + + return 0; +}; + +function abort(msg) { + log(msg); + die(); +} + +function validate_value(schema, key, value) { + switch(schema.type) { + case 'number': + value = +value; + if (schema.minimum && value < schema.minimum) + abort(`${key}: ${value} is lower than the minimum value`); + if (schema.maximum && value > schema.maximum) + abort(`${key}: ${value} is larger than the maximum value`); + if (schema.enum && !(value in schema.enum)) + abort(`${key}: ${value} has to be one of ${schema.enum}`); + break; + + case 'boolean': + value = !!+value; + break; + + case 'string': + if (schema.enum && !(value in schema.enum)) + abort(`${key}: ${value} has to be one of ${schema.enum}`); + break; + + case 'array': + if (type(value) != 'array') + value = [ value ]; + if (schema.items?.type) + for (let k, v in value) + value[k] = validate_value(schema.items, key, v); + break; + } + + return value; +} + +export function validate(schema, dict) { + schema = schemas[schema]; + + /* complain about anything that is not in the schema */ + for (let k, v in dict) { + if (substr(k, 0, 1) == '.') + continue; + if (schema[k]) + continue; + log(`${k} is not present in the schema`); + } + + /* convert all aliases */ + for (let k, v in dict) { + if (schema[k]?.type != 'alias') + continue; + if (schema[k].default == null) + abort(`${k} alias does not have a default value`); + + dict[schema[k].default] = v; + delete dict[k]; + } + + /* set defaults */ + for (let k, v in schema) { + if (schema[k]?.type == 'alias') + continue; + if (dict[k] != null || schema[k].default == null) + continue; + dict[k] = schema[k].default; + } + + /* validate value constraints */ + for (let k, v in dict) { + if (!schema[k]) + continue; + dict[k] = validate_value(schema[k], k, v); + } +}; diff --git a/package/network/config/wifi-scripts/files-ucode/usr/share/wifi_devices.json b/package/network/config/wifi-scripts/files-ucode/usr/share/wifi_devices.json new file mode 100644 index 00000000000000..5a38ca4b2f5846 --- /dev/null +++ b/package/network/config/wifi-scripts/files-ucode/usr/share/wifi_devices.json @@ -0,0 +1,260 @@ +{ + "pci": [ + [ "0x0777", "0x11ac", "0x0777", "0xe7f9", 0, 0, "Ubiquiti", "LiteBeam, 5AC" ], + [ "0xffff", "0xffff", "0xffff", "0xb102", 0, 0, "Ubiquiti", "PowerStation2, (18V)" ], + [ "0xffff", "0xffff", "0xffff", "0xb202", 0, 0, "Ubiquiti", "PowerStation2, (16D)" ], + [ "0xffff", "0xffff", "0xffff", "0xb302", 0, 0, "Ubiquiti", "PowerStation2, (EXT)" ], + [ "0xffff", "0xffff", "0xffff", "0xb105", 0, 0, "Ubiquiti", "PowerStation5, (22V)" ], + [ "0xffff", "0xffff", "0xffff", "0xb305", 0, 0, "Ubiquiti", "PowerStation5, (EXT)" ], + [ "0xffff", "0xffff", "0xffff", "0xc302", 0, 0, "Ubiquiti", "PicoStation2" ], + [ "0xffff", "0xffff", "0xffff", "0xc3a2", 10, 0, "Ubiquiti", "PicoStation2, HP" ], + [ "0xffff", "0xffff", "0xffff", "0xa105", 0, 0, "Ubiquiti", "WispStation5" ], + [ "0xffff", "0xffff", "0xffff", "0xa002", 10, 0, "Ubiquiti", "LiteStation2" ], + [ "0xffff", "0xffff", "0xffff", "0xa005", 5, 0, "Ubiquiti", "LiteStation5" ], + [ "0xffff", "0xffff", "0xffff", "0xc002", 10, 0, "Ubiquiti", "NanoStation2" ], + [ "0xffff", "0xffff", "0xffff", "0xc005", 5, 0, "Ubiquiti", "NanoStation5" ], + [ "0xffff", "0xffff", "0xffff", "0xc102", 10, 0, "Ubiquiti", "NanoStation, Loco2" ], + [ "0xffff", "0xffff", "0xffff", "0xc105", 5, 0, "Ubiquiti", "NanoStation, Loco5" ], + [ "0xffff", "0xffff", "0xffff", "0xc202", 10, 0, "Ubiquiti", "Bullet2" ], + [ "0xffff", "0xffff", "0xffff", "0xc205", 5, 0, "Ubiquiti", "Bullet5" ], + [ "0x168c", "0xffff", "0x0777", "0xe002", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe003", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe006", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe009", 6, 0, "Ubiquiti", "NanoStation, Loco, M9" ], + [ "0x168c", "0xffff", "0x0777", "0xe012", 10, 0, "Ubiquiti", "NanoStation, M2" ], + [ "0x168c", "0xffff", "0x0777", "0xe035", 3, 0, "Ubiquiti", "NanoStation, M3" ], + [ "0x168c", "0xffff", "0x0777", "0xe0a2", 2, 0, "Ubiquiti", "NanoStation, Loco, M2" ], + [ "0x168c", "0xffff", "0x0777", "0xe0a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe102", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe105", 5, 0, "Ubiquiti", "Rocket, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe112", 10, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe115", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1a3", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1a5", 5, 0, "Ubiquiti", "PowerBridge, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe1b2", 10, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1b3", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1b5", 5, 0, "Ubiquiti", "Rocket, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe1b6", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1b9", 6, 0, "Ubiquiti", "Rocket, M9" ], + [ "0x168c", "0xffff", "0x0777", "0xe1c2", 10, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1c3", 3, 0, "Ubiquiti", "Rocket, M3" ], + [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "Rocket, M5, GPS" ], + [ "0x168c", "0xffff", "0x0777", "0xe1c5", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1d2", 10, 0, "Ubiquiti", "Rocket, M2, Titanium" ], + [ "0x168c", "0xffff", "0x0777", "0xe1d3", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1d5", 5, 0, "Ubiquiti", "airOS, XM/XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe1d9", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1e3", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe1e5", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], + [ "0x168c", "0xffff", "0x0777", "0xe205", 6, 0, "Ubiquiti", "Bullet, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe212", 1, 0, "Ubiquiti", "AirGrid, M2" ], + [ "0x168c", "0xffff", "0x0777", "0xe215", 1, 0, "Ubiquiti", "AirGrid, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe232", 2, 0, "Ubiquiti", "NanoBridge, M2" ], + [ "0x168c", "0xffff", "0x0777", "0xe233", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe235", 1, 0, "Ubiquiti", "NanoBridge, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe239", 6, 0, "Ubiquiti", "NanoBridge, M9" ], + [ "0x168c", "0xffff", "0x0777", "0xe242", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe243", 3, 0, "Ubiquiti", "NanoBridge, M3" ], + [ "0x168c", "0xffff", "0x0777", "0xe245", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe252", 9, 0, "Ubiquiti", "AirGrid, M2, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe255", 6, 0, "Ubiquiti", "AirGrid, M5, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe2a3", 3, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe2a5", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe2b2", 10, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe2b5", 1, 0, "Ubiquiti", "NanoBridge, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe2b9", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe2c2", 10, 0, "Ubiquiti", "NanoBeam, M2, Int" ], + [ "0x168c", "0xffff", "0x0777", "0xe2c3", 6, 0, "Ubiquiti", "Bullet, M2, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe2c4", 6, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe2d2", 12, 0, "Ubiquiti", "Bullet, M2, Titanium, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe2d4", 6, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe2d5", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe2e5", 4, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2"], + [ "0x168c", "0xffff", "0x0777", "0xe305", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe345", 6, 0, "Ubiquiti", "WispStation, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe3a5", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe3b5", 6, 0, "Ubiquiti", "airOS, XM/XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe3e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 300" ], + [ "0x168c", "0xffff", "0x0777", "0xe402", 10, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe405", 1, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe4a2", 1, 0, "Ubiquiti", "AirRouter" ], + [ "0x168c", "0xffff", "0x0777", "0xe4a5", 1, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe4b2", 9, 0, "Ubiquiti", "AirRouter, HP" ], + [ "0x168c", "0xffff", "0x0777", "0xe4d5", 5, 0, "Ubiquiti", "Rocket, M5, Titanium" ], + [ "0x168c", "0xffff", "0x0777", "0xe4e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400" ], + [ "0x168c", "0xffff", "0x0777", "0xe5e5", 4, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe6a2", 1, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe6b2", 1, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe6b5", 5, 0, "Ubiquiti", "Rocket, M5, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe6c2", 6, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe6e5", 4, 0, "Ubiquiti", "PowerBeam, M5, 400, ISO" ], + [ "0x168c", "0xffff", "0x0777", "0xe7f8", 2, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe805", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0xffff", "0x0777", "0xe812", 6, 0, "Ubiquiti", "NanoBeam, M2, 13" ], + [ "0x168c", "0xffff", "0x0777", "0xe815", 4, 0, "Ubiquiti", "NanoBeam, M5, 16" ], + [ "0x168c", "0xffff", "0x0777", "0xe825", 4, 0, "Ubiquiti", "NanoBeam, M5, 19" ], + [ "0x168c", "0xffff", "0x0777", "0xe835", 6, 0, "Ubiquiti", "AirGrid, M5, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe845", 1, 0, "Ubiquiti", "NanoStation, Loco, M5, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe855", 5, 0, "Ubiquiti", "NanoStation, M5, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe865", 6, 0, "Ubiquiti", "LiteBeam, M5" ], + [ "0x168c", "0xffff", "0x0777", "0xe866", 6, 0, "Ubiquiti", "NanoStation, M2, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe867", 2, 0, "Ubiquiti", "NanoStation, Loco, M2, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe868", 7, 0, "Ubiquiti", "Rocket, M2, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe869", 2, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe875", 4, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe879", 2, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe885", 4, 0, "Ubiquiti", "PowerBeam, M5, 620, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe895", 4, 0, "Ubiquiti", "airOS, XW" ], + [ "0x168c", "0xffff", "0x0777", "0xe8a5", 1, 0, "Ubiquiti", "NanoStation, Loco, M5"], + [ "0x168c", "0xffff", "0x0777", "0xe8b5", 5, 0, "Ubiquiti", "airOS, XM" ], + [ "0x168c", "0x001b", "0x0777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], + [ "0x168c", "0x001b", "0x7777", "0x3002", 10, 0, "Ubiquiti", "XR2" ], + [ "0x168c", "0x001b", "0x0777", "0x3b02", 10, 0, "Ubiquiti", "XR2.3" ], + [ "0x168c", "0x001b", "0x0777", "0x3c02", 10, 0, "Ubiquiti", "XR2.6" ], + [ "0x168c", "0x001b", "0x0777", "0x3b03", 10, 0, "Ubiquiti", "XR3-2.8" ], + [ "0x168c", "0x001b", "0x0777", "0x3c03", 10, 0, "Ubiquiti", "XR3-3.6" ], + [ "0x168c", "0x001b", "0x0777", "0x3003", 10, 0, "Ubiquiti", "XR3" ], + [ "0x168c", "0x001b", "0x0777", "0x3004", 10, 0, "Ubiquiti", "XR4" ], + [ "0x168c", "0x001b", "0x0777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], + [ "0x168c", "0x001b", "0x7777", "0x3005", 10, 0, "Ubiquiti", "XR5" ], + [ "0x168c", "0x001b", "0x0777", "0x3007", 10, 0, "Ubiquiti", "XR7" ], + [ "0x168c", "0x001b", "0x0777", "0x3009", 10, -1520, "Ubiquiti", "XR9" ], + [ "0x168c", "0x001b", "0x168c", "0x2063", 0, 0, "Atheros", "AR5413" ], + [ "0x168c", "0x0013", "0x168c", "0x1042", 1, 0, "Ubiquiti", "SRC" ], + [ "0x168c", "0x0013", "0x0777", "0x2041", 10, 0, "Ubiquiti", "SR2" ], + [ "0x168c", "0x0013", "0x0777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], + [ "0x168c", "0x0013", "0x7777", "0x2004", 6, 0, "Ubiquiti", "SR4" ], + [ "0x168c", "0x0013", "0x0777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], + [ "0x168c", "0x0013", "0x7777", "0x1004", 6, 0, "Ubiquiti", "SR4C" ], + [ "0x168c", "0x0013", "0x168c", "0x2042", 7, 0, "Ubiquiti", "SR5" ], + [ "0x168c", "0x0013", "0x7777", "0x2009", 12, -1500, "Ubiquiti", "SR9" ], + [ "0x168c", "0x0027", "0x168c", "0x2082", 7, 0, "Ubiquiti", "SR71A" ], + [ "0x168c", "0x0027", "0x0777", "0x4082", 7, 0, "Ubiquiti", "SR71" ], + [ "0x168c", "0x0029", "0x0777", "0x4005", 7, 0, "Ubiquiti", "SR71-15" ], + [ "0x168c", "0x002a", "0x0777", "0xe302", 12, 0, "Ubiquiti", "PicoStation, M2" ], + [ "0x168c", "0x002a", "0x0777", "0xe012", 12, 0, "Ubiquiti", "NanoStation, M2" ], + [ "0x168c", "0x002a", "0x0777", "0xe005", 5, 0, "Ubiquiti", "NanoStation, M5" ], + [ "0x168c", "0x002a", "0x0777", "0xe202", 12, 0, "Ubiquiti", "Bullet, M2" ], + [ "0x168c", "0x002a", "0x0777", "0xe805", 5, 0, "Ubiquiti", "Bullet, M5" ], + [ "0x168c", "0x002a", "0x0777", "0xe345", 0, 0, "Ubiquiti", "WispStation, M5" ], + [ "0x168c", "0x0029", "0x168c", "0xa094", 0, 0, "Atheros", "AR9220" ], + [ "0x168c", "0x0029", "0x168c", "0xa095", 0, 0, "Atheros", "AR9223" ], + [ "0x168c", "0x002a", "0x168c", "0xa093", 0, 0, "Atheros", "AR9280" ], + [ "0x168c", "0x002b", "0x168c", "0xa091", 0, 0, "Atheros", "AR9285" ], + [ "0x168c", "0x002d", "0x168c", "0x209a", 0, 0, "Atheros", "AR9287" ], + [ "0x168c", "0x002e", "0x1a3b", "0x1121", 0, 0, "Atheros", "AR9287" ], + [ "0x168c", "0x002e", "0x0777", "0xe0a2", 8, 0, "Ubiquiti", "NanoStation, Loco, M2, (XM)" ], + [ "0x168c", "0x002e", "0x168c", "0x30a4", 0, 0, "Atheros", "AR9287" ], + [ "0x168c", "0x002e", "0x168c", "0xa199", 0, 0, "Atheros", "AR9287" ], + [ "0x168c", "0x0030", "0x168c", "0x3112", 0, 0, "Atheros", "AR9380" ], + [ "0x168c", "0x0030", "0x168c", "0x3114", 0, 0, "Atheros", "AR9390" ], + [ "0x168c", "0x0033", "0x168c", "0xa120", 0, 0, "Atheros", "AR9580" ], + [ "0x168c", "0x0033", "0x168c", "0xa136", 0, 0, "Atheros", "AR9580" ], + [ "0x168c", "0x0033", "0x168c", "0x3123", 0, 0, "Atheros", "AR9590" ], + [ "0x168c", "0x0033", "0x19b6", "0xd014", 0, 0, "MikroTik", "R11e-5HnD" ], + [ "0x168c", "0x0033", "0x19b6", "0xd057", 0, 0, "MikroTik", "R11e-5HnDr2" ], + [ "0x168c", "0x0033", "0x19b6", "0xd016", 0, 0, "MikroTik", "R11e-2HPnD" ], + [ "0x168c", "0x0034", "0x17aa", "0x3214", 0, 0, "Atheros", "AR9462" ], + [ "0x168c", "0x003c", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9880" ], + [ "0x168c", "0x003c", "0x168c", "0x3223", 0, 0, "Qualcomm, Atheros", "QCA9880" ], + [ "0x168c", "0x003c", "0x1a56", "0x1420", 0, 0, "Qualcomm, Atheros", "QCA9862" ], + [ "0x168c", "0x003c", "0x19b6", "0xd03c", 0, 0, "Mikrotik", "R11e-5HacT" ], + [ "0x168c", "0x003c", "0x19b6", "0xd075", 0, 0, "Mikrotik", "R11e-5HacD" ], + [ "0x168c", "0x003e", "0x168c", "0x3361", 0, 0, "Qualcomm, Atheros", "QCA6174" ], + [ "0x168c", "0x0040", "0x168c", "0x0002", 0, 0, "Qualcomm, Atheros", "QCA9990" ], + [ "0x168c", "0x0046", "0x0777", "0xe535", 0, 0, "Qualcomm, Atheros", "QCA9994" ], + [ "0x168c", "0x0046", "0x0777", "0xe5a2", 0, 0, "Qualcomm, Atheros", "QCA9994" ], + [ "0x168c", "0x0050", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9887" ], + [ "0x168c", "0x0056", "0x0000", "0x0000", 0, 0, "Qualcomm, Atheros", "QCA9886" ], + [ "0x17cb", "0x1104", "0x17cb", "0x1104", 0, 0, "Qualcomm, Atheros", "QCN6024/9024/9074" ], + [ "0x1814", "0x3051", "0x1814", "0x0007", 0, 0, "Ralink", "Rt3051" ], + [ "0x1814", "0x3052", "0x1814", "0x0008", 0, 0, "Ralink", "Rt3052" ], + [ "0x1814", "0x3350", "0x1814", "0x000b", 0, 0, "Ralink", "Rt3350" ], + [ "0x1814", "0x3662", "0x1814", "0x000d", 0, 0, "Ralink", "Rt3662" ], + [ "0x11ab", "0x2a55", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8864" ], + [ "0x02df", "0x9135", "0x0000", "0x0000", 0, 0, "Marvell", "88W8887" ], + [ "0x11ab", "0x2b40", "0x11ab", "0x0000", 0, 0, "Marvell", "88W8964" ], + [ "0x02df", "0x9141", "0x0000", "0x0000", 0, 0, "Marvell", "88W8997" ], + [ "0x14c3", "0x0608", "0x14c3", "0x0608", 0, 0, "AMD", "RZ608" ], + [ "0x14c3", "0x7603", "0x14c3", "0x7603", 0, 0, "MediaTek", "MT7603E" ], + [ "0x14c3", "0x7610", "0x14c3", "0x7610", 0, 0, "MediaTek", "MT7610E" ], + [ "0x14c3", "0x7612", "0x14c3", "0x7612", 0, 0, "MediaTek", "MT7612E" ], + [ "0x14c3", "0x7663", "0x14c3", "0x7663", 0, 0, "MediaTek", "MT7613BE" ], + [ "0x14c3", "0x7615", "0x7615", "0x14c3", 0, 0, "MediaTek", "MT7615E" ], + [ "0x14c3", "0x7628", "0x14c3", "0x0004", 0, 0, "MediaTek", "MT76x8" ], + [ "0x14c3", "0x7650", "0x14c3", "0x7650", 0, 0, "MediaTek", "MT7610E" ], + [ "0x14c3", "0x7662", "0x14c3", "0x7662", 0, 0, "MediaTek", "MT76x2E" ], + [ "0x14c3", "0x7915", "0x14c3", "0x7915", 0, 0, "MediaTek", "MT7915E" ], + [ "0x14c3", "0x7906", "0x14c3", "0x7906", 0, 0, "MediaTek", "MT7916AN" ], + [ "0x14c3", "0x7990", "0x14C3", "0x6639", 0, 0, "MediaTek", "MT7996E" ], + [ "0x14c3", "0x7992", "0x14C3", "0x7992", 0, 0, "MediaTek", "MT7992E" ], + [ "0x14e4", "0xaa52", "0x14e4", "0xaa52", 0, 0, "Broadcom", "BCM43602" ], + [ "0x02d0", "0xa9a6", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], + [ "0x02d0", "0x4345", "0x0000", "0x0000", 0, 0, "Cypress", "CYW43455" ], + [ "0x1ae9", "0x0310", "0x1ae9", "0x0000", 0, 0, "Wilocity", "Wil6210" ], + [ "0x0000", "0x0000", "0x148f", "0x7601", 0, 0, "MediaTek", "MT7601U" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7961", 0, 0, "MediaTek", "MT7921AU" ], + [ "0x0000", "0x0000", "0x0b05", "0x1833", 0, 0, "ASUS", "USB-AC54" ], + [ "0x0000", "0x0000", "0x0b05", "0x17eb", 0, 0, "ASUS", "USB-AC55" ], + [ "0x0000", "0x0000", "0x0b05", "0x180b", 0, 0, "ASUS", "USB-N53, B1" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7612", 0, 0, "Aukey", "USBAC1200" ], + [ "0x0000", "0x0000", "0x057c", "0x8503", 0, 0, "AVM", "FRITZ!WLAN, AC860" ], + [ "0x0000", "0x0000", "0x7392", "0xb711", 0, 0, "Edimax", "EW-7722UAC" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7632", 0, 0, "High, Cloud", "HC-M7662BU1" ], + [ "0x0000", "0x0000", "0x2c4e", "0x0103", 0, 0, "Mercury", "UD13" ], + [ "0x0000", "0x0000", "0x0846", "0x9053", 0, 0, "Netgear", "A6210" ], + [ "0x0000", "0x0000", "0x045e", "0x02e6", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], + [ "0x0000", "0x0000", "0x045e", "0x02fe", 0, 0, "Microsoft", "XBox, One, Wireless, Adapter" ], + [ "0x0000", "0x0000", "0x148f", "0x7610", 0, 0, "MediaTek", "MT7610U" ], + [ "0x0000", "0x0000", "0x13b1", "0x003e", 0, 0, "Linksys", "AE6000" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7610", 0, 0, "Sabrent", "NTWLAC" ], + [ "0x0000", "0x0000", "0x7392", "0xa711", 0, 0, "Edimax", "7711MAC" ], + [ "0x0000", "0x0000", "0x148f", "0x761a", 0, 0, "TP-Link", "TL-WDN5200" ], + [ "0x0000", "0x0000", "0x0b05", "0x17d1", 0, 0, "ASUS", "USB-AC51" ], + [ "0x0000", "0x0000", "0x0b05", "0x17db", 0, 0, "ASUS", "USB-AC50" ], + [ "0x0000", "0x0000", "0x0df6", "0x0075", 0, 0, "Sitecom", "WLA-3100" ], + [ "0x0000", "0x0000", "0x2019", "0xab31", 0, 0, "Planex", "GW-450D" ], + [ "0x0000", "0x0000", "0x2001", "0x3d02", 0, 0, "D-Link", "DWA-171, rev, B1" ], + [ "0x0000", "0x0000", "0x0586", "0x3425", 0, 0, "Zyxel", "NWD6505" ], + [ "0x0000", "0x0000", "0x07b8", "0x7610", 0, 0, "AboCom", "AU7212" ], + [ "0x0000", "0x0000", "0x04bb", "0x0951", 0, 0, "I-O, DATA", "WN-AC433UK" ], + [ "0x0000", "0x0000", "0x057c", "0x8502", 0, 0, "AVM", "FRITZ!WLAN, AC430" ], + [ "0x0000", "0x0000", "0x293c", "0x5702", 0, 0, "Comcast", "Xfinity, KXW02AAA" ], + [ "0x0000", "0x0000", "0x20f4", "0x806b", 0, 0, "TRENDnet", "TEW-806UBH" ], + [ "0x0000", "0x0000", "0x7392", "0xc711", 0, 0, "Devolo", "WiFi, Stick, ac" ], + [ "0x0000", "0x0000", "0x0df6", "0x0079", 0, 0, "Sitecom", "WL-356" ], + [ "0x0000", "0x0000", "0x2357", "0x0123", 0, 0, "TP-Link", "T2UHP, US, v1" ], + [ "0x0000", "0x0000", "0x2357", "0x010b", 0, 0, "TP-Link", "T2UHP, UN, v1" ], + [ "0x0000", "0x0000", "0x2357", "0x0105", 0, 0, "TP-Link", "Archer, T1U" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7630", 0, 0, "MediaTek", "MT7630U" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7650", 0, 0, "MediaTek", "MT7650U" ], + [ "0x0000", "0x0000", "0x0e8d", "0x7663", 0, 0, "MediaTek", "MT7663U" ], + [ "0x0000", "0x0000", "0x043e", "0x310c", 0, 0, "LG", "LGSBWAC02" ], + [ "0x0000", "0x0000", "0x0bda", "0x8176", 0, 0, "Realtek", "RTL8188CU" ], + [ "0x0000", "0x0000", "0x0bda", "0xf179", 0, 0, "Realtek", "RTL8188FTV" ] + ], + "compatible": { + "qca,ar9130-wmac": [ "Atheros", "AR9130" ], + "qca,ar9330-wmac": [ "Atheros", "AR9330" ], + "qca,ar9340-wmac": [ "Atheros", "AR9340" ], + "qca,qca9530-wmac": [ "Qualcomm Atheros", "QCA9530" ], + "qca,qca9550-wmac": [ "Qualcomm Atheros", "QCA9550" ], + "qca,qca9560-wmac": [ "Qualcomm Atheros", "QCA9560" ], + "qcom,ipq4019-wifi": [ "Qualcomm Atheros", "IPQ4019" ], + "qcom,ipq6018-wifi": [ "Qualcomm Atheros", "IPQ6018" ], + "qcom,ipq8074-wifi": [ "Qualcomm Atheros", "IPQ8074" ], + "mediatek,mt7622-wmac": [ "MediaTek", "MT7622" ], + "mediatek,mt7628-wmac": [ "MediaTek", "MT7628" ], + "mediatek,mt7981-wmac": [ "MediaTek", "MT7981" ], + "mediatek,mt7986-wmac": [ "MediaTek", "MT7986" ], + "ralink,rt2880-wmac": [ "Ralink", "Rt2880" ], + "ralink,rt3050-wmac": [ "Ralink", "Rt3050" ], + "ralink,rt3352-wmac": [ "Ralink", "Rt3352" ], + "ralink,rt3883-wmac": [ "Ralink", "Rt3883" ], + "ralink,rt5350-wmac": [ "Ralink", "Rt5350" ], + "ralink,rt7620-wmac": [ "MediaTek", "MT7620" ] + } +} diff --git a/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh b/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh index 32aac53baebc6a..da7f4e0c6f45bf 100755 --- a/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh +++ b/package/network/config/wifi-scripts/files/lib/netifd/wireless/mac80211.sh @@ -29,6 +29,7 @@ drv_mac80211_init_device_config() { config_add_string path phy 'macaddr:macaddr' config_add_string tx_burst config_add_string distance + config_add_string ifname_prefix config_add_int radio beacon_int chanbw frag rts config_add_int rxantenna txantenna txpower min_tx_power config_add_int num_global_macaddr multiple_bssid @@ -660,9 +661,9 @@ mac80211_check_ap() { } mac80211_set_ifname() { - local phy="$1" - local prefix="$2" - eval "ifname=\"$phy-$prefix\${idx_$prefix:-0}\"; idx_$prefix=\$((\${idx_$prefix:-0 } + 1))" + local prefix="$1" + local type="$2" + eval "ifname=\"$prefix$type\${idx_$type:-0}\"; idx_$type=\$((\${idx_$type:-0 } + 1))" } mac80211_prepare_vif() { @@ -679,7 +680,7 @@ mac80211_prepare_vif() { monitor) prefix=mon;; esac - mac80211_set_ifname "$phy$vif_phy_suffix" "$prefix" + mac80211_set_ifname "$ifname_prefix" "$prefix" } append active_ifnames "$ifname" @@ -1108,7 +1109,8 @@ drv_mac80211_setup() { txpower \ rxantenna txantenna \ frag rts beacon_int:100 htmode \ - num_global_macaddr:1 multiple_bssid + num_global_macaddr:1 multiple_bssid \ + ifname_prefix json_get_values basic_rate_list basic_rate json_get_values scan_list scan_list json_select .. @@ -1127,6 +1129,8 @@ drv_mac80211_setup() { return 1 } + set_default ifname_prefix "$phy$vif_phy_suffix-" + local wdev local cwdev local found diff --git a/package/network/config/wifi-scripts/files/sbin/wifi b/package/network/config/wifi-scripts/files/sbin/wifi index ba2d392c78ae95..376566094481e9 100755 --- a/package/network/config/wifi-scripts/files/sbin/wifi +++ b/package/network/config/wifi-scripts/files/sbin/wifi @@ -37,135 +37,22 @@ wifi_isup() { return 0 } -find_net_config() {( - local vif="$1" - local cfg - local ifname - - config_get cfg "$vif" network - - [ -z "$cfg" ] && { - include /lib/network - scan_interfaces - - config_get ifname "$vif" ifname - - cfg="$(find_config "$ifname")" - } - [ -z "$cfg" ] && return 0 - echo "$cfg" -)} - - -bridge_interface() {( - local cfg="$1" - [ -z "$cfg" ] && return 0 - - include /lib/network - scan_interfaces - - for cfg in $cfg; do - config_get iftype "$cfg" type - [ "$iftype" = bridge ] && config_get "$cfg" ifname - prepare_interface_bridge "$cfg" - return $? - done -)} - -prepare_key_wep() { - local key="$1" - local hex=1 - - echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0 - [ "${#key}" -eq 10 -a $hex -eq 1 ] || \ - [ "${#key}" -eq 26 -a $hex -eq 1 ] || { - [ "${key:0:2}" = "s:" ] && key="${key#s:}" - key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')" - } - echo "$key" -} - -wifi_fixup_hwmode() { - local device="$1" - local default="$2" - local hwmode hwmode_11n - - config_get channel "$device" channel - config_get hwmode "$device" hwmode - case "$hwmode" in - 11bg) hwmode=bg;; - 11a) hwmode=a;; - 11ad) hwmode=ad;; - 11b) hwmode=b;; - 11g) hwmode=g;; - 11n*) - hwmode_11n="${hwmode##11n}" - case "$hwmode_11n" in - a|g) ;; - default) hwmode_11n="$default" - esac - config_set "$device" hwmode_11n "$hwmode_11n" - ;; - *) - hwmode= - if [ "${channel:-0}" -gt 0 ]; then - if [ "${channel:-0}" -gt 14 ]; then - hwmode=a - else - hwmode=g - fi - else - hwmode="$default" - fi - ;; - esac - config_set "$device" hwmode "$hwmode" -} - -_wifi_updown() { - for device in ${2:-$DEVICES}; do ( - config_get disabled "$device" disabled - [ "$disabled" = "1" ] && { - echo "'$device' is disabled" - set disable - } - config_get iftype "$device" type - if eval "type ${1}_$iftype" 2>/dev/null >/dev/null; then - eval "scan_$iftype '$device'" - eval "${1}_$iftype '$device'" || echo "$device($iftype): ${1} failed" - elif [ ! -f /lib/netifd/wireless/$iftype.sh ]; then - echo "$device($iftype): Interface type not supported" - fi - ); done -} - wifi_updown() { cmd=down [ enable = "$1" ] && { - _wifi_updown disable "$2" ubus_wifi_cmd "$cmd" "$2" ubus call network reload - scan_wifi cmd=up } [ reconf = "$1" ] && { ubus call network reload - scan_wifi cmd=reconf } ubus_wifi_cmd "$cmd" "$2" - _wifi_updown "$@" -} - -wifi_reload_legacy() { - _wifi_updown "disable" "$1" - scan_wifi - _wifi_updown "enable" "$1" } wifi_reload() { ubus call network reload - wifi_reload_legacy } wifi_detect_notice() { @@ -214,75 +101,9 @@ wifi_config() { ); done } -start_net() {( - local iface="$1" - local config="$2" - local vifmac="$3" - - [ -f "/var/run/$iface.pid" ] && kill "$(cat /var/run/${iface}.pid)" 2>/dev/null - [ -z "$config" ] || { - include /lib/network - scan_interfaces - for config in $config; do - setup_interface "$iface" "$config" "" "$vifmac" - done - } -)} - -set_wifi_up() { - local cfg="$1" - local ifname="$2" - uci_set_state wireless "$cfg" up 1 - uci_set_state wireless "$cfg" ifname "$ifname" -} - -set_wifi_down() { - local cfg="$1" - local vifs vif vifstr - - [ -f "/var/run/wifi-${cfg}.pid" ] && - kill "$(cat "/var/run/wifi-${cfg}.pid")" 2>/dev/null - uci_revert_state wireless "$cfg" - config_get vifs "$cfg" vifs - for vif in $vifs; do - uci_revert_state wireless "$vif" - done -} - -scan_wifi() { - local cfgfile="$1" - DEVICES= - config_cb() { - local type="$1" - local section="$2" - - # section start - case "$type" in - wifi-device) - append DEVICES "$section" - config_set "$section" vifs "" - config_set "$section" ht_capab "" - ;; - esac - - # section end - config_get TYPE "$CONFIG_SECTION" TYPE - case "$TYPE" in - wifi-iface) - config_get device "$CONFIG_SECTION" device - config_get vifs "$device" vifs - append vifs "$CONFIG_SECTION" - config_set "$device" vifs "$vifs" - ;; - esac - } - config_load "${cfgfile:-wireless}" -} - DEVICES= DRIVERS= include /lib/wifi -scan_wifi case "$1" in down) wifi_updown "disable" "$2";; @@ -291,7 +112,6 @@ case "$1" in status) ubus_wifi_cmd "status" "$2";; isup) wifi_isup "$2"; exit $?;; reload) wifi_reload "$2";; - reload_legacy) wifi_reload_legacy "$2";; --help|help) usage;; reconf) wifi_updown "reconf" "$2";; ''|up) wifi_updown "enable" "$2";; diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile index 7757f4e14adb92..fe2e11479b1fa8 100644 --- a/package/network/services/hostapd/Makefile +++ b/package/network/services/hostapd/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=hostapd -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE_URL:=https://w1.fi/hostap.git PKG_SOURCE_PROTO:=git @@ -109,7 +109,7 @@ ifeq ($(SSL_VARIANT),openssl) DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y endif ifeq ($(LOCAL_VARIANT),full) - DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y + DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_EAP_PWD=y endif endif @@ -124,7 +124,7 @@ ifeq ($(SSL_VARIANT),wolfssl) DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 endif ifeq ($(LOCAL_VARIANT),full) - DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 + DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 CONFIG_EAP_PWD=y endif endif @@ -139,7 +139,7 @@ ifeq ($(SSL_VARIANT),mbedtls) DRIVER_MAKEOPTS += CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 endif ifeq ($(LOCAL_VARIANT),full) - DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 + DRIVER_MAKEOPTS += CONFIG_OWE=y CONFIG_SUITEB192=y CONFIG_AP=y CONFIG_MESH=y CONFIG_WPS_NFC=1 CONFIG_EAP_PWD=y endif endif diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config index d2397c850568f6..2ba0b72383f9d1 100644 --- a/package/network/services/hostapd/files/hostapd-full.config +++ b/package/network/services/hostapd/files/hostapd-full.config @@ -94,7 +94,7 @@ CONFIG_EAP_TTLS=y #CONFIG_EAP_PAX=y # EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK) -#CONFIG_EAP_PSK=y +CONFIG_EAP_PSK=y # EAP-pwd for the integrated EAP server (secure authentication with a password) #CONFIG_EAP_PWD=y diff --git a/package/network/services/hostapd/files/hostapd.uc b/package/network/services/hostapd/files/hostapd.uc index 2d9ce2874901d2..c1db91e4d4f944 100644 --- a/package/network/services/hostapd/files/hostapd.uc +++ b/package/network/services/hostapd/files/hostapd.uc @@ -45,6 +45,7 @@ hostapd.data.bss_info_fields = { wpa_pairwise: true, auth_algs: true, ieee80211w: true, + owe_transition_ifname: true, }; function iface_remove(cfg) diff --git a/package/network/services/hostapd/files/wpad.json b/package/network/services/hostapd/files/wpad.json index c73f3d98bd1d4c..3dc7bd3c988b92 100644 --- a/package/network/services/hostapd/files/wpad.json +++ b/package/network/services/hostapd/files/wpad.json @@ -1,22 +1,27 @@ { "bounding": [ "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", "CAP_NET_RAW" ], "effective": [ "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", "CAP_NET_RAW" ], "ambient": [ "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", "CAP_NET_RAW" ], "permitted": [ "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", "CAP_NET_RAW" ], "inheritable": [ "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", "CAP_NET_RAW" ] } diff --git a/package/network/services/hostapd/patches/763-radius-wispr.patch b/package/network/services/hostapd/patches/763-radius-wispr.patch new file mode 100644 index 00000000000000..da81a623e76c25 --- /dev/null +++ b/package/network/services/hostapd/patches/763-radius-wispr.patch @@ -0,0 +1,105 @@ +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -2035,6 +2035,25 @@ static int ieee802_1x_update_vlan(struct + } + #endif /* CONFIG_NO_VLAN */ + ++static int ieee802_1x_update_wispr(struct hostapd_data *hapd, ++ struct sta_info *sta, ++ struct radius_msg *msg) ++{ ++ memset(sta->bandwidth, 0, sizeof(sta->bandwidth)); ++ ++ if (radius_msg_get_wispr(msg, sta->bandwidth)) ++ return 0; ++ ++ if (!sta->bandwidth[0] && !sta->bandwidth[1]) ++ return 0; ++ ++ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, ++ HOSTAPD_LEVEL_INFO, ++ "received wispr bandwidth from RADIUS server %d/%d", ++ sta->bandwidth[0], sta->bandwidth[1]); ++ ++ return 0; ++} + + /** + * ieee802_1x_receive_auth - Process RADIUS frames from Authentication Server +@@ -2151,6 +2170,7 @@ ieee802_1x_receive_auth(struct radius_ms + ieee802_1x_check_hs20(hapd, sta, msg, + session_timeout_set ? + (int) session_timeout : -1); ++ ieee802_1x_update_wispr(hapd, sta, msg); + break; + case RADIUS_CODE_ACCESS_REJECT: + sm->eap_if->aaaFail = true; +--- a/src/ap/sta_info.h ++++ b/src/ap/sta_info.h +@@ -95,6 +95,7 @@ struct sta_info { + u8 supported_rates[WLAN_SUPP_RATES_MAX]; + int supported_rates_len; + u8 qosinfo; /* Valid when WLAN_STA_WMM is set */ ++ u32 bandwidth[2]; + + #ifdef CONFIG_MESH + enum mesh_plink_state plink_state; +--- a/src/radius/radius.c ++++ b/src/radius/radius.c +@@ -1339,6 +1339,35 @@ radius_msg_get_cisco_keys(struct radius_ + return keys; + } + ++#define RADIUS_VENDOR_ID_WISPR 14122 ++#define RADIUS_WISPR_AV_BW_UP 7 ++#define RADIUS_WISPR_AV_BW_DOWN 8 ++ ++int ++radius_msg_get_wispr(struct radius_msg *msg, u32 *bandwidth) ++{ ++ int i; ++ ++ if (msg == NULL || bandwidth == NULL) ++ return 1; ++ ++ for (i = 0; i < 2; i++) { ++ size_t keylen; ++ u8 *key; ++ ++ key = radius_msg_get_vendor_attr(msg, RADIUS_VENDOR_ID_WISPR, ++ RADIUS_WISPR_AV_BW_UP + i, &keylen); ++ if (!key) ++ continue; ++ ++ if (keylen == 4) ++ bandwidth[i] = ntohl(*((u32 *)key)); ++ os_free(key); ++ } ++ ++ return 0; ++} ++ + + int radius_msg_add_mppe_keys(struct radius_msg *msg, + const u8 *req_authenticator, +--- a/src/radius/radius.h ++++ b/src/radius/radius.h +@@ -233,6 +233,10 @@ enum { + RADIUS_VENDOR_ATTR_WFA_HS20_T_C_URL = 10, + }; + ++#define RADIUS_VENDOR_ID_WISPR 14122 ++#define RADIUS_WISPR_AV_BW_UP 7 ++#define RADIUS_WISPR_AV_BW_DOWN 8 ++ + #ifdef _MSC_VER + #pragma pack(pop) + #endif /* _MSC_VER */ +@@ -306,6 +310,7 @@ radius_msg_get_ms_keys(struct radius_msg + struct radius_ms_mppe_keys * + radius_msg_get_cisco_keys(struct radius_msg *msg, struct radius_msg *sent_msg, + const u8 *secret, size_t secret_len); ++int radius_msg_get_wispr(struct radius_msg *msg, u32 *bandwidth); + int radius_msg_add_mppe_keys(struct radius_msg *msg, + const u8 *req_authenticator, + const u8 *secret, size_t secret_len, diff --git a/package/network/services/hostapd/src/src/ap/ubus.c b/package/network/services/hostapd/src/src/ap/ubus.c index 22567207556599..395e2c2dbce3f8 100644 --- a/package/network/services/hostapd/src/src/ap/ubus.c +++ b/package/network/services/hostapd/src/src/ap/ubus.c @@ -369,6 +369,7 @@ hostapd_bss_get_status(struct ubus_context *ctx, struct ubus_object *obj, &op_class, &channel); blob_buf_init(&b, 0); + blobmsg_add_string(&b, "driver", hapd->driver->name); blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); blobmsg_printf(&b, "bssid", MACSTR, MAC2STR(hapd->conf->bssid)); @@ -1657,6 +1658,85 @@ static int avl_compare_macaddr(const void *k1, const void *k2, void *ptr) return memcmp(k1, k2, ETH_ALEN); } +static int +hostapd_wired_get_clients(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + struct hostap_sta_driver_data sta_driver_data; + struct sta_info *sta; + void *list, *c; + char mac_buf[20]; + static const struct { + const char *name; + uint32_t flag; + } sta_flags[] = { + { "authorized", WLAN_STA_AUTHORIZED }, + }; + + blob_buf_init(&b, 0); + list = blobmsg_open_table(&b, "clients"); + for (sta = hapd->sta_list; sta; sta = sta->next) { + void *r; + int i; + + sprintf(mac_buf, MACSTR, MAC2STR(sta->addr)); + c = blobmsg_open_table(&b, mac_buf); + for (i = 0; i < ARRAY_SIZE(sta_flags); i++) + blobmsg_add_u8(&b, sta_flags[i].name, + !!(sta->flags & sta_flags[i].flag)); + + blobmsg_close_table(&b, c); + } + blobmsg_close_array(&b, list); + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +static int +hostapd_wired_get_status(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + char iface_name[17]; + + blob_buf_init(&b, 0); + blobmsg_add_string(&b, "driver", hapd->driver->name); + blobmsg_add_string(&b, "status", hostapd_state_text(hapd->iface->state)); + + snprintf(iface_name, 17, "%s", hapd->iface->phy); + blobmsg_add_string(&b, "iface", iface_name); + + ubus_send_reply(ctx, req, b.head); + + return 0; +} + +static int +hostapd_wired_del_clients(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct hostapd_data *hapd = container_of(obj, struct hostapd_data, ubus.obj); + + hostapd_free_stas(hapd); + + return 0; +} + +static const struct ubus_method wired_methods[] = { + UBUS_METHOD_NOARG("reload", hostapd_bss_reload), + UBUS_METHOD_NOARG("get_clients", hostapd_wired_get_clients), + UBUS_METHOD_NOARG("del_clients", hostapd_wired_del_clients), + UBUS_METHOD_NOARG("get_status", hostapd_wired_get_status), +}; + +static struct ubus_object_type wired_object_type = + UBUS_OBJECT_TYPE("hostapd_wired", wired_methods); + void hostapd_ubus_add_bss(struct hostapd_data *hapd) { struct ubus_object *obj = &hapd->ubus.obj; @@ -1676,9 +1756,15 @@ void hostapd_ubus_add_bss(struct hostapd_data *hapd) avl_init(&hapd->ubus.banned, avl_compare_macaddr, false, NULL); obj->name = name; - obj->type = &bss_object_type; - obj->methods = bss_object_type.methods; - obj->n_methods = bss_object_type.n_methods; + if (!strcmp(hapd->driver->name, "wired")) { + obj->type = &wired_object_type; + obj->methods = wired_object_type.methods; + obj->n_methods = wired_object_type.n_methods; + } else { + obj->type = &bss_object_type; + obj->methods = bss_object_type.methods; + obj->n_methods = bss_object_type.n_methods; + } ret = ubus_add_object(ctx, obj); hostapd_ubus_ref_inc(); } @@ -1876,6 +1962,13 @@ void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info * blobmsg_add_string(&b, "ifname", hapd->conf->iface); if (auth_alg) blobmsg_add_string(&b, "auth-alg", auth_alg); + if (sta->bandwidth[0] || sta->bandwidth[1]) { + void *r = blobmsg_open_array(&b, "rate-limit"); + + blobmsg_add_u32(&b, "", sta->bandwidth[0]); + blobmsg_add_u32(&b, "", sta->bandwidth[1]); + blobmsg_close_array(&b, r); + } ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); } diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index d81ed62620afd6..fe160f6ef326aa 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -18,6 +18,7 @@ PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=GPL-2.0 PKG_BUILD_FLAGS:=no-lto +PKG_CONFIG_DEPENDS:=CONFIG_WIFI_SCRIPTS_UCODE IWINFO_ABI_VERSION:=20230701 @@ -62,7 +63,7 @@ define Package/iwinfo SECTION:=utils CATEGORY:=Utilities TITLE:=Generalized Wireless Information utility - DEPENDS:=+libiwinfo + DEPENDS:=+libiwinfo @!WIFI_SCRIPTS_UCODE endef define Package/iwinfo/description diff --git a/package/system/apk/Makefile b/package/system/apk/Makefile index 693c008df95e45..c045a990f0aa5d 100644 --- a/package/system/apk/Makefile +++ b/package/system/apk/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL=https://gitlab.alpinelinux.org/alpine/apk-tools.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2024-11-13 -PKG_SOURCE_VERSION:=e3464d096708b270138653ef93db59134bb24813 -PKG_MIRROR_HASH:=cc633e5c294c9d92391fba5537dfe2f12f82011b55d282beb0d5d7ceba212962 +PKG_SOURCE_DATE:=2024-11-30 +PKG_SOURCE_VERSION:=8d93a79fb8958607f097be2c4ac97f4596faf91d +PKG_MIRROR_HASH:=565c87fac26e696c362c2fe85159cc3ed2fd27153f244c2e9dc0fd7fa67a4173 PKG_VERSION=3.0.0_pre$(subst -,,$(PKG_SOURCE_DATE)) @@ -27,7 +27,7 @@ define Package/apk/default SECTION:=base CATEGORY:=Base system TITLE:=apk package manager - DEPENDS:=+zlib + DEPENDS:=+zlib +wget URL:=$(PKG_SOURCE_URL) PROVIDES:=apk endef @@ -53,10 +53,12 @@ MESON_HOST_VARS+=VERSION=$(PKG_VERSION) MESON_VARS+=VERSION=$(PKG_VERSION) MESON_COMMON_ARGS = \ + -Db_lto=true \ -Dcompressed-help=false \ -Ddocs=disabled \ -Dhelp=enabled \ -Dlua_version=5.1 \ + -Ddefault_library=static \ -Durl_backend=wget \ -Dzstd=false @@ -81,9 +83,6 @@ define Package/apk/default/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/apk $(1)/usr/bin/apk - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_INSTALL_DIR)/usr/lib/libapk.so.* $(1)/usr/lib/ - $(INSTALL_DIR) $(1)/etc/apk/repositories.d $(INSTALL_DATA) ./files/customfeeds.list $(1)/etc/apk/repositories.d/customfeeds.list endef diff --git a/package/system/fstools/Makefile b/package/system/fstools/Makefile index 419cdfff9aea2c..2f30915bf98525 100644 --- a/package/system/fstools/Makefile +++ b/package/system/fstools/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/fstools.git -PKG_MIRROR_HASH:=5f04ce2b346d9a48468180dd9601ca0fcc83896ebf5466855578e766646e14a1 -PKG_SOURCE_DATE:=2024-07-14 -PKG_SOURCE_VERSION:=408c2cc48e6694446c89da7f8121b399063e1067 +PKG_MIRROR_HASH:=b0de38a758cccdb234d909eda3bf4de40d260f75000f27d30e7d1bc4158b1094 +PKG_SOURCE_DATE:=2024-12-02 +PKG_SOURCE_VERSION:=49d36ba2d1ada4ca177612cfbe904beb286dcab7 CMAKE_INSTALL:=1 PKG_LICENSE:=GPL-2.0 @@ -95,9 +95,10 @@ endef define Package/fstools/install $(INSTALL_DIR) $(1)/sbin $(1)/lib - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{mount_root,jffs2reset} $(1)/sbin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/{mount_root,factoryreset} $(1)/sbin/ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libfstools.so $(1)/lib/ - $(LN) jffs2reset $(1)/sbin/jffs2mark + $(LN) factoryreset $(1)/sbin/jffs2mark + $(LN) factoryreset $(1)/sbin/jffs2reset endef define Package/snapshot-tool/install diff --git a/package/system/rpcd/Makefile b/package/system/rpcd/Makefile index da031db8498d0f..447bec1ac4e0f6 100644 --- a/package/system/rpcd/Makefile +++ b/package/system/rpcd/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/rpcd.git -PKG_MIRROR_HASH:=67b2cb985d8712a3e5a17ebf8c74fd35d553c8f9a4197616f9a3649a8740cc33 -PKG_SOURCE_DATE:=2024-09-17 -PKG_SOURCE_VERSION:=9f4b86e70352ab9ca6aa272d096419acc53e2390 +PKG_MIRROR_HASH:=081058ace6445fc8bf67e49f51e1bc87bf36bd0a38b34e6ff8976d7260bf2c9f +PKG_SOURCE_DATE:=2024-12-02 +PKG_SOURCE_VERSION:=cc9a471c32e106fa9ee045540613fefdc31c5cd2 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/system/uci/Makefile b/package/system/uci/Makefile index c8f661c68434f8..6b902a9c24f9d3 100644 --- a/package/system/uci/Makefile +++ b/package/system/uci/Makefile @@ -13,9 +13,9 @@ PKG_RELEASE:=1 PKG_SOURCE_URL=$(PROJECT_GIT)/project/uci.git PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2023-08-10 -PKG_SOURCE_VERSION:=5781664d5087ccc4b5ab58505883231212dbedbc -PKG_MIRROR_HASH:=0ca4a29c077e85a7cfe69916c3ceb2bee98662b6268befc3c02519939647f984 +PKG_SOURCE_DATE:=2024-11-26 +PKG_SOURCE_VERSION:=10f7996ec29449915640acca5d65b592365a4b14 +PKG_MIRROR_HASH:=8556add0dd77b85a5702faa94feb811606390c045d7f5004317a4ab3e07f773b PKG_LICENSE:=LGPL-2.1 PKG_LICENSE_FILES:= diff --git a/package/utils/busybox/Config-defaults.in b/package/utils/busybox/Config-defaults.in index f88f395e2cb5c9..26d3e642ce7b89 100644 --- a/package/utils/busybox/Config-defaults.in +++ b/package/utils/busybox/Config-defaults.in @@ -28,6 +28,9 @@ config BUSYBOX_DEFAULT_FEATURE_COMPRESS_USAGE config BUSYBOX_DEFAULT_LFS bool default y +config BUSYBOX_DEFAULT_TIME64 + bool + default n config BUSYBOX_DEFAULT_PAM bool default n @@ -1181,6 +1184,9 @@ config BUSYBOX_DEFAULT_FEATURE_FIND_EXEC config BUSYBOX_DEFAULT_FEATURE_FIND_EXEC_PLUS bool default n +config BUSYBOX_DEFAULT_FEATURE_FIND_EXEC_OK + bool + default n config BUSYBOX_DEFAULT_FEATURE_FIND_USER bool default y @@ -2051,6 +2057,9 @@ config BUSYBOX_DEFAULT_FLASH_UNLOCK config BUSYBOX_DEFAULT_FLASHCP bool default n +config BUSYBOX_DEFAULT_GETFATTR + bool + default n config BUSYBOX_DEFAULT_HDPARM bool default n @@ -2457,6 +2466,9 @@ config BUSYBOX_DEFAULT_FEATURE_IP_ADDRESS config BUSYBOX_DEFAULT_FEATURE_IP_LINK bool default y +config BUSYBOX_DEFAULT_FEATURE_IP_LINK_CAN + bool + default n config BUSYBOX_DEFAULT_FEATURE_IP_ROUTE bool default y @@ -2682,6 +2694,9 @@ config BUSYBOX_DEFAULT_ZCIP config BUSYBOX_DEFAULT_UDHCPD bool default n +config BUSYBOX_DEFAULT_FEATURE_UDHCPD_BOOTP + bool + default n config BUSYBOX_DEFAULT_FEATURE_UDHCPD_BASE_IP_ON_MAC bool default n @@ -3042,9 +3057,6 @@ config BUSYBOX_DEFAULT_ASH_PRINTF config BUSYBOX_DEFAULT_ASH_TEST bool default y -config BUSYBOX_DEFAULT_ASH_SLEEP - bool - default n config BUSYBOX_DEFAULT_ASH_HELP bool default n diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile index 4ef470df755890..4f155b7a2503b2 100644 --- a/package/utils/busybox/Makefile +++ b/package/utils/busybox/Makefile @@ -5,14 +5,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=busybox -PKG_VERSION:=1.36.1 +PKG_VERSION:=1.37.0 PKG_RELEASE:=2 PKG_FLAGS:=essential PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=https://www.busybox.net/downloads \ https://sources.buildroot.net/$(PKG_NAME) -PKG_HASH:=b8cc24c9574d809e7279c3be349795c5d5ceb6fdf19ca709f80cde50e47de314 +PKG_HASH:=3311dff32e746499f4df0d5df04d7eb396382d7e108bb9250e7b519b837043a4 PKG_BUILD_DEPENDS:=BUSYBOX_CONFIG_PAM:libpam PKG_BUILD_PARALLEL:=1 diff --git a/package/utils/busybox/config/Config.in b/package/utils/busybox/config/Config.in index f30629839e0d86..f1bd8ef12fda9e 100644 --- a/package/utils/busybox/config/Config.in +++ b/package/utils/busybox/config/Config.in @@ -107,6 +107,17 @@ config BUSYBOX_CONFIG_LFS programs that can benefit from large file support include dd, gzip, cp, mount, tar. +config BUSYBOX_CONFIG_TIME64 + bool "Support 64bit wide time types" + default BUSYBOX_DEFAULT_TIME64 + depends on BUSYBOX_CONFIG_LFS + help + Make times later than 2038 representable for several libc syscalls + (stat, clk_gettime etc.). Note this switch is specific to glibc + and has no effect on platforms that already use 64bit wide time types + (i.e. all 64bit archs and some selected 32bit archs (currently riscv + and x32)). + config BUSYBOX_CONFIG_PAM bool "Support PAM (Pluggable Authentication Modules)" default BUSYBOX_DEFAULT_PAM diff --git a/package/utils/busybox/config/archival/Config.in b/package/utils/busybox/config/archival/Config.in index ac2b3d20562e03..a3eebdce0f003d 100644 --- a/package/utils/busybox/config/archival/Config.in +++ b/package/utils/busybox/config/archival/Config.in @@ -80,7 +80,7 @@ config BUSYBOX_CONFIG_FEATURE_GUNZIP_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_GUNZIP_LONG_OPTIONS depends on (BUSYBOX_CONFIG_GUNZIP || BUSYBOX_CONFIG_ZCAT) && BUSYBOX_CONFIG_LONG_OPTS config BUSYBOX_CONFIG_BUNZIP2 - bool "bunzip2 (8.7 kb)" + bool "bunzip2 (9.1 kb)" default BUSYBOX_DEFAULT_BUNZIP2 select BUSYBOX_CONFIG_FEATURE_BZIP2_DECOMPRESS help @@ -94,13 +94,13 @@ config BUSYBOX_CONFIG_BUNZIP2 should probably say N here. config BUSYBOX_CONFIG_BZCAT - bool "bzcat (8.7 kb)" + bool "bzcat (9 kb)" default BUSYBOX_DEFAULT_BZCAT select BUSYBOX_CONFIG_FEATURE_BZIP2_DECOMPRESS help Alias to "bunzip2 -c". config BUSYBOX_CONFIG_UNLZMA - bool "unlzma (7.5 kb)" + bool "unlzma (7.8 kb)" default BUSYBOX_DEFAULT_UNLZMA help unlzma is a compression utility using the Lempel-Ziv-Markov chain @@ -109,7 +109,7 @@ config BUSYBOX_CONFIG_UNLZMA compressors. config BUSYBOX_CONFIG_LZCAT - bool "lzcat (7.5 kb)" + bool "lzcat (7.8 kb)" default BUSYBOX_DEFAULT_LZCAT help Alias to "unlzma -c". @@ -229,7 +229,7 @@ config BUSYBOX_CONFIG_DPKG This implementation of dpkg has a number of limitations, you should use the official dpkg if possible. config BUSYBOX_CONFIG_DPKG_DEB - bool "dpkg-deb (30 kb)" + bool "dpkg-deb (29 kb)" default BUSYBOX_DEFAULT_DPKG_DEB select BUSYBOX_CONFIG_FEATURE_SEAMLESS_GZ help @@ -282,7 +282,7 @@ config BUSYBOX_CONFIG_FEATURE_GZIP_DECOMPRESS This will be automatically selected if gunzip or zcat is enabled. config BUSYBOX_CONFIG_LZOP - bool "lzop (12 kb)" + bool "lzop (13 kb)" default BUSYBOX_DEFAULT_LZOP help Lzop compression/decompresion. diff --git a/package/utils/busybox/config/console-tools/Config.in b/package/utils/busybox/config/console-tools/Config.in index cf224e5e2e8dc6..35161782123c7e 100644 --- a/package/utils/busybox/config/console-tools/Config.in +++ b/package/utils/busybox/config/console-tools/Config.in @@ -7,39 +7,39 @@ menu "Console Utilities" config BUSYBOX_CONFIG_CHVT - bool "chvt (2 kb)" + bool "chvt (2.2 kb)" default BUSYBOX_DEFAULT_CHVT help This program is used to change to another terminal. Example: chvt 4 (change to terminal /dev/tty4) config BUSYBOX_CONFIG_CLEAR - bool "clear (tiny)" + bool "clear (371 bytes)" default BUSYBOX_DEFAULT_CLEAR help This program clears the terminal screen. config BUSYBOX_CONFIG_DEALLOCVT - bool "deallocvt (1.9 kb)" + bool "deallocvt (2.2 kb)" default BUSYBOX_DEFAULT_DEALLOCVT help This program deallocates unused virtual consoles. config BUSYBOX_CONFIG_DUMPKMAP - bool "dumpkmap (1.6 kb)" + bool "dumpkmap (1.9 kb)" default BUSYBOX_DEFAULT_DUMPKMAP help This program dumps the kernel's keyboard translation table to stdout, in binary format. You can then use loadkmap to load it. config BUSYBOX_CONFIG_FGCONSOLE - bool "fgconsole (1.5 kb)" + bool "fgconsole (1.8 kb)" default BUSYBOX_DEFAULT_FGCONSOLE help This program prints active (foreground) console number. config BUSYBOX_CONFIG_KBD_MODE - bool "kbd_mode (4.1 kb)" + bool "kbd_mode (4.3 kb)" default BUSYBOX_DEFAULT_KBD_MODE help This program reports and sets keyboard mode. config BUSYBOX_CONFIG_LOADFONT - bool "loadfont (5.2 kb)" + bool "loadfont (5.4 kb)" default BUSYBOX_DEFAULT_LOADFONT help This program loads a console font from standard input. @@ -78,25 +78,25 @@ config BUSYBOX_CONFIG_FEATURE_LOADFONT_RAW default BUSYBOX_DEFAULT_FEATURE_LOADFONT_RAW depends on BUSYBOX_CONFIG_LOADFONT || BUSYBOX_CONFIG_SETFONT config BUSYBOX_CONFIG_LOADKMAP - bool "loadkmap (1.8 kb)" + bool "loadkmap (2.1 kb)" default BUSYBOX_DEFAULT_LOADKMAP help This program loads a keyboard translation table from standard input. config BUSYBOX_CONFIG_OPENVT - bool "openvt (7.2 kb)" + bool "openvt (7.4 kb)" default BUSYBOX_DEFAULT_OPENVT help This program is used to start a command on an unused virtual terminal. config BUSYBOX_CONFIG_RESET - bool "reset (345 bytes)" + bool "reset (676 bytes)" default BUSYBOX_DEFAULT_RESET help This program is used to reset the terminal screen, if it gets messed up. config BUSYBOX_CONFIG_RESIZE - bool "resize (903 bytes)" + bool "resize (1.2 kb)" default BUSYBOX_DEFAULT_RESIZE help This program is used to (re)set the width and height of your current @@ -112,7 +112,7 @@ config BUSYBOX_CONFIG_FEATURE_RESIZE_PRINT E.g.: COLUMNS=80;LINES=44;export COLUMNS LINES; config BUSYBOX_CONFIG_SETCONSOLE - bool "setconsole (3.6 kb)" + bool "setconsole (3.8 kb)" default BUSYBOX_DEFAULT_SETCONSOLE help Redirect writes to /dev/console to another device, @@ -125,18 +125,18 @@ config BUSYBOX_CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_SETCONSOLE_LONG_OPTIONS depends on BUSYBOX_CONFIG_SETCONSOLE && BUSYBOX_CONFIG_LONG_OPTS config BUSYBOX_CONFIG_SETKEYCODES - bool "setkeycodes (2.1 kb)" + bool "setkeycodes (2.4 kb)" default BUSYBOX_DEFAULT_SETKEYCODES help This program loads entries into the kernel's scancode-to-keycode map, allowing unusual keyboards to generate usable keycodes. config BUSYBOX_CONFIG_SETLOGCONS - bool "setlogcons (1.8 kb)" + bool "setlogcons (2 kb)" default BUSYBOX_DEFAULT_SETLOGCONS help This program redirects the output console of kernel messages. config BUSYBOX_CONFIG_SHOWKEY - bool "showkey (4.7 kb)" + bool "showkey (4.9 kb)" default BUSYBOX_DEFAULT_SHOWKEY help Shows keys pressed. diff --git a/package/utils/busybox/config/coreutils/Config.in b/package/utils/busybox/config/coreutils/Config.in index 983740be6ed12b..8ba5afc5e4c67b 100644 --- a/package/utils/busybox/config/coreutils/Config.in +++ b/package/utils/busybox/config/coreutils/Config.in @@ -48,14 +48,14 @@ config BUSYBOX_CONFIG_FEATURE_HUMAN_READABLE Allow df, du, and ls to have human readable output. config BUSYBOX_CONFIG_BASENAME - bool "basename (438 bytes)" + bool "basename (3.7 kb)" default BUSYBOX_DEFAULT_BASENAME help basename is used to strip the directory and suffix from filenames, leaving just the filename itself. Enable this option if you wish to enable the 'basename' utility. config BUSYBOX_CONFIG_CAT - bool "cat (5.6 kb)" + bool "cat (5.8 kb)" default BUSYBOX_DEFAULT_CAT help cat is used to concatenate files and print them to the standard @@ -96,20 +96,20 @@ config BUSYBOX_CONFIG_FEATURE_CHOWN_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_CHOWN_LONG_OPTIONS depends on BUSYBOX_CONFIG_CHOWN && BUSYBOX_CONFIG_LONG_OPTS config BUSYBOX_CONFIG_CHROOT - bool "chroot (3.7 kb)" + bool "chroot (4 kb)" default BUSYBOX_DEFAULT_CHROOT help chroot is used to change the root directory and run a command. The default command is '/bin/sh'. config BUSYBOX_CONFIG_CKSUM - bool "cksum (4.1 kb)" + bool "cksum (4.3 kb)" default BUSYBOX_DEFAULT_CKSUM config BUSYBOX_CONFIG_CRC32 - bool "crc32 (4.1 kb)" + bool "crc32 (4.2 kb)" default BUSYBOX_DEFAULT_CRC32 config BUSYBOX_CONFIG_COMM - bool "comm (4.2 kb)" + bool "comm (4.4 kb)" default BUSYBOX_DEFAULT_COMM help comm is used to compare two files line by line and return @@ -133,7 +133,7 @@ config BUSYBOX_CONFIG_FEATURE_CP_REFLINK default BUSYBOX_DEFAULT_FEATURE_CP_REFLINK depends on BUSYBOX_CONFIG_FEATURE_CP_LONG_OPTIONS config BUSYBOX_CONFIG_CUT - bool "cut (5.8 kb)" + bool "cut (6.7 kb)" default BUSYBOX_DEFAULT_CUT help cut is used to print selected parts of lines from @@ -146,7 +146,7 @@ config BUSYBOX_CONFIG_FEATURE_CUT_REGEX help Allow regex based delimiters. config BUSYBOX_CONFIG_DATE - bool "date (7 kb)" + bool "date (7.2 kb)" default BUSYBOX_DEFAULT_DATE help date is used to set the system date or display the @@ -183,7 +183,7 @@ config BUSYBOX_CONFIG_FEATURE_DATE_COMPAT the same format. With it on, 'date DATE' additionally supports MMDDhhmm[[YY]YY][.ss] format. config BUSYBOX_CONFIG_DD - bool "dd (7.5 kb)" + bool "dd (8.3 kb)" default BUSYBOX_DEFAULT_DD help dd copies a file (from standard input to standard output, @@ -227,7 +227,7 @@ config BUSYBOX_CONFIG_FEATURE_DD_STATUS help Enable support for status=noxfer/none option. config BUSYBOX_CONFIG_DF - bool "df (6.8 kb)" + bool "df (7.1 kb)" default BUSYBOX_DEFAULT_DF help df reports the amount of disk space used and available @@ -262,26 +262,26 @@ config BUSYBOX_CONFIG_FEATURE_SKIP_ROOTFS Otherwise, choose Y. config BUSYBOX_CONFIG_DIRNAME - bool "dirname (329 bytes)" + bool "dirname (611 bytes)" default BUSYBOX_DEFAULT_DIRNAME help dirname is used to strip a non-directory suffix from a file name. config BUSYBOX_CONFIG_DOS2UNIX - bool "dos2unix (5.2 kb)" + bool "dos2unix (5.5 kb)" default BUSYBOX_DEFAULT_DOS2UNIX help dos2unix is used to convert a text file from DOS format to UNIX format, and vice versa. config BUSYBOX_CONFIG_UNIX2DOS - bool "unix2dos (5.2 kb)" + bool "unix2dos (5.5 kb)" default BUSYBOX_DEFAULT_UNIX2DOS help unix2dos is used to convert a text file from UNIX format to DOS format, and vice versa. config BUSYBOX_CONFIG_DU - bool "du (6.3 kb)" + bool "du (6.5 kb)" default BUSYBOX_DEFAULT_DU help du is used to report the amount of disk space used @@ -292,7 +292,7 @@ config BUSYBOX_CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K default BUSYBOX_DEFAULT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K depends on BUSYBOX_CONFIG_DU config BUSYBOX_CONFIG_ECHO - bool "echo (1.8 kb)" + bool "echo (2 kb)" default BUSYBOX_DEFAULT_ECHO help echo prints a specified string to stdout. @@ -303,25 +303,25 @@ config BUSYBOX_CONFIG_FEATURE_FANCY_ECHO default BUSYBOX_DEFAULT_FEATURE_FANCY_ECHO depends on BUSYBOX_CONFIG_ECHO || BUSYBOX_CONFIG_ASH_ECHO || BUSYBOX_CONFIG_HUSH_ECHO config BUSYBOX_CONFIG_ENV - bool "env (4 kb)" + bool "env (4.3 kb)" default BUSYBOX_DEFAULT_ENV help env is used to set an environment variable and run a command; without options it displays the current environment. config BUSYBOX_CONFIG_EXPAND - bool "expand (5.1 kb)" + bool "expand (5.3 kb)" default BUSYBOX_DEFAULT_EXPAND help By default, convert all tabs to spaces. config BUSYBOX_CONFIG_UNEXPAND - bool "unexpand (5.3 kb)" + bool "unexpand (5.5 kb)" default BUSYBOX_DEFAULT_UNEXPAND help By default, convert only leading sequences of blanks to tabs. config BUSYBOX_CONFIG_EXPR - bool "expr (6.6 kb)" + bool "expr (6.8 kb)" default BUSYBOX_DEFAULT_EXPR help expr is used to calculate numbers and print the result @@ -336,22 +336,22 @@ config BUSYBOX_CONFIG_EXPR_MATH_SUPPORT_64 the applet slightly larger, but will allow computation with very large numbers. config BUSYBOX_CONFIG_FACTOR - bool "factor (2.7 kb)" + bool "factor (3.2 kb)" default BUSYBOX_DEFAULT_FACTOR help factor factorizes integers config BUSYBOX_CONFIG_FALSE - bool "false (tiny)" + bool "false (314 bytes)" default BUSYBOX_DEFAULT_FALSE help false returns an exit code of FALSE (1). config BUSYBOX_CONFIG_FOLD - bool "fold (4.6 kb)" + bool "fold (4.8 kb)" default BUSYBOX_DEFAULT_FOLD help Wrap text to fit a specific width. config BUSYBOX_CONFIG_HEAD - bool "head (3.8 kb)" + bool "head (4 kb)" default BUSYBOX_DEFAULT_HEAD help head is used to print the first specified number of lines @@ -362,19 +362,19 @@ config BUSYBOX_CONFIG_FEATURE_FANCY_HEAD default BUSYBOX_DEFAULT_FEATURE_FANCY_HEAD depends on BUSYBOX_CONFIG_HEAD config BUSYBOX_CONFIG_HOSTID - bool "hostid (286 bytes)" + bool "hostid (566 bytes)" default BUSYBOX_DEFAULT_HOSTID help hostid prints the numeric identifier (in hexadecimal) for the current host. config BUSYBOX_CONFIG_ID - bool "id (7 kb)" + bool "id (7.1 kb)" default BUSYBOX_DEFAULT_ID help id displays the current user and group ID names. config BUSYBOX_CONFIG_GROUPS - bool "groups (6.7 kb)" + bool "groups (6.8 kb)" default BUSYBOX_DEFAULT_GROUPS help Print the group names associated with current user id. @@ -389,17 +389,17 @@ config BUSYBOX_CONFIG_FEATURE_INSTALL_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_INSTALL_LONG_OPTIONS depends on BUSYBOX_CONFIG_INSTALL && BUSYBOX_CONFIG_LONG_OPTS config BUSYBOX_CONFIG_LINK - bool "link (3.2 kb)" + bool "link (3.5 kb)" default BUSYBOX_DEFAULT_LINK help link creates hard links between files. config BUSYBOX_CONFIG_LN - bool "ln (4.9 kb)" + bool "ln (5.1 kb)" default BUSYBOX_DEFAULT_LN help ln is used to create hard or soft links between files. config BUSYBOX_CONFIG_LOGNAME - bool "logname (1.1 kb)" + bool "logname (1.4 kb)" default BUSYBOX_DEFAULT_LOGNAME help logname is used to print the current user's login name. @@ -468,31 +468,31 @@ config BUSYBOX_CONFIG_FEATURE_LS_COLOR_IS_DEFAULT configurable, and the output may not be legible on many output screens. config BUSYBOX_CONFIG_MD5SUM - bool "md5sum (6.5 kb)" + bool "md5sum (6.7 kb)" default BUSYBOX_DEFAULT_MD5SUM help Compute and check MD5 message digest config BUSYBOX_CONFIG_SHA1SUM - bool "sha1sum (5.9 kb)" + bool "sha1sum (6.7 kb)" default BUSYBOX_DEFAULT_SHA1SUM help Compute and check SHA1 message digest config BUSYBOX_CONFIG_SHA256SUM - bool "sha256sum (7 kb)" + bool "sha256sum (8.2 kb)" default BUSYBOX_DEFAULT_SHA256SUM help Compute and check SHA256 message digest config BUSYBOX_CONFIG_SHA512SUM - bool "sha512sum (7.4 kb)" + bool "sha512sum (7.3 kb)" default BUSYBOX_DEFAULT_SHA512SUM help Compute and check SHA512 message digest config BUSYBOX_CONFIG_SHA3SUM - bool "sha3sum (6.1 kb)" + bool "sha3sum (6.3 kb)" default BUSYBOX_DEFAULT_SHA3SUM help Compute and check SHA3 message digest @@ -509,24 +509,24 @@ config BUSYBOX_CONFIG_FEATURE_MD5_SHA1_SUM_CHECK against pre-calculated hash values. -s and -w are useful options when verifying checksums. config BUSYBOX_CONFIG_MKDIR - bool "mkdir (4.5 kb)" + bool "mkdir (4.7 kb)" default BUSYBOX_DEFAULT_MKDIR help mkdir is used to create directories with the specified names. config BUSYBOX_CONFIG_MKFIFO - bool "mkfifo (3.8 kb)" + bool "mkfifo (4 kb)" default BUSYBOX_DEFAULT_MKFIFO help mkfifo is used to create FIFOs (named pipes). The 'mknod' program can also create FIFOs. config BUSYBOX_CONFIG_MKNOD - bool "mknod (4.5 kb)" + bool "mknod (4.6 kb)" default BUSYBOX_DEFAULT_MKNOD help mknod is used to create FIFOs or block/character special files with the specified names. config BUSYBOX_CONFIG_MKTEMP - bool "mktemp (4.2 kb)" + bool "mktemp (4.5 kb)" default BUSYBOX_DEFAULT_MKTEMP help mktemp is used to create unique temporary files @@ -536,22 +536,22 @@ config BUSYBOX_CONFIG_MV help mv is used to move or rename files or directories. config BUSYBOX_CONFIG_NICE - bool "nice (2.1 kb)" + bool "nice (2.3 kb)" default BUSYBOX_DEFAULT_NICE help nice runs a program with modified scheduling priority. config BUSYBOX_CONFIG_NL - bool "nl (4.6 kb)" + bool "nl (4.9 kb)" default BUSYBOX_DEFAULT_NL help nl is used to number lines of files. config BUSYBOX_CONFIG_NOHUP - bool "nohup (2 kb)" + bool "nohup (2.2 kb)" default BUSYBOX_DEFAULT_NOHUP help run a command immune to hangups, with output to a non-tty. config BUSYBOX_CONFIG_NPROC - bool "nproc (3.7 kb)" + bool "nproc (3.9 kb)" default BUSYBOX_DEFAULT_NPROC help Print number of CPUs @@ -561,29 +561,29 @@ config BUSYBOX_CONFIG_OD help od is used to dump binary files in octal and other formats. config BUSYBOX_CONFIG_PASTE - bool "paste (4.9 kb)" + bool "paste (5.1 kb)" default BUSYBOX_DEFAULT_PASTE help paste is used to paste lines of different files together and write the result to stdout config BUSYBOX_CONFIG_PRINTENV - bool "printenv (1.3 kb)" + bool "printenv (1.6 kb)" default BUSYBOX_DEFAULT_PRINTENV help printenv is used to print all or part of environment. config BUSYBOX_CONFIG_PRINTF - bool "printf (3.8 kb)" + bool "printf (4.1 kb)" default BUSYBOX_DEFAULT_PRINTF help printf is used to format and print specified strings. It's similar to 'echo' except it has more options. config BUSYBOX_CONFIG_PWD - bool "pwd (3.7 kb)" + bool "pwd (4 kb)" default BUSYBOX_DEFAULT_PWD help pwd is used to print the current directory. config BUSYBOX_CONFIG_READLINK - bool "readlink (4 kb)" + bool "readlink (4.8 kb)" default BUSYBOX_DEFAULT_READLINK help This program reads a symbolic link and returns the name @@ -596,49 +596,50 @@ config BUSYBOX_CONFIG_FEATURE_READLINK_FOLLOW help Enable the readlink option (-f). config BUSYBOX_CONFIG_REALPATH - bool "realpath (1.6 kb)" + bool "realpath (2.5 kb)" default BUSYBOX_DEFAULT_REALPATH help Return the canonicalized absolute pathname. This isn't provided by GNU shellutils, but where else does it belong. config BUSYBOX_CONFIG_RM - bool "rm (5.4 kb)" + bool "rm (5.5 kb)" default BUSYBOX_DEFAULT_RM help rm is used to remove files or directories. config BUSYBOX_CONFIG_RMDIR - bool "rmdir (3.5 kb)" + bool "rmdir (3.8 kb)" default BUSYBOX_DEFAULT_RMDIR help rmdir is used to remove empty directories. config BUSYBOX_CONFIG_SEQ - bool "seq (3.8 kb)" + bool "seq (4 kb)" default BUSYBOX_DEFAULT_SEQ help print a sequence of numbers config BUSYBOX_CONFIG_SHRED - bool "shred (4.9 kb)" + bool "shred (5.5 kb)" default BUSYBOX_DEFAULT_SHRED help Overwrite a file to hide its contents, and optionally delete it config BUSYBOX_CONFIG_SHUF - bool "shuf (5.4 kb)" + bool "shuf (6 kb)" default BUSYBOX_DEFAULT_SHUF help Generate random permutations config BUSYBOX_CONFIG_SLEEP - bool "sleep (2 kb)" + bool "sleep (2.4 kb)" default BUSYBOX_DEFAULT_SLEEP help sleep is used to pause for a specified number of seconds. - It comes in 3 versions: + It comes in 2 versions: - small: takes one integer parameter - - fancy: takes multiple integer arguments with suffixes: - sleep 1d 2h 3m 15s - - fancy with fractional numbers: - sleep 2.3s 4.5h sleeps for 16202.3 seconds - Last one is "the most compatible" with coreutils sleep, - but it adds around 1k of code. + - fancy: + * takes multiple integer arguments with suffixes: + sleep 1d 2h 3m 15s + * allows fractional numbers: + sleep 2.3s 4.5h sleeps for 16202.3 seconds + fancy is more compatible with coreutils sleep, but it adds around + 1k of code. config BUSYBOX_CONFIG_FEATURE_FANCY_SLEEP bool "Enable multiple arguments and s/m/h/d suffixes" @@ -647,7 +648,7 @@ config BUSYBOX_CONFIG_FEATURE_FANCY_SLEEP help Allow sleep to pause for specified minutes, hours, and days. config BUSYBOX_CONFIG_SORT - bool "sort (7.7 kb)" + bool "sort (8.1 kb)" default BUSYBOX_DEFAULT_SORT help sort is used to sort lines of text in specified files. @@ -672,7 +673,7 @@ config BUSYBOX_CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY Attempt to use less memory (by storing only one copy of duplicated lines, and such). Useful if you work on huge files. config BUSYBOX_CONFIG_SPLIT - bool "split (5 kb)" + bool "split (5.2 kb)" default BUSYBOX_DEFAULT_SPLIT help Split a file into pieces. @@ -708,17 +709,17 @@ config BUSYBOX_CONFIG_FEATURE_STAT_FILESYSTEM Without this, stat will not support the '-f' option to display information about filesystem status. config BUSYBOX_CONFIG_STTY - bool "stty (8.9 kb)" + bool "stty (9.2 kb)" default BUSYBOX_DEFAULT_STTY help stty is used to change and print terminal line settings. config BUSYBOX_CONFIG_SUM - bool "sum (4 kb)" + bool "sum (4.2 kb)" default BUSYBOX_DEFAULT_SUM help checksum and count the blocks in a file config BUSYBOX_CONFIG_SYNC - bool "sync (3.8 kb)" + bool "sync (4 kb)" default BUSYBOX_DEFAULT_SYNC help sync is used to flush filesystem buffers. @@ -730,17 +731,17 @@ config BUSYBOX_CONFIG_FEATURE_SYNC_FANCY sync -d FILE... executes fdatasync() on each FILE. sync -f FILE... executes syncfs() on each FILE. config BUSYBOX_CONFIG_FSYNC - bool "fsync (3.6 kb)" + bool "fsync (3.8 kb)" default BUSYBOX_DEFAULT_FSYNC help fsync is used to flush file-related cached blocks to disk. config BUSYBOX_CONFIG_TAC - bool "tac (3.9 kb)" + bool "tac (4.1 kb)" default BUSYBOX_DEFAULT_TAC help tac is used to concatenate and print files in reverse. config BUSYBOX_CONFIG_TAIL - bool "tail (6.8 kb)" + bool "tail (7.2 kb)" default BUSYBOX_DEFAULT_TAIL help tail is used to print the last specified number of lines @@ -758,7 +759,7 @@ config BUSYBOX_CONFIG_FEATURE_FANCY_TAIL -v Always output headers giving file names -F Same as -f, but keep retrying config BUSYBOX_CONFIG_TEE - bool "tee (4.2 kb)" + bool "tee (4.4 kb)" default BUSYBOX_DEFAULT_TEE help tee is used to read from standard input and write @@ -771,7 +772,7 @@ config BUSYBOX_CONFIG_FEATURE_TEE_USE_BLOCK_IO help Enable this option for a faster tee, at expense of size. config BUSYBOX_CONFIG_TEST - bool "test (4.1 kb)" + bool "test (4.4 kb)" default BUSYBOX_DEFAULT_TEST help test is used to check file types and compare values, @@ -797,13 +798,13 @@ config BUSYBOX_CONFIG_FEATURE_TEST_64 help Enable 64-bit support in test. config BUSYBOX_CONFIG_TIMEOUT - bool "timeout (6 kb)" + bool "timeout (6.5 kb)" default BUSYBOX_DEFAULT_TIMEOUT help Runs a program and watches it. If it does not terminate in specified number of seconds, it is sent a signal. config BUSYBOX_CONFIG_TOUCH - bool "touch (5.9 kb)" + bool "touch (6.1 kb)" default BUSYBOX_DEFAULT_TOUCH help touch is used to create or change the access and/or @@ -816,7 +817,7 @@ config BUSYBOX_CONFIG_FEATURE_TOUCH_SUSV3 help Enable touch to use a reference file or a given date/time argument. config BUSYBOX_CONFIG_TR - bool "tr (5.1 kb)" + bool "tr (5.3 kb)" default BUSYBOX_DEFAULT_TR help tr is used to squeeze, and/or delete characters from standard @@ -841,29 +842,29 @@ config BUSYBOX_CONFIG_FEATURE_TR_EQUIV useful for cases when no other way of expressing a character is possible. config BUSYBOX_CONFIG_TRUE - bool "true (tiny)" + bool "true (311 bytes)" default BUSYBOX_DEFAULT_TRUE help true returns an exit code of TRUE (0). config BUSYBOX_CONFIG_TRUNCATE - bool "truncate (4.2 kb)" + bool "truncate (4.4 kb)" default BUSYBOX_DEFAULT_TRUNCATE help truncate truncates files to a given size. If a file does not exist, it is created unless told otherwise. config BUSYBOX_CONFIG_TSORT - bool "tsort (0.7 kb)" + bool "tsort (2.6 kb)" default BUSYBOX_DEFAULT_TSORT help tsort performs a topological sort. config BUSYBOX_CONFIG_TTY - bool "tty (3.6 kb)" + bool "tty (3.9 kb)" default BUSYBOX_DEFAULT_TTY help tty is used to print the name of the current terminal to standard output. config BUSYBOX_CONFIG_UNAME - bool "uname (3.9 kb)" + bool "uname (4.2 kb)" default BUSYBOX_DEFAULT_UNAME help uname is used to print system information. @@ -877,47 +878,47 @@ config BUSYBOX_CONFIG_UNAME_OSNAME default BUSYBOX_DEFAULT_UNAME_OSNAME "GNU/Linux". config BUSYBOX_CONFIG_BB_ARCH - bool "arch (1.1 kb)" + bool "arch (1.4 kb)" default BUSYBOX_DEFAULT_BB_ARCH help Same as uname -m. config BUSYBOX_CONFIG_UNIQ - bool "uniq (4.9 kb)" + bool "uniq (5.1 kb)" default BUSYBOX_DEFAULT_UNIQ help uniq is used to remove duplicate lines from a sorted file. config BUSYBOX_CONFIG_UNLINK - bool "unlink (3.2 kb)" + bool "unlink (3.5 kb)" default BUSYBOX_DEFAULT_UNLINK help unlink deletes a file by calling unlink() config BUSYBOX_CONFIG_USLEEP - bool "usleep (1.3 kb)" + bool "usleep (1.6 kb)" default BUSYBOX_DEFAULT_USLEEP help usleep is used to pause for a specified number of microseconds. config BUSYBOX_CONFIG_UUDECODE - bool "uudecode (5.8 kb)" + bool "uudecode (5.9 kb)" default BUSYBOX_DEFAULT_UUDECODE help uudecode is used to decode a uuencoded file. config BUSYBOX_CONFIG_BASE32 - bool "base32 (4.9 kb)" + bool "base32 (5.5 kb)" default BUSYBOX_DEFAULT_BASE32 help Base32 encode and decode config BUSYBOX_CONFIG_BASE64 - bool "base64 (4.9 kb)" + bool "base64 (5.3 kb)" default BUSYBOX_DEFAULT_BASE64 help Base64 encode and decode config BUSYBOX_CONFIG_UUENCODE - bool "uuencode (4.4 kb)" + bool "uuencode (4.7 kb)" default BUSYBOX_DEFAULT_UUENCODE help uuencode is used to uuencode a file. config BUSYBOX_CONFIG_WC - bool "wc (4.5 kb)" + bool "wc (4.7 kb)" default BUSYBOX_DEFAULT_WC help wc is used to print the number of bytes, words, and lines, @@ -930,33 +931,33 @@ config BUSYBOX_CONFIG_FEATURE_WC_LARGE help Use "unsigned long long" for counter variables. config BUSYBOX_CONFIG_WHO - bool "who (3.9 kb)" + bool "who (5.6 kb)" default BUSYBOX_DEFAULT_WHO depends on BUSYBOX_CONFIG_FEATURE_UTMP help Print users currently logged on. config BUSYBOX_CONFIG_W - bool "w (3.8 kb)" + bool "w (5.5 kb)" default BUSYBOX_DEFAULT_W depends on BUSYBOX_CONFIG_FEATURE_UTMP help Print users currently logged on. config BUSYBOX_CONFIG_USERS - bool "users (3.4 kb)" + bool "users (3.6 kb)" default BUSYBOX_DEFAULT_USERS depends on BUSYBOX_CONFIG_FEATURE_UTMP help Print users currently logged on. config BUSYBOX_CONFIG_WHOAMI - bool "whoami (3.2 kb)" + bool "whoami (3.5 kb)" default BUSYBOX_DEFAULT_WHOAMI help whoami is used to print the username of the current user id (same as id -un). config BUSYBOX_CONFIG_YES - bool "yes (1.2 kb)" + bool "yes (1.5 kb)" default BUSYBOX_DEFAULT_YES help yes is used to repeatedly output a specific string, or diff --git a/package/utils/busybox/config/debianutils/Config.in b/package/utils/busybox/config/debianutils/Config.in index 15abb08e6326d3..69bdbb654d9dc9 100644 --- a/package/utils/busybox/config/debianutils/Config.in +++ b/package/utils/busybox/config/debianutils/Config.in @@ -7,12 +7,12 @@ menu "Debian Utilities" config BUSYBOX_CONFIG_PIPE_PROGRESS - bool "pipe_progress (275 bytes)" + bool "pipe_progress (576 bytes)" default BUSYBOX_DEFAULT_PIPE_PROGRESS help Display a dot to indicate pipe activity. config BUSYBOX_CONFIG_RUN_PARTS - bool "run-parts (6.1 kb)" + bool "run-parts (6.2 kb)" default BUSYBOX_DEFAULT_RUN_PARTS help run-parts is a utility designed to run all the scripts in a directory. @@ -61,7 +61,7 @@ config BUSYBOX_CONFIG_FEATURE_START_STOP_DAEMON_FANCY -v|--verbose -N|--nicelevel N config BUSYBOX_CONFIG_WHICH - bool "which (3.8 kb)" + bool "which (4 kb)" default BUSYBOX_DEFAULT_WHICH help which is used to find programs in your PATH and diff --git a/package/utils/busybox/config/e2fsprogs/Config.in b/package/utils/busybox/config/e2fsprogs/Config.in index 4a9aa2ab4e2f07..ed6220a2d10ef8 100644 --- a/package/utils/busybox/config/e2fsprogs/Config.in +++ b/package/utils/busybox/config/e2fsprogs/Config.in @@ -7,19 +7,19 @@ menu "Linux Ext2 FS Progs" config BUSYBOX_CONFIG_CHATTR - bool "chattr (3.8 kb)" + bool "chattr (4.1 kb)" default BUSYBOX_DEFAULT_CHATTR help chattr changes the file attributes on a second extended file system. config BUSYBOX_CONFIG_FSCK - bool "fsck (7.4 kb)" + bool "fsck (7.6 kb)" default BUSYBOX_DEFAULT_FSCK help fsck is used to check and optionally repair one or more filesystems. In actuality, fsck is simply a front-end for the various file system checkers (fsck.fstype) available under Linux. config BUSYBOX_CONFIG_LSATTR - bool "lsattr (5.5 kb)" + bool "lsattr (5.7 kb)" default BUSYBOX_DEFAULT_LSATTR help lsattr lists the file attributes on a second extended file system. diff --git a/package/utils/busybox/config/editors/Config.in b/package/utils/busybox/config/editors/Config.in index dc80a4ec0df6f6..0e9bda0fbab425 100644 --- a/package/utils/busybox/config/editors/Config.in +++ b/package/utils/busybox/config/editors/Config.in @@ -7,7 +7,7 @@ menu "Editors" config BUSYBOX_CONFIG_AWK - bool "awk (23 kb)" + bool "awk (24 kb)" default BUSYBOX_DEFAULT_AWK help Awk is used as a pattern scanning and processing language. @@ -31,7 +31,7 @@ config BUSYBOX_CONFIG_FEATURE_AWK_GNU_EXTENSIONS This enables the use of awk library files. Example: awk -f mylib.awk -e '{print myfunction($1);}' ... config BUSYBOX_CONFIG_CMP - bool "cmp (4.9 kb)" + bool "cmp (5.3 kb)" default BUSYBOX_DEFAULT_CMP help cmp is used to compare two files and returns the result @@ -57,14 +57,14 @@ config BUSYBOX_CONFIG_FEATURE_DIFF_DIR This option enables support for directory and subdirectory comparison. config BUSYBOX_CONFIG_ED - bool "ed (21 kb)" + bool "ed (16 kb)" default BUSYBOX_DEFAULT_ED help The original 1970's Unix text editor, from the days of teletypes. Small, simple, evil. Part of SUSv3. If you're not already using this, you don't need it. config BUSYBOX_CONFIG_PATCH - bool "patch (9.4 kb)" + bool "patch (9.6 kb)" default BUSYBOX_DEFAULT_PATCH help Apply a unified diff formatted patch. @@ -75,7 +75,7 @@ config BUSYBOX_CONFIG_SED sed is used to perform text transformations on a file or input from a pipeline. config BUSYBOX_CONFIG_VI - bool "vi (23 kb)" + bool "vi (26 kb)" default BUSYBOX_DEFAULT_VI help 'vi' is a text editor. More specifically, it is the One True @@ -134,7 +134,7 @@ config BUSYBOX_CONFIG_FEATURE_VI_SEARCH config BUSYBOX_CONFIG_FEATURE_VI_REGEX_SEARCH bool "Enable regex in search and replace" - default BUSYBOX_DEFAULT_FEATURE_VI_REGEX_SEARCH # Uses GNU regex, which may be unavailable. FIXME + default BUSYBOX_DEFAULT_FEATURE_VI_REGEX_SEARCH depends on BUSYBOX_CONFIG_FEATURE_VI_SEARCH depends on USE_GLIBC help diff --git a/package/utils/busybox/config/findutils/Config.in b/package/utils/busybox/config/findutils/Config.in index 805d44f149e35c..8ea35b7c553de5 100644 --- a/package/utils/busybox/config/findutils/Config.in +++ b/package/utils/busybox/config/findutils/Config.in @@ -7,7 +7,7 @@ menu "Finding Utilities" config BUSYBOX_CONFIG_FIND - bool "find (14 kb)" + bool "find (16 kb)" default BUSYBOX_DEFAULT_FIND help find is used to search your system to find specified files. @@ -136,6 +136,13 @@ config BUSYBOX_CONFIG_FEATURE_FIND_EXEC_PLUS Without this option, -exec + is a synonym for -exec ; (IOW: it works correctly, but without expected speedup) +config BUSYBOX_CONFIG_FEATURE_FIND_EXEC_OK + bool "Enable -ok: execute confirmed commands" + default BUSYBOX_DEFAULT_FEATURE_FIND_EXEC_OK + depends on BUSYBOX_CONFIG_FEATURE_FIND_EXEC + help + Support the 'find -ok' option which prompts before executing. + config BUSYBOX_CONFIG_FEATURE_FIND_USER bool "Enable -user: username/uid matching" default BUSYBOX_DEFAULT_FEATURE_FIND_USER @@ -234,19 +241,19 @@ config BUSYBOX_CONFIG_FEATURE_FIND_LINKS help Support the 'find -links' option for matching number of links. config BUSYBOX_CONFIG_GREP - bool "grep (8.6 kb)" + bool "grep (8.9 kb)" default BUSYBOX_DEFAULT_GREP help grep is used to search files for a specified pattern. config BUSYBOX_CONFIG_EGREP - bool "egrep (7.8 kb)" + bool "egrep (8 kb)" default BUSYBOX_DEFAULT_EGREP help Alias to "grep -E". config BUSYBOX_CONFIG_FGREP - bool "fgrep (7.8 kb)" + bool "fgrep (8 kb)" default BUSYBOX_DEFAULT_FGREP help Alias to "grep -F". @@ -260,7 +267,7 @@ config BUSYBOX_CONFIG_FEATURE_GREP_CONTEXT context surrounding our matching lines. Print the specified number of context lines (-C). config BUSYBOX_CONFIG_XARGS - bool "xargs (7.2 kb)" + bool "xargs (7.6 kb)" default BUSYBOX_DEFAULT_XARGS help xargs is used to execute a specified command for diff --git a/package/utils/busybox/config/init/Config.in b/package/utils/busybox/config/init/Config.in index fc6c916a682758..56cc2ef1da645d 100644 --- a/package/utils/busybox/config/init/Config.in +++ b/package/utils/busybox/config/init/Config.in @@ -45,19 +45,19 @@ config BUSYBOX_CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE Enable reading and parsing of $PWD/bootchartd.conf and /etc/bootchartd.conf files. config BUSYBOX_CONFIG_HALT - bool "halt (4 kb)" + bool "halt (4.3 kb)" default BUSYBOX_DEFAULT_HALT help Stop all processes and halt the system. config BUSYBOX_CONFIG_POWEROFF - bool "poweroff (4 kb)" + bool "poweroff (4.3 kb)" default BUSYBOX_DEFAULT_POWEROFF help Stop all processes and power off the system. config BUSYBOX_CONFIG_REBOOT - bool "reboot (4 kb)" + bool "reboot (4.3 kb)" default BUSYBOX_DEFAULT_REBOOT help Stop all processes and reboot the system. diff --git a/package/utils/busybox/config/klibc-utils/Config.in b/package/utils/busybox/config/klibc-utils/Config.in index 06b9681bc92833..6fb5bbf6691054 100644 --- a/package/utils/busybox/config/klibc-utils/Config.in +++ b/package/utils/busybox/config/klibc-utils/Config.in @@ -17,12 +17,12 @@ config BUSYBOX_CONFIG_NUKE help Alias to "rm -rf". config BUSYBOX_CONFIG_RESUME - bool "resume (3.2 kb)" + bool "resume (3.6 kb)" default BUSYBOX_DEFAULT_RESUME help Resume from saved "suspend-to-disk" image config BUSYBOX_CONFIG_RUN_INIT - bool "run-init (7.7 kb)" + bool "run-init (8 kb)" default BUSYBOX_DEFAULT_RUN_INIT help The run-init utility is used from initramfs to select a new diff --git a/package/utils/busybox/config/loginutils/Config.in b/package/utils/busybox/config/loginutils/Config.in index 465fa519cb19f6..95422f1037eab3 100644 --- a/package/utils/busybox/config/loginutils/Config.in +++ b/package/utils/busybox/config/loginutils/Config.in @@ -93,18 +93,18 @@ config BUSYBOX_CONFIG_USE_BB_CRYPT_SHA user which has password encrypted with these algorithms. config BUSYBOX_CONFIG_ADD_SHELL - bool "add-shell (3.1 kb)" + bool "add-shell (3.3 kb)" default BUSYBOX_DEFAULT_ADD_SHELL if BUSYBOX_CONFIG_DESKTOP help Add shells to /etc/shells. config BUSYBOX_CONFIG_REMOVE_SHELL - bool "remove-shell (3 kb)" + bool "remove-shell (3.3 kb)" default BUSYBOX_DEFAULT_REMOVE_SHELL if BUSYBOX_CONFIG_DESKTOP help Remove shells from /etc/shells. config BUSYBOX_CONFIG_ADDGROUP - bool "addgroup (8.6 kb)" + bool "addgroup (8.8 kb)" default BUSYBOX_DEFAULT_ADDGROUP select BUSYBOX_CONFIG_LONG_OPTS help @@ -160,7 +160,7 @@ config BUSYBOX_CONFIG_LAST_SYSTEM_ID help Last valid system uid or gid for adduser and addgroup config BUSYBOX_CONFIG_CHPASSWD - bool "chpasswd (18 kb)" + bool "chpasswd (19 kb)" default BUSYBOX_DEFAULT_CHPASSWD help Reads a file of user name and password pairs from standard input @@ -173,27 +173,27 @@ config BUSYBOX_CONFIG_FEATURE_DEFAULT_PASSWD_ALGO help Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". config BUSYBOX_CONFIG_CRYPTPW - bool "cryptpw (14 kb)" + bool "cryptpw (15 kb)" default BUSYBOX_DEFAULT_CRYPTPW help Encrypts the given password with the crypt(3) libc function using the given salt. config BUSYBOX_CONFIG_MKPASSWD - bool "mkpasswd (15 kb)" + bool "mkpasswd (16 kb)" default BUSYBOX_DEFAULT_MKPASSWD help Encrypts the given password with the crypt(3) libc function using the given salt. Debian has this utility under mkpasswd name. Busybox provides mkpasswd as an alias for cryptpw. config BUSYBOX_CONFIG_DELUSER - bool "deluser (9.1 kb)" + bool "deluser (9.3 kb)" default BUSYBOX_DEFAULT_DELUSER help Utility for deleting a user account. config BUSYBOX_CONFIG_DELGROUP - bool "delgroup (6.4 kb)" + bool "delgroup (6.6 kb)" default BUSYBOX_DEFAULT_DELGROUP help Utility for deleting a group account. @@ -206,7 +206,7 @@ config BUSYBOX_CONFIG_FEATURE_DEL_USER_FROM_GROUP If called with two non-option arguments, deluser or delgroup will remove an user from a specified group. config BUSYBOX_CONFIG_GETTY - bool "getty (10 kb)" + bool "getty (11 kb)" default BUSYBOX_DEFAULT_GETTY select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -224,7 +224,7 @@ config BUSYBOX_CONFIG_GETTY read -r login exec /bin/login "$login" config BUSYBOX_CONFIG_LOGIN - bool "login (24 kb)" + bool "login (25 kb)" default BUSYBOX_DEFAULT_LOGIN select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -269,7 +269,7 @@ config BUSYBOX_CONFIG_FEATURE_SECURETTY The file contains the device names of tty lines (one per line, without leading /dev/) on which root is allowed to login. config BUSYBOX_CONFIG_PASSWD - bool "passwd (21 kb)" + bool "passwd (22 kb)" default BUSYBOX_DEFAULT_PASSWD select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -312,14 +312,14 @@ config BUSYBOX_CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY default BUSYBOX_DEFAULT_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY depends on BUSYBOX_CONFIG_SU config BUSYBOX_CONFIG_SULOGIN - bool "sulogin (17 kb)" + bool "sulogin (18 kb)" default BUSYBOX_DEFAULT_SULOGIN select BUSYBOX_CONFIG_FEATURE_SYSLOG help sulogin is invoked when the system goes into single user mode (this is done through an entry in inittab). config BUSYBOX_CONFIG_VLOCK - bool "vlock (17 kb)" + bool "vlock (18 kb)" default BUSYBOX_DEFAULT_VLOCK help Build the "vlock" applet which allows you to lock (virtual) terminals. diff --git a/package/utils/busybox/config/mailutils/Config.in b/package/utils/busybox/config/mailutils/Config.in index ea7ae6d6495f71..146478a87221ce 100644 --- a/package/utils/busybox/config/mailutils/Config.in +++ b/package/utils/busybox/config/mailutils/Config.in @@ -9,12 +9,12 @@ config BUSYBOX_CONFIG_FEATURE_MIME_CHARSET Default charset of the message. config BUSYBOX_CONFIG_MAKEMIME - bool "makemime (5.4 kb)" + bool "makemime (5.6 kb)" default BUSYBOX_DEFAULT_MAKEMIME help Create MIME-formatted messages. config BUSYBOX_CONFIG_POPMAILDIR - bool "popmaildir (10 kb)" + bool "popmaildir (11 kb)" default BUSYBOX_DEFAULT_POPMAILDIR help Simple yet powerful POP3 mail popper. Delivers content @@ -30,7 +30,7 @@ config BUSYBOX_CONFIG_FEATURE_POPMAILDIR_DELIVERY Allow to use a custom program for message actual delivery (-M "prog [args...]"). config BUSYBOX_CONFIG_REFORMIME - bool "reformime (7.5 kb)" + bool "reformime (7.6 kb)" default BUSYBOX_DEFAULT_REFORMIME help Parse MIME-formatted messages. diff --git a/package/utils/busybox/config/miscutils/Config.in b/package/utils/busybox/config/miscutils/Config.in index e15e318fe07585..3d3a6d86fd1709 100644 --- a/package/utils/busybox/config/miscutils/Config.in +++ b/package/utils/busybox/config/miscutils/Config.in @@ -7,13 +7,13 @@ menu "Miscellaneous Utilities" config BUSYBOX_CONFIG_ADJTIMEX - bool "adjtimex (4.7 kb)" + bool "adjtimex (4.9 kb)" default BUSYBOX_DEFAULT_ADJTIMEX help Adjtimex reads and optionally sets adjustment parameters for the Linux clock adjustment algorithm. config BUSYBOX_CONFIG_ASCII - bool "ascii" + bool "ascii (784 bytes)" default BUSYBOX_DEFAULT_ASCII help Print ascii table. @@ -39,7 +39,7 @@ config BUSYBOX_CONFIG_FEATURE_COMPRESS_BBCONFIG and have very little memory, this might not be a win. Otherwise, you probably want this. config BUSYBOX_CONFIG_BC - bool "bc (45 kb)" + bool "bc (38 kb)" default BUSYBOX_DEFAULT_BC select BUSYBOX_CONFIG_FEATURE_DC_BIG help @@ -63,7 +63,7 @@ config BUSYBOX_CONFIG_BC 5) "read()" accepts expressions, not only numeric literals. config BUSYBOX_CONFIG_DC - bool "dc (36 kb)" + bool "dc (29 kb)" default BUSYBOX_DEFAULT_DC help dc is a reverse-polish notation command-line calculator which @@ -125,7 +125,7 @@ config BUSYBOX_CONFIG_FEATURE_BC_LONG_OPTIONS endif config BUSYBOX_CONFIG_BEEP - bool "beep (2.4 kb)" + bool "beep (2.7 kb)" default BUSYBOX_DEFAULT_BEEP help The beep applets beeps in a given freq/Hz. @@ -146,7 +146,7 @@ config BUSYBOX_CONFIG_FEATURE_BEEP_LENGTH_MS help Length in ms for default beep. config BUSYBOX_CONFIG_CHAT - bool "chat (6.3 kb)" + bool "chat (6.7 kb)" default BUSYBOX_DEFAULT_CHAT help Simple chat utility. @@ -220,7 +220,7 @@ config BUSYBOX_CONFIG_CONSPY or conspy -nd NUM screenshot of console num or conspy -cs NUM poor man's GNU screen like config BUSYBOX_CONFIG_CROND - bool "crond (14 kb)" + bool "crond (15 kb)" default BUSYBOX_DEFAULT_CROND select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -330,7 +330,7 @@ config BUSYBOX_CONFIG_FEATURE_DEVFS /dev/loop0. If your /dev directory has normal names instead of devfs names, you don't want this. config BUSYBOX_CONFIG_DEVMEM - bool "devmem (2.5 kb)" + bool "devmem (2.7 kb)" default BUSYBOX_DEFAULT_DEVMEM help devmem is a small program that reads and writes from physical @@ -380,6 +380,11 @@ config BUSYBOX_CONFIG_FLASHCP help The flashcp binary, inspired by mtd-utils as of git head 5eceb74f7. This utility is used to copy images into a MTD device. +config BUSYBOX_CONFIG_GETFATTR + bool "getfattr (12.3 kb)" + default BUSYBOX_DEFAULT_GETFATTR + help + Get extended attributes on files config BUSYBOX_CONFIG_HDPARM bool "hdparm (25 kb)" default BUSYBOX_DEFAULT_HDPARM @@ -437,36 +442,36 @@ config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA help Enable the 'hdparm -d' option to get/set using_dma flag. config BUSYBOX_CONFIG_HEXEDIT - bool "hexedit (21 kb)" + bool "hexedit (15 kb)" default BUSYBOX_DEFAULT_HEXEDIT help Edit file in hexadecimal. config BUSYBOX_CONFIG_I2CGET - bool "i2cget (5.5 kb)" + bool "i2cget (5.7 kb)" default BUSYBOX_DEFAULT_I2CGET help Read from I2C/SMBus chip registers. config BUSYBOX_CONFIG_I2CSET - bool "i2cset (6.7 kb)" + bool "i2cset (6.9 kb)" default BUSYBOX_DEFAULT_I2CSET help Set I2C registers. config BUSYBOX_CONFIG_I2CDUMP - bool "i2cdump (7.1 kb)" + bool "i2cdump (7.2 kb)" default BUSYBOX_DEFAULT_I2CDUMP help Examine I2C registers. config BUSYBOX_CONFIG_I2CDETECT - bool "i2cdetect (7.1 kb)" + bool "i2cdetect (7.3 kb)" default BUSYBOX_DEFAULT_I2CDETECT help Detect I2C chips. config BUSYBOX_CONFIG_I2CTRANSFER - bool "i2ctransfer (4.0 kb)" + bool "i2ctransfer (5.5 kb)" default BUSYBOX_DEFAULT_I2CTRANSFER help Send user-defined I2C messages in one transfer. @@ -579,7 +584,7 @@ config BUSYBOX_CONFIG_LOCK help Small utility for using locks in scripts config BUSYBOX_CONFIG_LSSCSI - bool "lsscsi (2.5 kb)" + bool "lsscsi (2.9 kb)" default BUSYBOX_DEFAULT_LSSCSI help lsscsi is a utility for displaying information about SCSI buses in the @@ -587,7 +592,7 @@ config BUSYBOX_CONFIG_LSSCSI This version uses sysfs (/sys/bus/scsi/devices) only. config BUSYBOX_CONFIG_MAKEDEVS - bool "makedevs (9.2 kb)" + bool "makedevs (9.4 kb)" default BUSYBOX_DEFAULT_MAKEDEVS help 'makedevs' is a utility used to create a batch of devices with @@ -623,7 +628,7 @@ config BUSYBOX_CONFIG_MAN help Format and display manual pages. config BUSYBOX_CONFIG_MICROCOM - bool "microcom (5.7 kb)" + bool "microcom (5.9 kb)" default BUSYBOX_DEFAULT_MICROCOM help The poor man's minicom utility for chatting with serial port devices. @@ -635,36 +640,36 @@ config BUSYBOX_CONFIG_MIM Run a script from a Makefile-like specification file. Unlike 'make' dependencies aren't supported. config BUSYBOX_CONFIG_MT - bool "mt (2.5 kb)" + bool "mt (2.7 kb)" default BUSYBOX_DEFAULT_MT help mt is used to control tape devices. You can use the mt utility to advance or rewind a tape past a specified number of archive files on the tape. config BUSYBOX_CONFIG_NANDWRITE - bool "nandwrite (4.8 kb)" + bool "nandwrite (5 kb)" default BUSYBOX_DEFAULT_NANDWRITE help Write to the specified MTD device, with bad blocks awareness config BUSYBOX_CONFIG_NANDDUMP - bool "nanddump (5.2 kb)" + bool "nanddump (5.4 kb)" default BUSYBOX_DEFAULT_NANDDUMP help Dump the content of raw NAND chip config BUSYBOX_CONFIG_PARTPROBE - bool "partprobe (3.5 kb)" + bool "partprobe (3.7 kb)" default BUSYBOX_DEFAULT_PARTPROBE help Ask kernel to rescan partition table. config BUSYBOX_CONFIG_RAIDAUTORUN - bool "raidautorun (1.3 kb)" + bool "raidautorun (1.6 kb)" default BUSYBOX_DEFAULT_RAIDAUTORUN help raidautorun tells the kernel md driver to search and start RAID arrays. config BUSYBOX_CONFIG_READAHEAD - bool "readahead (1.5 kb)" + bool "readahead (1.7 kb)" default BUSYBOX_DEFAULT_READAHEAD depends on BUSYBOX_CONFIG_LFS help @@ -691,7 +696,7 @@ config BUSYBOX_CONFIG_RFKILL rfkill block|unblock wlan : block/unblock all wlan(wifi) devices config BUSYBOX_CONFIG_RUNLEVEL - bool "runlevel (559 bytes)" + bool "runlevel (837 bytes)" default BUSYBOX_DEFAULT_RUNLEVEL depends on BUSYBOX_CONFIG_FEATURE_UTMP help @@ -700,50 +705,50 @@ config BUSYBOX_CONFIG_RUNLEVEL This applet uses utmp but does not rely on busybox supporing utmp on purpose. It is used by e.g. emdebian via /etc/init.d/rc. config BUSYBOX_CONFIG_RX - bool "rx (2.9 kb)" + bool "rx (3.2 kb)" default BUSYBOX_DEFAULT_RX help Receive files using the Xmodem protocol. config BUSYBOX_CONFIG_SEEDRNG - bool "seedrng (1.3 kb)" + bool "seedrng (9.1 kb)" default BUSYBOX_DEFAULT_SEEDRNG help Seed the kernel RNG from seed files, meant to be called once during startup, once during shutdown, and optionally at some periodic interval in between. config BUSYBOX_CONFIG_SETFATTR - bool "setfattr (3.7 kb)" + bool "setfattr (3.9 kb)" default BUSYBOX_DEFAULT_SETFATTR help Set/delete extended attributes on files config BUSYBOX_CONFIG_SETSERIAL - bool "setserial (6.9 kb)" + bool "setserial (7.1 kb)" default BUSYBOX_DEFAULT_SETSERIAL help Retrieve or set Linux serial port. config BUSYBOX_CONFIG_STRINGS - bool "strings (4.6 kb)" + bool "strings (4.8 kb)" default BUSYBOX_DEFAULT_STRINGS help strings prints the printable character sequences for each file specified. config BUSYBOX_CONFIG_TIME - bool "time (6.8 kb)" + bool "time (8.1 kb)" default BUSYBOX_DEFAULT_TIME help The time command runs the specified program with the given arguments. When the command finishes, time writes a message to standard output giving timing statistics about this program run. config BUSYBOX_CONFIG_TREE - bool "tree (0.6 kb)" + bool "tree (2.5 kb)" default BUSYBOX_DEFAULT_TREE help List files and directories in a tree structure. config BUSYBOX_CONFIG_TS - bool "ts (450 bytes)" + bool "ts (4.4 kb)" default BUSYBOX_DEFAULT_TS config BUSYBOX_CONFIG_TTYSIZE - bool "ttysize (432 bytes)" + bool "ttysize (718 bytes)" default BUSYBOX_DEFAULT_TTYSIZE help A replacement for "stty size". Unlike stty, can report only width, @@ -751,52 +756,52 @@ config BUSYBOX_CONFIG_TTYSIZE error, but returns default 80x24. Usage in shell scripts: width=`ttysize w`. config BUSYBOX_CONFIG_UBIATTACH - bool "ubiattach (4.2 kb)" + bool "ubiattach (4.5 kb)" default BUSYBOX_DEFAULT_UBIATTACH help Attach MTD device to an UBI device. config BUSYBOX_CONFIG_UBIDETACH - bool "ubidetach (4.1 kb)" + bool "ubidetach (4.3 kb)" default BUSYBOX_DEFAULT_UBIDETACH help Detach MTD device from an UBI device. config BUSYBOX_CONFIG_UBIMKVOL - bool "ubimkvol (5.3 kb)" + bool "ubimkvol (5.5 kb)" default BUSYBOX_DEFAULT_UBIMKVOL help Create a UBI volume. config BUSYBOX_CONFIG_UBIRMVOL - bool "ubirmvol (4.9 kb)" + bool "ubirmvol (5.1 kb)" default BUSYBOX_DEFAULT_UBIRMVOL help Delete a UBI volume. config BUSYBOX_CONFIG_UBIRSVOL - bool "ubirsvol (4.2 kb)" + bool "ubirsvol (4.4 kb)" default BUSYBOX_DEFAULT_UBIRSVOL help Resize a UBI volume. config BUSYBOX_CONFIG_UBIUPDATEVOL - bool "ubiupdatevol (5.2 kb)" + bool "ubiupdatevol (5.6 kb)" default BUSYBOX_DEFAULT_UBIUPDATEVOL help Update a UBI volume. config BUSYBOX_CONFIG_UBIRENAME - bool "ubirename (2.4 kb)" + bool "ubirename (2.7 kb)" default BUSYBOX_DEFAULT_UBIRENAME help Utility to rename UBI volumes config BUSYBOX_CONFIG_VOLNAME - bool "volname (1.6 kb)" + bool "volname (1.9 kb)" default BUSYBOX_DEFAULT_VOLNAME help Prints a CD-ROM volume name. config BUSYBOX_CONFIG_WATCHDOG - bool "watchdog (5.3 kb)" + bool "watchdog (5.7 kb)" default BUSYBOX_DEFAULT_WATCHDOG help The watchdog utility is used with hardware or software watchdog diff --git a/package/utils/busybox/config/modutils/Config.in b/package/utils/busybox/config/modutils/Config.in index e3538081ea8cf1..58a0e5b7673def 100644 --- a/package/utils/busybox/config/modutils/Config.in +++ b/package/utils/busybox/config/modutils/Config.in @@ -47,7 +47,7 @@ config BUSYBOX_CONFIG_INSMOD help insmod is used to load specified modules in the running kernel. config BUSYBOX_CONFIG_LSMOD - bool "lsmod (1.9 kb)" + bool "lsmod (2.1 kb)" default BUSYBOX_DEFAULT_LSMOD help lsmod is used to display a list of loaded modules. @@ -66,7 +66,7 @@ config BUSYBOX_CONFIG_MODINFO help Show information about a Linux Kernel module config BUSYBOX_CONFIG_MODPROBE - bool "modprobe (28 kb)" + bool "modprobe (27 kb)" default BUSYBOX_DEFAULT_MODPROBE help Handle the loading of modules, and their dependencies on a high @@ -83,7 +83,7 @@ config BUSYBOX_CONFIG_FEATURE_MODPROBE_BLACKLIST hardware autodetection scripts to load modules like evdev, frame buffer drivers etc. config BUSYBOX_CONFIG_RMMOD - bool "rmmod (3.3 kb)" + bool "rmmod (3.5 kb)" default BUSYBOX_DEFAULT_RMMOD help rmmod is used to unload specified modules from the kernel. diff --git a/package/utils/busybox/config/networking/Config.in b/package/utils/busybox/config/networking/Config.in index 861e4f9bbfa966..fd2b4efd854e4d 100644 --- a/package/utils/busybox/config/networking/Config.in +++ b/package/utils/busybox/config/networking/Config.in @@ -90,12 +90,12 @@ config BUSYBOX_CONFIG_ARP help Manipulate the system ARP cache. config BUSYBOX_CONFIG_ARPING - bool "arping (9 kb)" + bool "arping (9.1 kb)" default BUSYBOX_DEFAULT_ARPING help Ping hosts by ARP packets. config BUSYBOX_CONFIG_BRCTL - bool "brctl (4.7 kb)" + bool "brctl (9.9 kb)" default BUSYBOX_DEFAULT_BRCTL help Manage ethernet bridges. @@ -120,12 +120,12 @@ config BUSYBOX_CONFIG_FEATURE_BRCTL_SHOW Add support for option which prints the current config: show config BUSYBOX_CONFIG_DNSD - bool "dnsd (9.8 kb)" + bool "dnsd (10 kb)" default BUSYBOX_DEFAULT_DNSD help Small and static DNS server daemon. config BUSYBOX_CONFIG_ETHER_WAKE - bool "ether-wake (4.9 kb)" + bool "ether-wake (5.2 kb)" default BUSYBOX_DEFAULT_ETHER_WAKE help Send a magic packet to wake up sleeping machines. @@ -167,13 +167,13 @@ config BUSYBOX_CONFIG_FEATURE_FTPD_AUTHENTICATION of the user it was started under, and does not require login. Take care to not launch it under root. config BUSYBOX_CONFIG_FTPGET - bool "ftpget (7.8 kb)" + bool "ftpget (7.9 kb)" default BUSYBOX_DEFAULT_FTPGET help Retrieve a remote file via FTP. config BUSYBOX_CONFIG_FTPPUT - bool "ftpput (7.5 kb)" + bool "ftpput (7.6 kb)" default BUSYBOX_DEFAULT_FTPPUT help Store a remote file via FTP. @@ -183,13 +183,13 @@ config BUSYBOX_CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_FTPGETPUT_LONG_OPTIONS depends on BUSYBOX_CONFIG_LONG_OPTS && (BUSYBOX_CONFIG_FTPGET || BUSYBOX_CONFIG_FTPPUT) config BUSYBOX_CONFIG_HOSTNAME - bool "hostname (5.5 kb)" + bool "hostname (5.8 kb)" default BUSYBOX_DEFAULT_HOSTNAME help Show or set the system's host name. config BUSYBOX_CONFIG_DNSDOMAINNAME - bool "dnsdomainname (3.6 kb)" + bool "dnsdomainname (3.8 kb)" default BUSYBOX_DEFAULT_DNSDOMAINNAME help Alias to "hostname -d". @@ -408,7 +408,7 @@ config BUSYBOX_CONFIG_IFENSLAVE Userspace application to bind several interfaces to a logical interface (use with kernel bonding driver). config BUSYBOX_CONFIG_IFPLUGD - bool "ifplugd (10 kb)" + bool "ifplugd (11 kb)" default BUSYBOX_DEFAULT_IFPLUGD help Network interface plug detection daemon. @@ -569,7 +569,7 @@ config BUSYBOX_CONFIG_IP trying to be portable, it's better to use "ip CMD" forms. config BUSYBOX_CONFIG_IPADDR - bool "ipaddr (14 kb)" + bool "ipaddr (15 kb)" default BUSYBOX_DEFAULT_IPADDR select BUSYBOX_CONFIG_FEATURE_IP_ADDRESS help @@ -590,7 +590,7 @@ config BUSYBOX_CONFIG_IPROUTE Short form of "ip route" config BUSYBOX_CONFIG_IPTUNNEL - bool "iptunnel (9.6 kb)" + bool "iptunnel (9.8 kb)" default BUSYBOX_DEFAULT_IPTUNNEL select BUSYBOX_CONFIG_FEATURE_IP_TUNNEL help @@ -604,7 +604,7 @@ config BUSYBOX_CONFIG_IPRULE Short form of "ip rule" config BUSYBOX_CONFIG_IPNEIGH - bool "ipneigh (8.3 kb)" + bool "ipneigh (8.6 kb)" default BUSYBOX_DEFAULT_IPNEIGH select BUSYBOX_CONFIG_FEATURE_IP_NEIGH help @@ -624,6 +624,12 @@ config BUSYBOX_CONFIG_FEATURE_IP_LINK help Configure network devices with "ip". +config BUSYBOX_CONFIG_FEATURE_IP_LINK_CAN + bool "ip link set type can" + default BUSYBOX_DEFAULT_FEATURE_IP_LINK_CAN + help + Configure CAN devices with "ip". + config BUSYBOX_CONFIG_FEATURE_IP_ROUTE bool "ip route" default BUSYBOX_DEFAULT_FEATURE_IP_ROUTE @@ -669,7 +675,7 @@ config BUSYBOX_CONFIG_FEATURE_IP_RARE_PROTOCOLS Ethernet, wireless, infrared, ppp/slip, ip tunnelling link types are supported without this option selected. config BUSYBOX_CONFIG_IPCALC - bool "ipcalc (4.4 kb)" + bool "ipcalc (4.6 kb)" default BUSYBOX_DEFAULT_IPCALC help ipcalc takes an IP address and netmask and calculates the @@ -688,14 +694,14 @@ config BUSYBOX_CONFIG_FEATURE_IPCALC_FANCY Adds the options hostname, prefix and silent to the output of "ipcalc". config BUSYBOX_CONFIG_FAKEIDENTD - bool "fakeidentd (8.7 kb)" + bool "fakeidentd (9 kb)" default BUSYBOX_DEFAULT_FAKEIDENTD select BUSYBOX_CONFIG_FEATURE_SYSLOG help fakeidentd listens on the ident port and returns a predefined fake value on any query. config BUSYBOX_CONFIG_NAMEIF - bool "nameif (6.6 kb)" + bool "nameif (6.9 kb)" default BUSYBOX_DEFAULT_NAMEIF select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -723,7 +729,7 @@ config BUSYBOX_CONFIG_FEATURE_NAMEIF_EXTENDED new_interface_name mac=00:80:C8:38:91:B5 new_interface_name 00:80:C8:38:91:B5 config BUSYBOX_CONFIG_NBDCLIENT - bool "nbd-client (6 kb)" + bool "nbd-client (6.3 kb)" default BUSYBOX_DEFAULT_NBDCLIENT help Network block device client @@ -792,7 +798,7 @@ config BUSYBOX_CONFIG_FEATURE_NETSTAT_PRG Add support for -p flag to print out PID and program name. +700 bytes of code. config BUSYBOX_CONFIG_NSLOOKUP - bool "nslookup (9.7 kb)" + bool "nslookup (10 kb)" default BUSYBOX_DEFAULT_NSLOOKUP help nslookup is a tool to query Internet name servers. @@ -807,7 +813,7 @@ config BUSYBOX_CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS default BUSYBOX_DEFAULT_FEATURE_NSLOOKUP_LONG_OPTIONS depends on BUSYBOX_CONFIG_FEATURE_NSLOOKUP_BIG && BUSYBOX_CONFIG_LONG_OPTS config BUSYBOX_CONFIG_NTPD - bool "ntpd (22 kb)" + bool "ntpd (23 kb)" default BUSYBOX_DEFAULT_NTPD help The NTP client/server daemon. @@ -855,22 +861,22 @@ config BUSYBOX_CONFIG_FEATURE_FANCY_PING or terminate with SIGALRM in 5 seconds otherwise. No command-line options will be recognized. config BUSYBOX_CONFIG_PSCAN - bool "pscan (6 kb)" + bool "pscan (6.2 kb)" default BUSYBOX_DEFAULT_PSCAN help Simple network port scanner. config BUSYBOX_CONFIG_ROUTE - bool "route (8.7 kb)" + bool "route (9 kb)" default BUSYBOX_DEFAULT_ROUTE help Route displays or manipulates the kernel's IP routing tables. config BUSYBOX_CONFIG_SLATTACH - bool "slattach (6.2 kb)" + bool "slattach (6.3 kb)" default BUSYBOX_DEFAULT_SLATTACH help slattach configures serial line as SLIP network interface. config BUSYBOX_CONFIG_SSL_CLIENT - bool "ssl_client (25 kb)" + bool "ssl_client (28 kb)" default BUSYBOX_DEFAULT_SSL_CLIENT select BUSYBOX_CONFIG_TLS help @@ -929,7 +935,7 @@ config BUSYBOX_CONFIG_FEATURE_TELNET_WIDTH default BUSYBOX_DEFAULT_FEATURE_TELNET_WIDTH depends on BUSYBOX_CONFIG_TELNET config BUSYBOX_CONFIG_TELNETD - bool "telnetd (12 kb)" + bool "telnetd (13 kb)" default BUSYBOX_DEFAULT_TELNETD select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -1076,7 +1082,7 @@ config BUSYBOX_CONFIG_TRACEROUTE Utility to trace the route of IP packets. config BUSYBOX_CONFIG_TRACEROUTE6 - bool "traceroute6 (13 kb)" + bool "traceroute6 (12 kb)" default BUSYBOX_DEFAULT_TRACEROUTE6 depends on BUSYBOX_CONFIG_FEATURE_IPV6 help @@ -1095,7 +1101,7 @@ config BUSYBOX_CONFIG_FEATURE_TRACEROUTE_USE_ICMP default BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_USE_ICMP depends on BUSYBOX_CONFIG_TRACEROUTE || BUSYBOX_CONFIG_TRACEROUTE6 config BUSYBOX_CONFIG_TUNCTL - bool "tunctl (6.2 kb)" + bool "tunctl (6.4 kb)" default BUSYBOX_DEFAULT_TUNCTL help tunctl creates or deletes tun devices. @@ -1108,12 +1114,12 @@ config BUSYBOX_CONFIG_FEATURE_TUNCTL_UG Allow to specify owner and group of newly created interface. 340 bytes of pure bloat. Say no here. config BUSYBOX_CONFIG_VCONFIG - bool "vconfig (2.3 kb)" + bool "vconfig (2.6 kb)" default BUSYBOX_DEFAULT_VCONFIG help Creates, removes, and configures VLAN interfaces config BUSYBOX_CONFIG_WGET - bool "wget (38 kb)" + bool "wget (41 kb)" default BUSYBOX_DEFAULT_WGET help wget is a utility for non-interactive download of files from HTTP @@ -1233,12 +1239,12 @@ config BUSYBOX_CONFIG_FEATURE_WGET_OPENSSL By default TLS verification is performed, unless --no-check-certificate option is passed. config BUSYBOX_CONFIG_WHOIS - bool "whois (6.3 kb)" + bool "whois (6.5 kb)" default BUSYBOX_DEFAULT_WHOIS help whois is a client for the whois directory service config BUSYBOX_CONFIG_ZCIP - bool "zcip (8.4 kb)" + bool "zcip (8.7 kb)" default BUSYBOX_DEFAULT_ZCIP select BUSYBOX_CONFIG_FEATURE_SYSLOG help diff --git a/package/utils/busybox/config/networking/udhcp/Config.in b/package/utils/busybox/config/networking/udhcp/Config.in index 6757f1efc9c9a6..3c88e285a1ec40 100644 --- a/package/utils/busybox/config/networking/udhcp/Config.in +++ b/package/utils/busybox/config/networking/udhcp/Config.in @@ -11,6 +11,13 @@ config BUSYBOX_CONFIG_UDHCPD udhcpd is a DHCP server geared primarily toward embedded systems, while striving to be fully functional and RFC compliant. +config BUSYBOX_CONFIG_FEATURE_UDHCPD_BOOTP + bool "Answer to BOOTP requests as well" + default BUSYBOX_DEFAULT_FEATURE_UDHCPD_BOOTP + depends on BUSYBOX_CONFIG_UDHCPD + help + Support old BOOTP protocol too. + config BUSYBOX_CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC bool "Select IP address based on client MAC" default BUSYBOX_DEFAULT_FEATURE_UDHCPD_BASE_IP_ON_MAC @@ -44,7 +51,7 @@ config BUSYBOX_CONFIG_DHCPD_LEASES_FILE of the file. Normally it is safe to leave it untouched. config BUSYBOX_CONFIG_DUMPLEASES - bool "dumpleases (5.1 kb)" + bool "dumpleases (5.3 kb)" default BUSYBOX_DEFAULT_DUMPLEASES help dumpleases displays the leases written out by the udhcpd. @@ -52,7 +59,7 @@ config BUSYBOX_CONFIG_DUMPLEASES by the absolute time that it expires in seconds from epoch. config BUSYBOX_CONFIG_DHCPRELAY - bool "dhcprelay (5.2 kb)" + bool "dhcprelay (5.5 kb)" default BUSYBOX_DEFAULT_DHCPRELAY help dhcprelay listens for DHCP requests on one or more interfaces diff --git a/package/utils/busybox/config/printutils/Config.in b/package/utils/busybox/config/printutils/Config.in index c53ee19d4eacc6..a320c87ebca237 100644 --- a/package/utils/busybox/config/printutils/Config.in +++ b/package/utils/busybox/config/printutils/Config.in @@ -7,18 +7,18 @@ menu "Print Utilities" config BUSYBOX_CONFIG_LPD - bool "lpd (5.5 kb)" + bool "lpd (5.7 kb)" default BUSYBOX_DEFAULT_LPD help lpd is a print spooling daemon. config BUSYBOX_CONFIG_LPR - bool "lpr (9.9 kb)" + bool "lpr (10 kb)" default BUSYBOX_DEFAULT_LPR help lpr sends files (or standard input) to a print spooling daemon. config BUSYBOX_CONFIG_LPQ - bool "lpq (9.9 kb)" + bool "lpq (10 kb)" default BUSYBOX_DEFAULT_LPQ help lpq is a print spool queue examination and manipulation program. diff --git a/package/utils/busybox/config/procps/Config.in b/package/utils/busybox/config/procps/Config.in index 0501daf8fd2de1..1524f61dc74ec1 100644 --- a/package/utils/busybox/config/procps/Config.in +++ b/package/utils/busybox/config/procps/Config.in @@ -22,26 +22,26 @@ config BUSYBOX_CONFIG_FEATURE_SHOW_THREADS and 'h' command in top. config BUSYBOX_CONFIG_FREE - bool "free (3.1 kb)" + bool "free (3.8 kb)" default BUSYBOX_DEFAULT_FREE help free displays the total amount of free and used physical and swap memory in the system, as well as the buffers used by the kernel. The shared memory column should be ignored; it is obsolete. config BUSYBOX_CONFIG_FUSER - bool "fuser (7 kb)" + bool "fuser (7.3 kb)" default BUSYBOX_DEFAULT_FUSER help fuser lists all PIDs (Process IDs) that currently have a given file open. fuser can also list all PIDs that have a given network (TCP or UDP) port open. config BUSYBOX_CONFIG_IOSTAT - bool "iostat (7.6 kb)" + bool "iostat (8 kb)" default BUSYBOX_DEFAULT_IOSTAT help Report CPU and I/O statistics config BUSYBOX_CONFIG_KILL - bool "kill (3.1 kb)" + bool "kill (3.4 kb)" default BUSYBOX_DEFAULT_KILL help The command kill sends the specified signal to the specified @@ -49,7 +49,7 @@ config BUSYBOX_CONFIG_KILL signal is sent. config BUSYBOX_CONFIG_KILLALL - bool "killall (5.6 kb)" + bool "killall (5.9 kb)" default BUSYBOX_DEFAULT_KILLALL help killall sends a signal to all processes running any of the @@ -57,7 +57,7 @@ config BUSYBOX_CONFIG_KILLALL sent. config BUSYBOX_CONFIG_KILLALL5 - bool "killall5 (5.3 kb)" + bool "killall5 (5.6 kb)" default BUSYBOX_DEFAULT_KILLALL5 help The SystemV killall command. killall5 sends a signal @@ -65,34 +65,34 @@ config BUSYBOX_CONFIG_KILLALL5 in its own session, so it won't kill the shell that is running the script it was called from. config BUSYBOX_CONFIG_LSOF - bool "lsof (3.4 kb)" + bool "lsof (3.7 kb)" default BUSYBOX_DEFAULT_LSOF help Show open files in the format of: PID /path/to/executable /path/to/opened/file config BUSYBOX_CONFIG_MPSTAT - bool "mpstat (9.8 kb)" + bool "mpstat (10 kb)" default BUSYBOX_DEFAULT_MPSTAT help Per-processor statistics config BUSYBOX_CONFIG_NMETER - bool "nmeter (11 kb)" + bool "nmeter (12 kb)" default BUSYBOX_DEFAULT_NMETER help Prints selected system stats continuously, one line per update. config BUSYBOX_CONFIG_PGREP - bool "pgrep (6.5 kb)" + bool "pgrep (6.8 kb)" default BUSYBOX_DEFAULT_PGREP help Look for processes by name. config BUSYBOX_CONFIG_PKILL - bool "pkill (7.5 kb)" + bool "pkill (7.8 kb)" default BUSYBOX_DEFAULT_PKILL help Send signals to processes by name. config BUSYBOX_CONFIG_PIDOF - bool "pidof (6.3 kb)" + bool "pidof (6.5 kb)" default BUSYBOX_DEFAULT_PIDOF help Pidof finds the process id's (pids) of the named programs. It prints @@ -114,12 +114,12 @@ config BUSYBOX_CONFIG_FEATURE_PIDOF_OMIT The special pid %PPID can be used to name the parent process of the pidof, in other words the calling shell or shell script. config BUSYBOX_CONFIG_PMAP - bool "pmap (6 kb)" + bool "pmap (6.2 kb)" default BUSYBOX_DEFAULT_PMAP help Display processes' memory mappings. config BUSYBOX_CONFIG_POWERTOP - bool "powertop (9.6 kb)" + bool "powertop (9.9 kb)" default BUSYBOX_DEFAULT_POWERTOP help Analyze power consumption on Intel-based laptops @@ -132,7 +132,7 @@ config BUSYBOX_CONFIG_FEATURE_POWERTOP_INTERACTIVE Without this, powertop will only refresh display every 10 seconds. No keyboard commands will work, only ^C to terminate. config BUSYBOX_CONFIG_PS - bool "ps (11 kb)" + bool "ps (12 kb)" default BUSYBOX_DEFAULT_PS help ps gives a snapshot of the current processes. @@ -172,23 +172,23 @@ config BUSYBOX_CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS default BUSYBOX_DEFAULT_FEATURE_PS_ADDITIONAL_COLUMNS depends on (BUSYBOX_CONFIG_PS || BUSYBOX_CONFIG_MINIPS) && BUSYBOX_CONFIG_DESKTOP config BUSYBOX_CONFIG_PSTREE - bool "pstree (9.3 kb)" + bool "pstree (9.4 kb)" default BUSYBOX_DEFAULT_PSTREE help Display a tree of processes. config BUSYBOX_CONFIG_PWDX - bool "pwdx (3.7 kb)" + bool "pwdx (3.9 kb)" default BUSYBOX_DEFAULT_PWDX help Report current working directory of a process config BUSYBOX_CONFIG_SMEMCAP - bool "smemcap (2.5 kb)" + bool "smemcap (3 kb)" default BUSYBOX_DEFAULT_SMEMCAP help smemcap is a tool for capturing process data for smem, a memory usage statistic tool. config BUSYBOX_CONFIG_BB_SYSCTL - bool "sysctl (7.4 kb)" + bool "sysctl (7.9 kb)" default BUSYBOX_DEFAULT_BB_SYSCTL help Configure kernel parameters at runtime. @@ -254,7 +254,7 @@ config BUSYBOX_CONFIG_FEATURE_TOPMEM help Enable 's' in top (gives lots of memory info). config BUSYBOX_CONFIG_UPTIME - bool "uptime (3.7 kb)" + bool "uptime (4 kb)" default BUSYBOX_DEFAULT_UPTIME help uptime gives a one line display of the current time, how long @@ -268,7 +268,7 @@ config BUSYBOX_CONFIG_FEATURE_UPTIME_UTMP_SUPPORT help Display the number of users currently logged on. config BUSYBOX_CONFIG_WATCH - bool "watch (4.4 kb)" + bool "watch (5.2 kb)" default BUSYBOX_DEFAULT_WATCH help watch is used to execute a program periodically, showing diff --git a/package/utils/busybox/config/runit/Config.in b/package/utils/busybox/config/runit/Config.in index 2c701f2136e85d..3a95619bde9bf9 100644 --- a/package/utils/busybox/config/runit/Config.in +++ b/package/utils/busybox/config/runit/Config.in @@ -7,44 +7,44 @@ menu "Runit Utilities" config BUSYBOX_CONFIG_CHPST - bool "chpst (9 kb)" + bool "chpst (9.2 kb)" default BUSYBOX_DEFAULT_CHPST help chpst changes the process state according to the given options, and execs specified program. config BUSYBOX_CONFIG_SETUIDGID - bool "setuidgid (4 kb)" + bool "setuidgid (4.2 kb)" default BUSYBOX_DEFAULT_SETUIDGID help Sets soft resource limits as specified by options config BUSYBOX_CONFIG_ENVUIDGID - bool "envuidgid (3.9 kb)" + bool "envuidgid (4.1 kb)" default BUSYBOX_DEFAULT_ENVUIDGID help Sets $UID to account's uid and $GID to account's gid config BUSYBOX_CONFIG_ENVDIR - bool "envdir (2.5 kb)" + bool "envdir (2.9 kb)" default BUSYBOX_DEFAULT_ENVDIR help Sets various environment variables as specified by files in the given directory config BUSYBOX_CONFIG_SOFTLIMIT - bool "softlimit (4.5 kb)" + bool "softlimit (4.7 kb)" default BUSYBOX_DEFAULT_SOFTLIMIT help Sets soft resource limits as specified by options config BUSYBOX_CONFIG_RUNSV - bool "runsv (7.8 kb)" + bool "runsv (8.2 kb)" default BUSYBOX_DEFAULT_RUNSV help runsv starts and monitors a service and optionally an appendant log service. config BUSYBOX_CONFIG_RUNSVDIR - bool "runsvdir (6.3 kb)" + bool "runsvdir (6.6 kb)" default BUSYBOX_DEFAULT_RUNSVDIR help runsvdir starts a runsv process for each subdirectory, or symlink to @@ -60,7 +60,7 @@ config BUSYBOX_CONFIG_FEATURE_RUNSVDIR_LOG message (viewable via top/ps). Otherwise (feature is off or no parameter), error messages go to stderr only. config BUSYBOX_CONFIG_SV - bool "sv (8.5 kb)" + bool "sv (8.7 kb)" default BUSYBOX_DEFAULT_SV help sv reports the current status and controls the state of services @@ -75,14 +75,14 @@ config BUSYBOX_CONFIG_SV_DEFAULT_SERVICE_DIR Defaults to "/var/service" config BUSYBOX_CONFIG_SVC - bool "svc (8.4 kb)" + bool "svc (8.7 kb)" default BUSYBOX_DEFAULT_SVC help svc controls the state of services monitored by the runsv supervisor. It is compatible with daemontools command with the same name. config BUSYBOX_CONFIG_SVOK - bool "svok (1.5 kb)" + bool "svok (1.8 kb)" default BUSYBOX_DEFAULT_SVOK help svok checks whether runsv supervisor is running. diff --git a/package/utils/busybox/config/shell/Config.in b/package/utils/busybox/config/shell/Config.in index a68e9114ef7761..848609a8409f32 100644 --- a/package/utils/busybox/config/shell/Config.in +++ b/package/utils/busybox/config/shell/Config.in @@ -87,7 +87,7 @@ config BUSYBOX_CONFIG_SHELL_ASH depends on !BUSYBOX_CONFIG_NOMMU config BUSYBOX_CONFIG_ASH - bool "ash (78 kb)" + bool "ash (80 kb)" default BUSYBOX_DEFAULT_ASH depends on !BUSYBOX_CONFIG_NOMMU select BUSYBOX_CONFIG_SHELL_ASH @@ -201,11 +201,6 @@ config BUSYBOX_CONFIG_ASH_TEST default BUSYBOX_DEFAULT_ASH_TEST depends on BUSYBOX_CONFIG_SHELL_ASH -config BUSYBOX_CONFIG_ASH_SLEEP - bool "sleep builtin" - default BUSYBOX_DEFAULT_ASH_SLEEP - depends on BUSYBOX_CONFIG_SHELL_ASH - config BUSYBOX_CONFIG_ASH_HELP bool "help builtin" default BUSYBOX_DEFAULT_ASH_HELP @@ -227,7 +222,7 @@ config BUSYBOX_CONFIG_ASH_CMDCMD endif # ash options config BUSYBOX_CONFIG_CTTYHACK - bool "cttyhack (2.4 kb)" + bool "cttyhack (2.7 kb)" default BUSYBOX_DEFAULT_CTTYHACK help One common problem reported on the mailing list is the "can't @@ -270,7 +265,7 @@ config BUSYBOX_CONFIG_CTTYHACK # getty 115200 $(cttyhack) config BUSYBOX_CONFIG_HUSH - bool "hush (68 kb)" + bool "hush (70 kb)" default BUSYBOX_DEFAULT_HUSH select BUSYBOX_CONFIG_SHELL_HUSH help diff --git a/package/utils/busybox/config/sysklogd/Config.in b/package/utils/busybox/config/sysklogd/Config.in index 1aa2ea005fdcf2..5f982ed9c22e89 100644 --- a/package/utils/busybox/config/sysklogd/Config.in +++ b/package/utils/busybox/config/sysklogd/Config.in @@ -7,7 +7,7 @@ menu "System Logging Utilities" config BUSYBOX_CONFIG_KLOGD - bool "klogd (5.7 kb)" + bool "klogd (6.2 kb)" default BUSYBOX_DEFAULT_KLOGD help klogd is a utility which intercepts and logs all @@ -35,7 +35,7 @@ config BUSYBOX_CONFIG_FEATURE_KLOGD_KLOGCTL If in doubt, say 'Y'. config BUSYBOX_CONFIG_LOGGER - bool "logger (6.3 kb)" + bool "logger (6.5 kb)" default BUSYBOX_DEFAULT_LOGGER select BUSYBOX_CONFIG_FEATURE_SYSLOG help @@ -44,7 +44,7 @@ config BUSYBOX_CONFIG_LOGGER they can be logged. This is generally used to help locate problems that occur within programs and scripts. config BUSYBOX_CONFIG_LOGREAD - bool "logread (4.8 kb)" + bool "logread (5 kb)" default BUSYBOX_DEFAULT_LOGREAD help If you enabled Circular Buffer support, you almost @@ -64,7 +64,7 @@ config BUSYBOX_CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING contention at some minor memory expense. config BUSYBOX_CONFIG_SYSLOGD - bool "syslogd (13 kb)" + bool "syslogd (14 kb)" default BUSYBOX_DEFAULT_SYSLOGD help The syslogd utility is used to record logs of all the diff --git a/package/utils/busybox/config/util-linux/Config.in b/package/utils/busybox/config/util-linux/Config.in index e3e59f1506d9a9..18ba619db023cc 100644 --- a/package/utils/busybox/config/util-linux/Config.in +++ b/package/utils/busybox/config/util-linux/Config.in @@ -7,7 +7,7 @@ menu "Linux System Utilities" config BUSYBOX_CONFIG_ACPID - bool "acpid (9 kb)" + bool "acpid (9.3 kb)" default BUSYBOX_DEFAULT_ACPID help acpid listens to ACPI events coming either in textual form from @@ -28,7 +28,7 @@ config BUSYBOX_CONFIG_FEATURE_ACPID_COMPAT help Accept and ignore compatibility options -g -m -s -S -v. config BUSYBOX_CONFIG_BLKDISCARD - bool "blkdiscard (4.3 kb)" + bool "blkdiscard (4.6 kb)" default BUSYBOX_DEFAULT_BLKDISCARD help blkdiscard discards sectors on a given device. @@ -46,23 +46,23 @@ config BUSYBOX_CONFIG_FEATURE_BLKID_TYPE help Show TYPE="filesystem type" config BUSYBOX_CONFIG_BLOCKDEV - bool "blockdev (2.3 kb)" + bool "blockdev (2.6 kb)" default BUSYBOX_DEFAULT_BLOCKDEV help Performs some ioctls with block devices. config BUSYBOX_CONFIG_CAL - bool "cal (5.8 kb)" + bool "cal (6.1 kb)" default BUSYBOX_DEFAULT_CAL help cal is used to display a monthly calendar. config BUSYBOX_CONFIG_CHRT - bool "chrt (4.7 kb)" + bool "chrt (5.1 kb)" default BUSYBOX_DEFAULT_CHRT help Manipulate real-time attributes of a process. This requires sched_{g,s}etparam support in your libc. config BUSYBOX_CONFIG_DMESG - bool "dmesg (3.7 kb)" + bool "dmesg (3.9 kb)" default BUSYBOX_DEFAULT_DMESG help dmesg is used to examine or control the kernel ring buffer. When the @@ -94,7 +94,7 @@ config BUSYBOX_CONFIG_FEATURE_DMESG_PRETTY <6>BIOS-provided physical RAM map: <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable) config BUSYBOX_CONFIG_EJECT - bool "eject (4 kb)" + bool "eject (4.3 kb)" default BUSYBOX_DEFAULT_EJECT help Used to eject cdroms. (defaults to /dev/cdrom) @@ -107,17 +107,17 @@ config BUSYBOX_CONFIG_FEATURE_EJECT_SCSI Add the -s option to eject, this allows to eject SCSI-Devices and usb-storage devices. config BUSYBOX_CONFIG_FALLOCATE - bool "fallocate (4.1 kb)" + bool "fallocate (4.3 kb)" default BUSYBOX_DEFAULT_FALLOCATE help Preallocate space for files. config BUSYBOX_CONFIG_FATATTR - bool "fatattr (1.9 kb)" + bool "fatattr (2.2 kb)" default BUSYBOX_DEFAULT_FATATTR help fatattr lists or changes the file attributes on a fat file system. config BUSYBOX_CONFIG_FBSET - bool "fbset (5.9 kb)" + bool "fbset (6.2 kb)" default BUSYBOX_DEFAULT_FBSET help fbset is used to show or change the settings of a Linux frame buffer @@ -144,12 +144,12 @@ config BUSYBOX_CONFIG_FEATURE_FBSET_READMODE default BUSYBOX_DEFAULT_FEATURE_FBSET_READMODE /etc/fb.modes, which can be used to set frame buffer device to pre-defined video modes. config BUSYBOX_CONFIG_FDFORMAT - bool "fdformat (4.4 kb)" + bool "fdformat (4.7 kb)" default BUSYBOX_DEFAULT_FDFORMAT help fdformat is used to low-level format a floppy disk. config BUSYBOX_CONFIG_FDISK - bool "fdisk (37 kb)" + bool "fdisk (31 kb)" default BUSYBOX_DEFAULT_FDISK help The fdisk utility is used to divide hard disks into one or more @@ -222,18 +222,18 @@ config BUSYBOX_CONFIG_FEATURE_FDISK_ADVANCED partition, and similarly evil things. Unless you have a very good reason you would be wise to leave this disabled. config BUSYBOX_CONFIG_FINDFS - bool "findfs (12 kb)" + bool "findfs (11 kb)" default BUSYBOX_DEFAULT_FINDFS select BUSYBOX_CONFIG_VOLUMEID help Prints the name of a filesystem with given label or UUID. config BUSYBOX_CONFIG_FLOCK - bool "flock (6.3 kb)" + bool "flock (6.5 kb)" default BUSYBOX_DEFAULT_FLOCK help Manage locks from shell scripts config BUSYBOX_CONFIG_FDFLUSH - bool "fdflush (1.3 kb)" + bool "fdflush (1.6 kb)" default BUSYBOX_DEFAULT_FDFLUSH help fdflush is only needed when changing media on slightly-broken @@ -245,7 +245,7 @@ config BUSYBOX_CONFIG_FDFLUSH leave this disabled. config BUSYBOX_CONFIG_FREERAMDISK - bool "freeramdisk (1.3 kb)" + bool "freeramdisk (1.6 kb)" default BUSYBOX_DEFAULT_FREERAMDISK help Linux allows you to create ramdisks. This utility allows you to @@ -265,18 +265,18 @@ config BUSYBOX_CONFIG_FSCK_MINIX check for and attempt to repair any corruption that occurs to a minix filesystem. config BUSYBOX_CONFIG_FSFREEZE - bool "fsfreeze (3.5 kb)" + bool "fsfreeze (3.7 kb)" default BUSYBOX_DEFAULT_FSFREEZE select BUSYBOX_CONFIG_LONG_OPTS help Halt new accesses and flush writes on a mounted filesystem. config BUSYBOX_CONFIG_FSTRIM - bool "fstrim (4.4 kb)" + bool "fstrim (4.6 kb)" default BUSYBOX_DEFAULT_FSTRIM help Discard unused blocks on a mounted filesystem. config BUSYBOX_CONFIG_GETOPT - bool "getopt (5.8 kb)" + bool "getopt (6 kb)" default BUSYBOX_DEFAULT_GETOPT help The getopt utility is used to break up (parse) options in command @@ -293,26 +293,27 @@ config BUSYBOX_CONFIG_FEATURE_GETOPT_LONG help Enable support for long options (option -l). config BUSYBOX_CONFIG_HEXDUMP - bool "hexdump (8.6 kb)" + bool "hexdump (8.7 kb)" default BUSYBOX_DEFAULT_HEXDUMP help The hexdump utility is used to display binary data in a readable way that is comparable to the output from most hex editors. config BUSYBOX_CONFIG_HD - bool "hd (7.8 kb)" + bool "hd (8.3 kb)" default BUSYBOX_DEFAULT_HD help hd is an alias to hexdump -C. config BUSYBOX_CONFIG_XXD - bool "xxd (8.9 kb)" + bool "xxd (11 kb)" default BUSYBOX_DEFAULT_XXD help The xxd utility is used to display binary data in a readable way that is comparable to the output from most hex editors. config BUSYBOX_CONFIG_HWCLOCK - bool "hwclock (5.8 kb)" + bool "hwclock (5.9 kb)" default BUSYBOX_DEFAULT_HWCLOCK + select BUSYBOX_CONFIG_LONG_OPTS help The hwclock utility is used to read and set the hardware clock on a system. This is primarily used to set the current time on @@ -331,26 +332,26 @@ config BUSYBOX_CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO config BUSYBOX_CONFIG_IONICE - bool "ionice (3.8 kb)" + bool "ionice (4 kb)" default BUSYBOX_DEFAULT_IONICE help Set/set program io scheduling class and priority Requires kernel >= 2.6.13 config BUSYBOX_CONFIG_IPCRM - bool "ipcrm (3.2 kb)" + bool "ipcrm (3.5 kb)" default BUSYBOX_DEFAULT_IPCRM help The ipcrm utility allows the removal of System V interprocess communication (IPC) objects and the associated data structures from the system. config BUSYBOX_CONFIG_IPCS - bool "ipcs (11 kb)" + bool "ipcs (12 kb)" default BUSYBOX_DEFAULT_IPCS help The ipcs utility is used to provide information on the currently allocated System V interprocess (IPC) objects in the system. config BUSYBOX_CONFIG_LAST - bool "last (6.1 kb)" + bool "last (7.4 kb)" default BUSYBOX_DEFAULT_LAST depends on BUSYBOX_CONFIG_FEATURE_WTMP help @@ -364,14 +365,14 @@ config BUSYBOX_CONFIG_FEATURE_LAST_FANCY 'last' displays detailed information about the last users that logged into the system (mimics sysvinit last). +900 bytes. config BUSYBOX_CONFIG_LOSETUP - bool "losetup (5.5 kb)" + bool "losetup (6.2 kb)" default BUSYBOX_DEFAULT_LOSETUP help losetup is used to associate or detach a loop device with a regular file or block device, and to query the status of a loop device. This version does not currently support enabling data encryption. config BUSYBOX_CONFIG_LSPCI - bool "lspci (6.3 kb)" + bool "lspci (6.4 kb)" default BUSYBOX_DEFAULT_LSPCI help lspci is a utility for displaying information about PCI buses in the @@ -379,7 +380,7 @@ config BUSYBOX_CONFIG_LSPCI This version uses sysfs (/sys/bus/pci/devices) only. config BUSYBOX_CONFIG_LSUSB - bool "lsusb (4.2 kb)" + bool "lsusb (4.4 kb)" default BUSYBOX_DEFAULT_LSUSB help lsusb is a utility for displaying information about USB buses in the @@ -387,7 +388,7 @@ config BUSYBOX_CONFIG_LSUSB This version uses sysfs (/sys/bus/usb/devices) only. config BUSYBOX_CONFIG_MDEV - bool "mdev (17 kb)" + bool "mdev (20 kb)" default BUSYBOX_DEFAULT_MDEV help mdev is a mini-udev implementation for dynamically creating device @@ -454,7 +455,7 @@ config BUSYBOX_CONFIG_FEATURE_MDEV_DAEMON resources than registering mdev as hotplug helper or using the uevent applet. config BUSYBOX_CONFIG_MESG - bool "mesg (1.4 kb)" + bool "mesg (1.8 kb)" default BUSYBOX_DEFAULT_MESG help Mesg controls access to your terminal by others. It is typically @@ -505,18 +506,18 @@ config BUSYBOX_CONFIG_MKFS_REISER Utility to create ReiserFS filesystems. Note: this applet needs a lot of testing and polishing. config BUSYBOX_CONFIG_MKDOSFS - bool "mkdosfs (7.2 kb)" + bool "mkdosfs (7.6 kb)" default BUSYBOX_DEFAULT_MKDOSFS help Utility to create FAT32 filesystems. config BUSYBOX_CONFIG_MKFS_VFAT - bool "mkfs.vfat (7.2 kb)" + bool "mkfs.vfat (7.6 kb)" default BUSYBOX_DEFAULT_MKFS_VFAT help Alias to "mkdosfs". config BUSYBOX_CONFIG_MKSWAP - bool "mkswap (6.3 kb)" + bool "mkswap (6.6 kb)" default BUSYBOX_DEFAULT_MKSWAP help The mkswap utility is used to configure a file or disk partition as @@ -535,7 +536,7 @@ config BUSYBOX_CONFIG_FEATURE_MKSWAP_UUID help Generate swap spaces with universally unique identifiers. config BUSYBOX_CONFIG_MORE - bool "more (7 kb)" + bool "more (7.2 kb)" default BUSYBOX_DEFAULT_MORE help more is a simple utility which allows you to read text one screen @@ -544,7 +545,7 @@ config BUSYBOX_CONFIG_MORE you will probably find this utility very helpful. If you don't have any need to reading text files, you can leave this disabled. config BUSYBOX_CONFIG_MOUNT - bool "mount (23 kb)" + bool "mount (24 kb)" default BUSYBOX_DEFAULT_MOUNT help All files and filesystems in Unix are arranged into one big directory @@ -634,7 +635,7 @@ config BUSYBOX_CONFIG_FEATURE_MOUNT_OTHERTAB help Support mount -T (specifying an alternate fstab) config BUSYBOX_CONFIG_MOUNTPOINT - bool "mountpoint (4.9 kb)" + bool "mountpoint (5.1 kb)" default BUSYBOX_DEFAULT_MOUNTPOINT help mountpoint checks if the directory is a mountpoint. @@ -659,12 +660,12 @@ config BUSYBOX_CONFIG_NOLOGIN_DEPENDENCIES If you know these will be available externally you can disable this option. config BUSYBOX_CONFIG_NSENTER - bool "nsenter (6.5 kb)" + bool "nsenter (6.8 kb)" default BUSYBOX_DEFAULT_NSENTER help Run program with namespaces of other processes. config BUSYBOX_CONFIG_PIVOT_ROOT - bool "pivot_root (1.1 kb)" + bool "pivot_root (1.4 kb)" default BUSYBOX_DEFAULT_PIVOT_ROOT help The pivot_root utility swaps the mount points for the root filesystem @@ -675,7 +676,7 @@ config BUSYBOX_CONFIG_PIVOT_ROOT Note: This is for initrd in linux 2.4. Under initramfs (introduced in linux 2.6) use switch_root instead. config BUSYBOX_CONFIG_RDATE - bool "rdate (5.6 kb)" + bool "rdate (5.9 kb)" default BUSYBOX_DEFAULT_RDATE help The rdate utility allows you to synchronize the date and time of your @@ -683,44 +684,44 @@ config BUSYBOX_CONFIG_RDATE the RFC868 protocol, which is built into the inetd daemon on most systems. config BUSYBOX_CONFIG_RDEV - bool "rdev (1.8 kb)" + bool "rdev (2.1 kb)" default BUSYBOX_DEFAULT_RDEV help Print the device node associated with the filesystem mounted at '/'. config BUSYBOX_CONFIG_READPROFILE - bool "readprofile (7.1 kb)" + bool "readprofile (7.5 kb)" default BUSYBOX_DEFAULT_READPROFILE help This allows you to parse /proc/profile for basic profiling. config BUSYBOX_CONFIG_RENICE - bool "renice (4.2 kb)" + bool "renice (4.4 kb)" default BUSYBOX_DEFAULT_RENICE help Renice alters the scheduling priority of one or more running processes. config BUSYBOX_CONFIG_REV - bool "rev (4.4 kb)" + bool "rev (4.6 kb)" default BUSYBOX_DEFAULT_REV help Reverse lines of a file or files. config BUSYBOX_CONFIG_RTCWAKE - bool "rtcwake (6.8 kb)" + bool "rtcwake (7.5 kb)" default BUSYBOX_DEFAULT_RTCWAKE help Enter a system sleep state until specified wakeup time. config BUSYBOX_CONFIG_SCRIPT - bool "script (8.6 kb)" + bool "script (8.8 kb)" default BUSYBOX_DEFAULT_SCRIPT help The script makes typescript of terminal session. config BUSYBOX_CONFIG_SCRIPTREPLAY - bool "scriptreplay (2.4 kb)" + bool "scriptreplay (2.6 kb)" default BUSYBOX_DEFAULT_SCRIPTREPLAY help This program replays a typescript, using timing information given by script -t. config BUSYBOX_CONFIG_SETARCH - bool "setarch (3.6 kb)" + bool "setarch (3.8 kb)" default BUSYBOX_DEFAULT_SETARCH help The linux32 utility is used to create a 32bit environment for the @@ -729,18 +730,18 @@ config BUSYBOX_CONFIG_SETARCH (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). config BUSYBOX_CONFIG_LINUX32 - bool "linux32 (3.3 kb)" + bool "linux32 (3.6 kb)" default BUSYBOX_DEFAULT_LINUX32 help Alias to "setarch linux32". config BUSYBOX_CONFIG_LINUX64 - bool "linux64 (3.3 kb)" + bool "linux64 (3.5 kb)" default BUSYBOX_DEFAULT_LINUX64 help Alias to "setarch linux64". config BUSYBOX_CONFIG_SETPRIV - bool "setpriv (6.6 kb)" + bool "setpriv (6.9 kb)" default BUSYBOX_DEFAULT_SETPRIV select BUSYBOX_CONFIG_LONG_OPTS help @@ -775,7 +776,7 @@ config BUSYBOX_CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES this option allows using the human-readable names in addition to the index-based names. config BUSYBOX_CONFIG_SETSID - bool "setsid (3.6 kb)" + bool "setsid (3.8 kb)" default BUSYBOX_DEFAULT_SETSID help setsid runs a program in a new session @@ -818,7 +819,7 @@ config BUSYBOX_CONFIG_FEATURE_SWAPONOFF_LABEL This allows for specifying a device by label or uuid, rather than by name. This feature utilizes the same functionality as blkid/findfs. config BUSYBOX_CONFIG_SWITCH_ROOT - bool "switch_root (5.5 kb)" + bool "switch_root (5.7 kb)" default BUSYBOX_DEFAULT_SWITCH_ROOT help The switch_root utility is used from initramfs to select a new @@ -837,7 +838,7 @@ config BUSYBOX_CONFIG_SWITCH_ROOT list of active mount points. That's why. config BUSYBOX_CONFIG_TASKSET - bool "taskset (4.2 kb)" + bool "taskset (5.6 kb)" default BUSYBOX_DEFAULT_TASKSET help Retrieve or set a processes's CPU affinity. @@ -860,7 +861,7 @@ config BUSYBOX_CONFIG_FEATURE_TASKSET_CPULIST Add support for taking/printing affinity as CPU list when '-c' option is used. For example, it prints '0-3,7' instead of mask '8f'. config BUSYBOX_CONFIG_UEVENT - bool "uevent (3.1 kb)" + bool "uevent (3.5 kb)" default BUSYBOX_DEFAULT_UEVENT help uevent is a netlink listener for kernel uevent notifications @@ -881,14 +882,14 @@ config BUSYBOX_CONFIG_FEATURE_UMOUNT_ALL help Support -a option to unmount all currently mounted filesystems. config BUSYBOX_CONFIG_UNSHARE - bool "unshare (7.2 kb)" + bool "unshare (7.3 kb)" default BUSYBOX_DEFAULT_UNSHARE depends on !BUSYBOX_CONFIG_NOMMU select BUSYBOX_CONFIG_LONG_OPTS help Run program with some namespaces unshared from parent. config BUSYBOX_CONFIG_WALL - bool "wall (2.6 kb)" + bool "wall (2.9 kb)" default BUSYBOX_DEFAULT_WALL depends on BUSYBOX_CONFIG_FEATURE_UTMP help diff --git a/package/utils/busybox/files/cron b/package/utils/busybox/files/cron index 4efdfa52cad32b..2ddffa61e48359 100755 --- a/package/utils/busybox/files/cron +++ b/package/utils/busybox/files/cron @@ -28,7 +28,7 @@ start_service() { ln -s /etc/crontabs /var/spool/cron/ 2>/dev/null procd_open_instance - procd_set_param command "$PROG" -f -c /etc/crontabs -l "${loglevel:-5}" + procd_set_param command "$PROG" -f -c /etc/crontabs -l "${loglevel:-7}" for crontab in /etc/crontabs/*; do procd_set_param file "$crontab" done diff --git a/package/utils/busybox/patches/001-fix-non-x86-build.patch b/package/utils/busybox/patches/001-fix-non-x86-build.patch new file mode 100644 index 00000000000000..b33ec98bf29968 --- /dev/null +++ b/package/utils/busybox/patches/001-fix-non-x86-build.patch @@ -0,0 +1,14 @@ +Index: busybox-1.37.0/libbb/hash_md5_sha.c +=================================================================== +--- busybox-1.37.0.orig/libbb/hash_md5_sha.c ++++ busybox-1.37.0/libbb/hash_md5_sha.c +@@ -1313,7 +1313,9 @@ unsigned FAST_FUNC sha1_end(sha1_ctx_t * + hash_size = 8; + if (ctx->process_block == sha1_process_block64 + #if ENABLE_SHA1_HWACCEL ++# if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + || ctx->process_block == sha1_process_block64_shaNI ++# endif + #endif + ) { + hash_size = 5; diff --git a/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch b/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch index c0f234ee421ecb..595eaa6afe3883 100644 --- a/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch +++ b/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch @@ -1,6 +1,6 @@ --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c -@@ -722,6 +722,7 @@ static int bcast_or_ucast(struct dhcp_pa +@@ -711,6 +711,7 @@ static int bcast_or_ucast(struct dhcp_pa static NOINLINE int send_discover(uint32_t requested) { struct dhcp_packet packet; @@ -8,7 +8,7 @@ /* Fill in: op, htype, hlen, cookie, chaddr fields, * xid field, message type option: -@@ -736,6 +737,7 @@ static NOINLINE int send_discover(uint32 +@@ -725,6 +726,7 @@ static NOINLINE int send_discover(uint32 */ add_client_options(&packet); diff --git a/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch b/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch index a4bda992c42b22..94745cf8d93340 100644 --- a/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch +++ b/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch @@ -1,6 +1,6 @@ --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c -@@ -1384,6 +1384,12 @@ int udhcpc_main(int argc UNUSED_PARAM, c +@@ -1374,6 +1374,12 @@ int udhcpc_main(int argc UNUSED_PARAM, c struct pollfd pfds[2]; struct dhcp_packet packet; diff --git a/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch b/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch index f4c0a8092257e9..9a3ddb52fd67a6 100644 --- a/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch +++ b/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch @@ -1,6 +1,6 @@ --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c -@@ -683,7 +683,7 @@ static int do_add_or_delete(char **argv, +@@ -953,7 +953,7 @@ static int do_add_or_delete(char **argv, } xrtnl_open(&rth); ll_init_map(&rth); diff --git a/package/utils/busybox/patches/530-nslookup-ensure-unique-transaction-IDs-for-the-DNS-queries.patch b/package/utils/busybox/patches/530-nslookup-ensure-unique-transaction-IDs-for-the-DNS-queries.patch index caa5ee78f35ad3..bbd7b277fe9b09 100644 --- a/package/utils/busybox/patches/530-nslookup-ensure-unique-transaction-IDs-for-the-DNS-queries.patch +++ b/package/utils/busybox/patches/530-nslookup-ensure-unique-transaction-IDs-for-the-DNS-queries.patch @@ -29,7 +29,7 @@ Forwarded: http://lists.busybox.net/pipermail/busybox/2022-October/089911.html --- --- a/networking/nslookup.c +++ b/networking/nslookup.c -@@ -978,6 +978,10 @@ int nslookup_main(int argc UNUSED_PARAM, +@@ -1370,6 +1370,10 @@ int nslookup_main(int argc UNUSED_PARAM, } } diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index 6ee0cf2a1d56b9..a68dea81507242 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -8,17 +8,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ucode -PKG_RELEASE:=3 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git -PKG_SOURCE_DATE:=2024-07-22 -PKG_SOURCE_VERSION:=b610860dd4a0591ff586dd71a50f556a0ddafced -PKG_MIRROR_HASH:=a5ec51dd989174422d3b19b022ff4f863d57eb559c9f08d54c0d10651f598357 +PKG_SOURCE_DATE:=2024-12-02 +PKG_SOURCE_VERSION:=b0b5d93846a1fb9d1d94992d5fdf508ef345e87d +PKG_MIRROR_HASH:=b43fcb38a85469552d5fb641ade271c346634a52c3628155d3215953ff2c25e1 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC PKG_ABI_VERSION:=20230711 +PKG_BUILD_DEPENDS:=libmd HOST_BUILD_DEPENDS:=libjson-c/host include $(INCLUDE_DIR)/package.mk @@ -51,7 +52,8 @@ CMAKE_HOST_OPTIONS += \ -DUCI_SUPPORT=OFF \ -DULOOP_SUPPORT=OFF \ -DDEBUG_SUPPORT=ON \ - -DLOG_SUPPORT=OFF + -DLOG_SUPPORT=OFF \ + -DDIGEST_SUPPORT=OFF define Package/ucode/default @@ -178,6 +180,10 @@ $(eval $(call UcodeModule, \ uloop, ULOOP_SUPPORT, +libubox, \ The uloop module allows ucode scripts to interact with OpenWrt uloop event loop implementation.)) +$(eval $(call UcodeModule, \ + digest, DIGEST_SUPPORT, , \ + The digest module allows ucode scripts to use libmd digests.)) + $(eval $(call BuildPackage,libucode)) $(eval $(call BuildPackage,ucode)) diff --git a/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch b/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch deleted file mode 100644 index 22e05f7c620518..00000000000000 --- a/package/utils/ucode/patches/100-nl80211_vif_radio_mask.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/include/linux/nl80211.h -+++ b/include/linux/nl80211.h -@@ -2868,6 +2868,9 @@ enum nl80211_commands { - * nested item, it contains attributes defined in - * &enum nl80211_if_combination_attrs. - * -+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32). -+ * A value of 0 means all radios. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3416,6 +3419,8 @@ enum nl80211_attrs { - NL80211_ATTR_WIPHY_RADIOS, - NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS, - -+ NL80211_ATTR_VIF_RADIO_MASK, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, ---- a/lib/nl80211.c -+++ b/lib/nl80211.c -@@ -829,7 +829,7 @@ static const uc_nl_nested_spec_t nl80211 - - static const uc_nl_nested_spec_t nl80211_msg = { - .headsize = 0, -- .nattrs = 128, -+ .nattrs = 129, - .attrs = { - { NL80211_ATTR_4ADDR, "4addr", DT_U8, 0, NULL }, - { NL80211_ATTR_AIRTIME_WEIGHT, "airtime_weight", DT_U16, 0, NULL }, -@@ -959,6 +959,7 @@ static const uc_nl_nested_spec_t nl80211 - { NL80211_ATTR_MAX_AP_ASSOC_STA, "max_ap_assoc", DT_U16, 0, NULL }, - { NL80211_ATTR_SURVEY_INFO, "survey_info", DT_NESTED, 0, &nl80211_survey_info_nla }, - { NL80211_ATTR_WIPHY_RADIOS, "radios", DT_NESTED, DF_MULTIPLE|DF_AUTOIDX, &nl80211_wiphy_radio_nla }, -+ { NL80211_ATTR_VIF_RADIO_MASK, "vif_radio_mask", DT_U32, 0, NULL }, - } - }; - diff --git a/scripts/json_overview_image_info.py b/scripts/json_overview_image_info.py index 0d2cf7f1ef5134..96921c27430a86 100755 --- a/scripts/json_overview_image_info.py +++ b/scripts/json_overview_image_info.py @@ -47,7 +47,13 @@ def get_initial_output(image_info): if output: - default_packages, output["arch_packages"] = run( + ( + default_packages, + output["arch_packages"], + linux_version, + linux_release, + linux_vermagic, + ) = run( [ "make", "--no-print-directory", @@ -55,6 +61,9 @@ def get_initial_output(image_info): "target/linux/", "val.DEFAULT_PACKAGES", "val.ARCH_PACKAGES", + "val.LINUX_VERSION", + "val.LINUX_RELEASE", + "val.LINUX_VERMAGIC", "V=s", ], stdout=PIPE, @@ -64,7 +73,11 @@ def get_initial_output(image_info): ).stdout.splitlines() output["default_packages"] = sorted(default_packages.split()) - + output["linux_kernel"] = { + "version": linux_version, + "release": linux_release, + "vermagic": linux_vermagic, + } output_path.write_text(json.dumps(output, sort_keys=True, separators=(",", ":"))) else: print("JSON info file script could not find any JSON files for target") diff --git a/scripts/metadata.pm b/scripts/metadata.pm index ecfe42c0bc926c..dec9e62dff1295 100644 --- a/scripts/metadata.pm +++ b/scripts/metadata.pm @@ -136,6 +136,7 @@ sub parse_target_metadata($) { /^Linux-Kernel-Arch:\s*(.+)\s*$/ and $target->{karch} = $1; /^Default-Subtarget:\s*(.+)\s*$/ and $target->{def_subtarget} = $1; /^Default-Packages:\s*(.+)\s*$/ and $target->{packages} = [ split(/\s+/, $1) ]; + /^Target-Default-Profile:\s*(.+)\s*$/ and $target->{default_profile} = $1; /^Target-Profile:\s*(.+)\s*$/ and do { $profile = { id => $1, diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl index 0c17e2e3273df6..ce96d1e7d538a1 100755 --- a/scripts/target-metadata.pl +++ b/scripts/target-metadata.pl @@ -179,7 +179,7 @@ () print <{profiles}->[0]; + foreach my $p (@{$target->{profiles}}) { + last unless $target->{default_profile}; + my $name = $p->{id}; + $name =~ s/^DEVICE_//; + next unless $name eq $target->{default_profile}; + $profile = $p; + last; + } $profile or next; print <{conf}_$profile->{id} if TARGET_$target->{conf} && !BUILDBOT diff --git a/target/linux/ath79/dts/ar9331_alfa-network_ap121f.dtsi b/target/linux/ath79/dts/ar9331_alfa-network_ap121f.dtsi index ca0b4131acffdf..2d9e17bcf8ac46 100644 --- a/target/linux/ath79/dts/ar9331_alfa-network_ap121f.dtsi +++ b/target/linux/ath79/dts/ar9331_alfa-network_ap121f.dtsi @@ -116,10 +116,6 @@ macaddr_art_0: macaddr@0 { reg = <0x0 0x6>; }; - - macaddr_art_1002: macaddr@1002 { - reg = <0x1002 0x6>; - }; }; }; @@ -143,6 +139,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_art_1002>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/ar9344_alfa-network_n5q.dts b/target/linux/ath79/dts/ar9344_alfa-network_n5q.dts index 9f4c95c3d46ef2..8dfcd2ee3a107f 100644 --- a/target/linux/ath79/dts/ar9344_alfa-network_n5q.dts +++ b/target/linux/ath79/dts/ar9344_alfa-network_n5q.dts @@ -154,10 +154,6 @@ macaddr_art_6: macaddr@6 { reg = <0x6 0x6>; }; - - macaddr_art_1002: macaddr@1002 { - reg = <0x1002 0x6>; - }; }; }; @@ -173,6 +169,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_art_1002>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/ar9344_embeddedwireless_balin.dts b/target/linux/ath79/dts/ar9344_embeddedwireless_balin.dts index a5d684cf99520f..e2bfd5484242b7 100644 --- a/target/linux/ath79/dts/ar9344_embeddedwireless_balin.dts +++ b/target/linux/ath79/dts/ar9344_embeddedwireless_balin.dts @@ -122,8 +122,8 @@ &wmac { status = "okay"; - nvmem-cells = <&macaddr_art_1002 0>, <&calibration_art_1000>; - nvmem-cell-names = "mac-address", "calibration"; + nvmem-cells = <&calibration_art_1000>; + nvmem-cell-names = "calibration"; }; &pcie { diff --git a/target/linux/ath79/dts/qca9531_alcatel_hh40v.dts b/target/linux/ath79/dts/qca9531_alcatel_hh40v.dts index c68b49d6c26d43..16ba785a235289 100644 --- a/target/linux/ath79/dts/qca9531_alcatel_hh40v.dts +++ b/target/linux/ath79/dts/qca9531_alcatel_hh40v.dts @@ -140,10 +140,6 @@ macaddr_art_6: macaddr@6 { reg = <0x6 0x6>; }; - - macaddr_art_1002: macaddr@1002 { - reg = <0x1002 0x6>; - }; }; }; }; @@ -174,6 +170,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_art_1002>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9531_alfa-network_r36a.dtsi b/target/linux/ath79/dts/qca9531_alfa-network_r36a.dtsi index 13a2e28619c87e..48f2eff86a2f32 100644 --- a/target/linux/ath79/dts/qca9531_alfa-network_r36a.dtsi +++ b/target/linux/ath79/dts/qca9531_alfa-network_r36a.dtsi @@ -124,6 +124,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_art_1002 0>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15.dts b/target/linux/ath79/dts/qca9557_sophos_ap15.dts index 773b423cde1bbc..d6c0a65ebecb37 100644 --- a/target/linux/ath79/dts/qca9557_sophos_ap15.dts +++ b/target/linux/ath79/dts/qca9557_sophos_ap15.dts @@ -1,148 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca955x.dtsi" - -#include -#include -#include +#include "qca9557_sophos_ap15.dtsi" / { compatible = "sophos,ap15", "qca,qca9557"; model = "Sophos AP15"; - - aliases { - led-boot = &led_status_green; - led-failsafe = &led_status_yellow; - led-running = &led_status_green; - led-upgrade = &led_status_yellow; - label-mac-device = ð0; - }; - - chosen { - bootargs = "console=ttyS0,115200n8"; - }; - - leds { - compatible = "gpio-leds"; - - led_status_green: status_green { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio 13 GPIO_ACTIVE_LOW>; - default-state = "on"; - }; - - led_status_yellow: status_yellow { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio 14 GPIO_ACTIVE_LOW>; - }; - }; -}; - -&spi { - status = "okay"; - - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x000000 0x040000>; - read-only; - }; - - partition@40000 { - label = "u-boot-env"; - reg = <0x040000 0x010000>; - }; - - partition@50000 { - label = "art"; - reg = <0x050000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - cal_art_1000: calibration@1000 { - reg = <0x1000 0x440>; - }; - }; - }; - - partition@60000 { - label = "config"; - reg = <0x060000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - macaddr_config_201a: macaddr@201a { - reg = <0x201a 0x6>; - }; - }; - }; - - partition@70000 { - compatible = "denx,uimage"; - label = "firmware"; - reg = <0x070000 0xf90000>; - }; - }; - }; -}; - -&mdio0 { - status = "okay"; - - phy-mask = <0x10>; - - phy4: ethernet-phy@4 { - reg = <4>; - eee-broken-100tx; - eee-broken-1000t; - }; -}; - -ð0 { - status = "okay"; - - pll-data = <0xa6000000 0xa0000101 0xa0001313>; - - nvmem-cells = <&macaddr_config_201a>; - nvmem-cell-names = "mac-address"; - - phy-mode = "rgmii-id"; - phy-handle = <&phy4>; - - gmac_config: gmac-config { - device = <&gmac>; - - rgmii-enabled = <1>; - - rxdv-delay = <3>; - rxd-delay = <3>; - txen-delay = <3>; - txd-delay = <3>; - }; -}; - -&wmac { - status = "okay"; - - nvmem-cells = <&cal_art_1000>; - nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15.dtsi b/target/linux/ath79/dts/qca9557_sophos_ap15.dtsi new file mode 100644 index 00000000000000..c5ac5e3d9d5179 --- /dev/null +++ b/target/linux/ath79/dts/qca9557_sophos_ap15.dtsi @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca955x.dtsi" + +#include +#include +#include + +/ { + aliases { + led-boot = &led_status_green; + led-failsafe = &led_status_yellow; + led-running = &led_status_green; + led-upgrade = &led_status_yellow; + label-mac-device = ð0; + }; + + chosen { + bootargs = "console=ttyS0,115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led_status_green: status_green { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 13 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led_status_yellow: status_yellow { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + }; + + partition@50000 { + label = "art"; + reg = <0x050000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + cal_art_1000: calibration@1000 { + reg = <0x1000 0x440>; + }; + }; + }; + + partition@60000 { + label = "config"; + reg = <0x060000 0x010000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_config_201a: macaddr@201a { + reg = <0x201a 0x6>; + }; + }; + }; + + partition@70000 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x070000 0xf90000>; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy-mask = <0x10>; + + phy4: ethernet-phy@4 { + reg = <4>; + eee-broken-100tx; + eee-broken-1000t; + }; +}; + +ð0 { + status = "okay"; + + pll-data = <0xa6000000 0xa0000101 0xa0001313>; + + nvmem-cells = <&macaddr_config_201a>; + nvmem-cell-names = "mac-address"; + + phy-mode = "rgmii-id"; + phy-handle = <&phy4>; + + gmac_config: gmac-config { + device = <&gmac>; + + rgmii-enabled = <1>; + + rxdv-delay = <3>; + rxd-delay = <3>; + txen-delay = <3>; + txd-delay = <3>; + }; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; +}; diff --git a/target/linux/ath79/dts/qca9557_sophos_ap15c.dts b/target/linux/ath79/dts/qca9557_sophos_ap15c.dts index 68d02e97a54a14..464bdd5a45e1ad 100644 --- a/target/linux/ath79/dts/qca9557_sophos_ap15c.dts +++ b/target/linux/ath79/dts/qca9557_sophos_ap15c.dts @@ -1,27 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later OR MIT -#include "qca955x.dtsi" - -#include -#include -#include +#include "qca9557_sophos_ap15.dtsi" / { compatible = "sophos,ap15c", "qca,qca9557"; model = "Sophos AP15C"; - aliases { - led-boot = &led_status_green; - led-failsafe = &led_status_yellow; - led-running = &led_status_green; - led-upgrade = &led_status_yellow; - label-mac-device = ð0; - }; - - chosen { - bootargs = "console=ttyS0,115200n8"; - }; - keys { compatible = "gpio-keys"; @@ -32,128 +16,4 @@ debounce-interval = <60>; }; }; - - leds { - compatible = "gpio-leds"; - - led_status_green: status_green { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio 13 GPIO_ACTIVE_LOW>; - default-state = "on"; - }; - - led_status_yellow: status_yellow { - function = LED_FUNCTION_STATUS; - color = ; - gpios = <&gpio 14 GPIO_ACTIVE_LOW>; - }; - }; -}; - -&spi { - status = "okay"; - - flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <25000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "u-boot"; - reg = <0x000000 0x040000>; - read-only; - }; - - partition@40000 { - label = "u-boot-env"; - reg = <0x040000 0x010000>; - }; - - partition@50000 { - label = "art"; - reg = <0x050000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - cal_art_1000: calibration@1000 { - reg = <0x1000 0x440>; - }; - }; - }; - - partition@60000 { - label = "config"; - reg = <0x060000 0x010000>; - read-only; - - nvmem-layout { - compatible = "fixed-layout"; - #address-cells = <1>; - #size-cells = <1>; - - macaddr_config_201a: macaddr@201a { - reg = <0x201a 0x6>; - }; - }; - }; - - partition@70000 { - compatible = "denx,uimage"; - label = "firmware"; - reg = <0x070000 0xf90000>; - }; - }; - }; -}; - -&mdio0 { - status = "okay"; - - phy-mask = <0x10>; - - phy4: ethernet-phy@4 { - reg = <4>; - eee-broken-100tx; - eee-broken-1000t; - }; -}; - -ð0 { - status = "okay"; - - pll-data = <0xa6000000 0xa0000101 0xa0001313>; - - nvmem-cells = <&macaddr_config_201a>; - nvmem-cell-names = "mac-address"; - - phy-mode = "rgmii-id"; - phy-handle = <&phy4>; - - gmac_config: gmac-config { - device = <&gmac>; - - rgmii-enabled = <1>; - - rxdv-delay = <3>; - rxd-delay = <3>; - txen-delay = <3>; - txd-delay = <3>; - }; -}; - -&wmac { - status = "okay"; - - nvmem-cells = <&cal_art_1000>; - nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi index 53bb5b0141254b..43e34c6029182d 100644 --- a/target/linux/ath79/dts/qca955x_elecom_wab.dtsi +++ b/target/linux/ath79/dts/qca955x_elecom_wab.dtsi @@ -8,7 +8,6 @@ / { aliases { - label-mac-device = ð0; led-boot = &led_status; led-failsafe = &led_status; led-upgrade = &led_status; @@ -108,9 +107,6 @@ phy-mode = "rgmii-rxid"; pll-data = <0xae000000 0x80000101 0x80001313>; - nvmem-cells = <&macaddr_uboot_ethaddr 0>; - nvmem-cell-names = "mac-address"; - gmac-config { device = <&gmac>; @@ -148,8 +144,8 @@ wifi@0,0 { compatible = "qcom,ath10k"; reg = <0x0000 0 0 0 0>; - nvmem-cells = <&cal_art_5000>, <&macaddr_uboot_ethaddr 1>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_5000>; + nvmem-cell-names = "calibration"; }; }; @@ -173,14 +169,9 @@ }; partition@40000 { - compatible = "u-boot,env"; label = "u-boot-env"; reg = <0x40000 0x10000>; read-only; - - macaddr_uboot_ethaddr: ethaddr { - #nvmem-cell-cells = <1>; - }; }; partition@50000 { @@ -261,6 +252,6 @@ &wmac { status = "okay"; - nvmem-cells = <&cal_art_1000>, <&macaddr_uboot_ethaddr 0>; - nvmem-cell-names = "calibration", "mac-address"; + nvmem-cells = <&cal_art_1000>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9563_glinet_gl-x1200.dtsi b/target/linux/ath79/dts/qca9563_glinet_gl-x1200.dtsi index ab1f8902b10a0f..5f1ef04f0bb428 100644 --- a/target/linux/ath79/dts/qca9563_glinet_gl-x1200.dtsi +++ b/target/linux/ath79/dts/qca9563_glinet_gl-x1200.dtsi @@ -111,14 +111,6 @@ macaddr_art_0: macaddr@0 { reg = <0x0 0x6>; }; - - macaddr_art_1002: macaddr@1002 { - reg = <0x1002 0x6>; - }; - - macaddr_art_5006: macaddr@5006 { - reg = <0x5006 0x6>; - }; }; }; @@ -182,8 +174,8 @@ compatible = "qcom,ath10k"; reg = <0 0 0 0 0>; - nvmem-cells = <&macaddr_art_5006>, <&calibration_ath10k>; - nvmem-cell-names = "mac-address", "pre-calibration"; + nvmem-cells = <&calibration_ath10k>; + nvmem-cell-names = "pre-calibration"; }; }; @@ -206,6 +198,6 @@ &wmac { status = "okay"; - nvmem-cells = <&macaddr_art_1002>, <&calibration_ath9k>; - nvmem-cell-names = "mac-address", "calibration"; + nvmem-cells = <&calibration_ath9k>; + nvmem-cell-names = "calibration"; }; diff --git a/target/linux/ath79/dts/qca9563_kuwfi_n650.dts b/target/linux/ath79/dts/qca9563_kuwfi_n650.dts new file mode 100644 index 00000000000000..03801dabb3ed6c --- /dev/null +++ b/target/linux/ath79/dts/qca9563_kuwfi_n650.dts @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "qca956x.dtsi" + +#include +#include +#include +#include + +/ { + model = "KuWFi N650"; + compatible = "kuwfi,n650", "qca,qca9563"; + + aliases { + label-mac-device = ð0; + led-boot = &led_green; + led-running = &led_green; + led-failsafe = &led_blue; + led-upgrade = &led_blue; + }; + + virtual_flash { + compatible = "mtd-concat"; + devices = <&fwconcat0 &fwconcat1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x0>; + label = "firmware"; + compatible = "openwrt,uimage", "denx,uimage"; + openwrt,ih-magic = ; + }; + }; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "Reset button"; + linux,code = ; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + debounce-interval = <60>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led_blue: blue { + function = LED_FUNCTION_DEBUG; + color = ; + gpios = <&gpio 7 GPIO_ACTIVE_LOW>; + }; + + led_green: green { + function = LED_FUNCTION_POWER; + color = ; + gpios = <&gpio 8 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x030000>; + read-only; + }; + + partition@30000 { + label = "u-boot-env"; + reg = <0x030000 0x010000>; + }; + + fwconcat0: partition@40000 { + label = "fwconcat0"; + reg = <0x040000 0xd40000>; + }; + + partition@d80000 { + label = "loader"; + reg = <0xd80000 0x10000>; + }; + + fwconcat1: partition@d90000 { + label = "fwconcat1"; + reg = <0xd90000 0x160000>; + }; + + partition@ef0000 { + label = "log"; + reg = <0xef0000 0x0f0000>; + read-only; + }; + + partition@fe0000 { + label = "nvram"; + reg = <0xfe0000 0x010000>; + read-only; + }; + + partition@ff0000 { + label = "art"; + reg = <0xff0000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + macaddr_art_0: macaddr@0 { + compatible = "mac-base"; + reg = <0x0 0x6>; + #nvmem-cell-cells = <1>; + }; + + precal_art_5000: pre-calibration@5000 { + reg = <0x5000 0x2f20>; + }; + }; + }; + }; + }; +}; + +&mdio0 { + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + phy-mode = "sgmii"; + reset-gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + qca,mib-poll-interval = <500>; + + qca,ar8327-initvals = < + 0x04 0x00080080 /* PORT0 PAD MODE CTRL */ + 0x7c 0x0000007e /* PORT0_STATUS */ + >; + }; +}; + +ð0 { + status = "okay"; + + nvmem-cells = <&macaddr_art_0 0>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy0>; + phy-mode = "sgmii"; +}; + +&pcie { + status = "okay"; + + wifi@0,0 { + compatible = "pci168c,0056"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&precal_art_5000>, <&macaddr_art_0 1>; + nvmem-cell-names = "pre-calibration", "mac-address"; + }; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index 2bd97442d956dc..e987d754f0ac42 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -401,6 +401,10 @@ ath79_setup_interfaces() ucidef_add_switch "switch0" \ "0@eth0" "1:lan:2" "4:lan:1" ;; + kuwfi,n650) + ucidef_add_switch "switch0" \ + "0@eth0" "2:lan:1" "3:lan:2" + ;; letv,lba-047-ch) ucidef_set_interface_wan "eth0" ucidef_add_switch "switch0" \ @@ -717,6 +721,9 @@ ath79_setup_macs() lan_mac=$(mtd_get_mac_ascii devdata "lanmac") wan_mac=$(mtd_get_mac_ascii devdata "wanmac") ;; + elecom,wab-i1750-ps|\ + elecom,wab-s1167-ps|\ + elecom,wab-s600-ps|\ engenius,ecb1200|\ engenius,ecb1750) lan_mac=$(mtd_get_mac_ascii u-boot-env ethaddr) diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac index 6676e4d509873f..5155d240a825ac 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/ieee80211/10_fix_wifi_mac @@ -42,6 +42,16 @@ case "$board" in [ "$PHYNBR" -eq 1 ] && \ mtd_get_mac_ascii bdcfg "wlanmac" > /sys${DEVPATH}/macaddress ;; + elecom,wab-i1750-ps|\ + elecom,wab-s1167-ps|\ + elecom,wab-s600-ps) + # set the 5G MAC address (= ethaddr + 1) + [ "$PHYNBR" -eq 0 ] && \ + macaddr_add "$(mtd_get_mac_ascii u-boot-env ethaddr)" 1 > /sys${DEVPATH}/macaddress + # set the 2.4G MAC address (= ethaddr) + [ "$PHYNBR" -eq 1 ] && \ + mtd_get_mac_ascii u-boot-env "ethaddr" > /sys${DEVPATH}/macaddress + ;; engenius,ecb1200|\ engenius,ecb1750) [ "$PHYNBR" -eq 0 ] && \ diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 0173f5cb16180d..92f9bc6cddef5a 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -1963,6 +1963,25 @@ define Device/kuwfi_c910 endef TARGET_DEVICES += kuwfi_c910 +define Device/kuwfi_n650 + $(Device/loader-okli-uimage) + SOC := qca9563 + DEVICE_VENDOR := KuWFi + DEVICE_MODEL := N650 + DEVICE_PACKAGES += kmod-ath10k-ct ath10k-firmware-qca9888-ct + FACTORY_SIZE := 13632k + LOADER_FLASH_OFFS := 0x40000 + KERNEL := kernel-bin | append-dtb | lzma | uImage lzma -M 0x4f4b4c49 + IMAGE_SIZE := 15040k + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$$$(BLOCKSIZE) | \ + append-rootfs | pad-rootfs | check-size | pad-to 13568k | \ + append-loader-okli-uimage $(1) | pad-to 64k | check-size $$$$(FACTORY_SIZE) + ARTIFACTS := loader.bin + ARTIFACT/loader.bin := append-loader-okli-uimage $(1) | pad-to 64k +endef +TARGET_DEVICES += kuwfi_n650 + define Device/letv_lba-047-ch $(Device/loader-okli-uimage) SOC := qca9531 diff --git a/target/linux/generic/backport-6.6/860-v6.7-leds-add-ktd202x-driver.patch b/target/linux/generic/backport-6.6/860-v6.7-leds-add-ktd202x-driver.patch new file mode 100644 index 00000000000000..fb767c5d9998be --- /dev/null +++ b/target/linux/generic/backport-6.6/860-v6.7-leds-add-ktd202x-driver.patch @@ -0,0 +1,682 @@ +From 0ebdb7210943eb345992bea9892adbd15a206193 Mon Sep 17 00:00:00 2001 +From: André Apitzsch +Date: Mon, 2 Oct 2023 18:48:28 +0200 +Subject: leds: Add ktd202x driver +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit adds support for Kinetic KTD2026/7 RGB/White LED driver. + +Signed-off-by: André Apitzsch +Link: https://lore.kernel.org/r/20231002-ktd202x-v6-2-26be8eefeb88@apitzsch.eu +Signed-off-by: Lee Jones +--- + drivers/leds/rgb/Kconfig | 13 + + drivers/leds/rgb/Makefile | 1 + + drivers/leds/rgb/leds-ktd202x.c | 625 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 639 insertions(+) + create mode 100644 drivers/leds/rgb/leds-ktd202x.c + +(limited to 'drivers/leds/rgb') + +--- a/drivers/leds/rgb/Kconfig ++++ b/drivers/leds/rgb/Kconfig +@@ -14,6 +14,19 @@ config LEDS_GROUP_MULTICOLOR + To compile this driver as a module, choose M here: the module + will be called leds-group-multicolor. + ++config LEDS_KTD202X ++ tristate "LED support for KTD202x Chips" ++ depends on I2C ++ depends on OF ++ select REGMAP_I2C ++ help ++ This option enables support for the Kinetic KTD2026/KTD2027 ++ RGB/White LED driver found in different BQ mobile phones. ++ It is a 3 or 4 channel LED driver programmed via an I2C interface. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called leds-ktd202x. ++ + config LEDS_PWM_MULTICOLOR + tristate "PWM driven multi-color LED Support" + depends on PWM +--- a/drivers/leds/rgb/Makefile ++++ b/drivers/leds/rgb/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + + obj-$(CONFIG_LEDS_GROUP_MULTICOLOR) += leds-group-multicolor.o ++obj-$(CONFIG_LEDS_KTD202X) += leds-ktd202x.o + obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o + obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o + obj-$(CONFIG_LEDS_MT6370_RGB) += leds-mt6370-rgb.o +--- /dev/null ++++ b/drivers/leds/rgb/leds-ktd202x.c +@@ -0,0 +1,625 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Kinetic KTD2026/7 RGB/White LED driver with I2C interface ++ * ++ * Copyright 2023 André Apitzsch ++ * ++ * Datasheet: https://www.kinet-ic.com/uploads/KTD2026-7-04h.pdf ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define KTD2026_NUM_LEDS 3 ++#define KTD2027_NUM_LEDS 4 ++#define KTD202X_MAX_LEDS 4 ++ ++/* Register bank */ ++#define KTD202X_REG_RESET_CONTROL 0x00 ++#define KTD202X_REG_FLASH_PERIOD 0x01 ++#define KTD202X_REG_PWM1_TIMER 0x02 ++#define KTD202X_REG_PWM2_TIMER 0x03 ++#define KTD202X_REG_CHANNEL_CTRL 0x04 ++#define KTD202X_REG_TRISE_FALL 0x05 ++#define KTD202X_REG_LED_IOUT(x) (0x06 + (x)) ++ ++/* Register 0 */ ++#define KTD202X_TIMER_SLOT_CONTROL_TSLOT1 0x00 ++#define KTD202X_TIMER_SLOT_CONTROL_TSLOT2 0x01 ++#define KTD202X_TIMER_SLOT_CONTROL_TSLOT3 0x02 ++#define KTD202X_TIMER_SLOT_CONTROL_TSLOT4 0x03 ++#define KTD202X_RSTR_RESET 0x07 ++ ++#define KTD202X_ENABLE_CTRL_WAKE 0x00 /* SCL High & SDA High */ ++#define KTD202X_ENABLE_CTRL_SLEEP 0x08 /* SCL High & SDA Toggling */ ++ ++#define KTD202X_TRISE_FALL_SCALE_NORMAL 0x00 ++#define KTD202X_TRISE_FALL_SCALE_SLOW_X2 0x20 ++#define KTD202X_TRISE_FALL_SCALE_SLOW_X4 0x40 ++#define KTD202X_TRISE_FALL_SCALE_FAST_X8 0x60 ++ ++/* Register 1 */ ++#define KTD202X_FLASH_PERIOD_256_MS_LOG_RAMP 0x00 ++ ++/* Register 2-3 */ ++#define KTD202X_FLASH_ON_TIME_0_4_PERCENT 0x01 ++ ++/* Register 4 */ ++#define KTD202X_CHANNEL_CTRL_MASK(x) (BIT(2 * (x)) | BIT(2 * (x) + 1)) ++#define KTD202X_CHANNEL_CTRL_OFF 0x00 ++#define KTD202X_CHANNEL_CTRL_ON(x) BIT(2 * (x)) ++#define KTD202X_CHANNEL_CTRL_PWM1(x) BIT(2 * (x) + 1) ++#define KTD202X_CHANNEL_CTRL_PWM2(x) (BIT(2 * (x)) | BIT(2 * (x) + 1)) ++ ++/* Register 5 */ ++#define KTD202X_RAMP_TIMES_2_MS 0x00 ++ ++/* Register 6-9 */ ++#define KTD202X_LED_CURRENT_10_mA 0x4f ++ ++#define KTD202X_FLASH_PERIOD_MIN_MS 256 ++#define KTD202X_FLASH_PERIOD_STEP_MS 128 ++#define KTD202X_FLASH_PERIOD_MAX_STEPS 126 ++#define KTD202X_FLASH_ON_MAX 256 ++ ++#define KTD202X_MAX_BRIGHTNESS 192 ++ ++static const struct reg_default ktd202x_reg_defaults[] = { ++ { KTD202X_REG_RESET_CONTROL, KTD202X_TIMER_SLOT_CONTROL_TSLOT1 | ++ KTD202X_ENABLE_CTRL_WAKE | KTD202X_TRISE_FALL_SCALE_NORMAL }, ++ { KTD202X_REG_FLASH_PERIOD, KTD202X_FLASH_PERIOD_256_MS_LOG_RAMP }, ++ { KTD202X_REG_PWM1_TIMER, KTD202X_FLASH_ON_TIME_0_4_PERCENT }, ++ { KTD202X_REG_PWM2_TIMER, KTD202X_FLASH_ON_TIME_0_4_PERCENT }, ++ { KTD202X_REG_CHANNEL_CTRL, KTD202X_CHANNEL_CTRL_OFF }, ++ { KTD202X_REG_TRISE_FALL, KTD202X_RAMP_TIMES_2_MS }, ++ { KTD202X_REG_LED_IOUT(0), KTD202X_LED_CURRENT_10_mA }, ++ { KTD202X_REG_LED_IOUT(1), KTD202X_LED_CURRENT_10_mA }, ++ { KTD202X_REG_LED_IOUT(2), KTD202X_LED_CURRENT_10_mA }, ++ { KTD202X_REG_LED_IOUT(3), KTD202X_LED_CURRENT_10_mA }, ++}; ++ ++struct ktd202x_led { ++ struct ktd202x *chip; ++ union { ++ struct led_classdev cdev; ++ struct led_classdev_mc mcdev; ++ }; ++ u32 index; ++}; ++ ++struct ktd202x { ++ struct mutex mutex; ++ struct regulator_bulk_data regulators[2]; ++ struct device *dev; ++ struct regmap *regmap; ++ bool enabled; ++ int num_leds; ++ struct ktd202x_led leds[] __counted_by(num_leds); ++}; ++ ++static int ktd202x_chip_disable(struct ktd202x *chip) ++{ ++ int ret; ++ ++ if (!chip->enabled) ++ return 0; ++ ++ regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_SLEEP); ++ ++ ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); ++ if (ret) { ++ dev_err(chip->dev, "Failed to disable regulators: %d\n", ret); ++ return ret; ++ } ++ ++ chip->enabled = false; ++ return 0; ++} ++ ++static int ktd202x_chip_enable(struct ktd202x *chip) ++{ ++ int ret; ++ ++ if (chip->enabled) ++ return 0; ++ ++ ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators); ++ if (ret) { ++ dev_err(chip->dev, "Failed to enable regulators: %d\n", ret); ++ return ret; ++ } ++ chip->enabled = true; ++ ++ ret = regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_ENABLE_CTRL_WAKE); ++ ++ if (ret) { ++ dev_err(chip->dev, "Failed to enable the chip: %d\n", ret); ++ ktd202x_chip_disable(chip); ++ } ++ ++ return ret; ++} ++ ++static bool ktd202x_chip_in_use(struct ktd202x *chip) ++{ ++ int i; ++ ++ for (i = 0; i < chip->num_leds; i++) { ++ if (chip->leds[i].cdev.brightness) ++ return true; ++ } ++ ++ return false; ++} ++ ++static int ktd202x_brightness_set(struct ktd202x_led *led, ++ struct mc_subled *subleds, ++ unsigned int num_channels) ++{ ++ bool mode_blink = false; ++ int channel; ++ int state; ++ int ret; ++ int i; ++ ++ if (ktd202x_chip_in_use(led->chip)) { ++ ret = ktd202x_chip_enable(led->chip); ++ if (ret) ++ return ret; ++ } ++ ++ ret = regmap_read(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, &state); ++ if (ret) ++ return ret; ++ ++ /* ++ * In multicolor case, assume blink mode if PWM is set for at least one ++ * channel because another channel cannot be in state ON at the same time ++ */ ++ for (i = 0; i < num_channels; i++) { ++ int channel_state; ++ ++ channel = subleds[i].channel; ++ channel_state = (state >> 2 * channel) & KTD202X_CHANNEL_CTRL_MASK(0); ++ if (channel_state == KTD202X_CHANNEL_CTRL_OFF) ++ continue; ++ mode_blink = channel_state == KTD202X_CHANNEL_CTRL_PWM1(0); ++ break; ++ } ++ ++ for (i = 0; i < num_channels; i++) { ++ enum led_brightness brightness; ++ int mode; ++ ++ brightness = subleds[i].brightness; ++ channel = subleds[i].channel; ++ ++ if (brightness) { ++ /* Register expects brightness between 0 and MAX_BRIGHTNESS - 1 */ ++ ret = regmap_write(led->chip->regmap, KTD202X_REG_LED_IOUT(channel), ++ brightness - 1); ++ if (ret) ++ return ret; ++ ++ if (mode_blink) ++ mode = KTD202X_CHANNEL_CTRL_PWM1(channel); ++ else ++ mode = KTD202X_CHANNEL_CTRL_ON(channel); ++ } else { ++ mode = KTD202X_CHANNEL_CTRL_OFF; ++ } ++ ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, ++ KTD202X_CHANNEL_CTRL_MASK(channel), mode); ++ if (ret) ++ return ret; ++ } ++ ++ if (!ktd202x_chip_in_use(led->chip)) ++ return ktd202x_chip_disable(led->chip); ++ ++ return 0; ++} ++ ++static int ktd202x_brightness_single_set(struct led_classdev *cdev, ++ enum led_brightness value) ++{ ++ struct ktd202x_led *led = container_of(cdev, struct ktd202x_led, cdev); ++ struct mc_subled info; ++ int ret; ++ ++ cdev->brightness = value; ++ ++ mutex_lock(&led->chip->mutex); ++ ++ info.brightness = value; ++ info.channel = led->index; ++ ret = ktd202x_brightness_set(led, &info, 1); ++ ++ mutex_unlock(&led->chip->mutex); ++ ++ return ret; ++} ++ ++static int ktd202x_brightness_mc_set(struct led_classdev *cdev, ++ enum led_brightness value) ++{ ++ struct led_classdev_mc *mc = lcdev_to_mccdev(cdev); ++ struct ktd202x_led *led = container_of(mc, struct ktd202x_led, mcdev); ++ int ret; ++ ++ cdev->brightness = value; ++ ++ mutex_lock(&led->chip->mutex); ++ ++ led_mc_calc_color_components(mc, value); ++ ret = ktd202x_brightness_set(led, mc->subled_info, mc->num_colors); ++ ++ mutex_unlock(&led->chip->mutex); ++ ++ return ret; ++} ++ ++static int ktd202x_blink_set(struct ktd202x_led *led, unsigned long *delay_on, ++ unsigned long *delay_off, struct mc_subled *subleds, ++ unsigned int num_channels) ++{ ++ unsigned long delay_total_ms; ++ int ret, num_steps, on; ++ u8 ctrl_mask = 0; ++ u8 ctrl_pwm1 = 0; ++ u8 ctrl_on = 0; ++ int i; ++ ++ mutex_lock(&led->chip->mutex); ++ ++ for (i = 0; i < num_channels; i++) { ++ int channel = subleds[i].channel; ++ ++ ctrl_mask |= KTD202X_CHANNEL_CTRL_MASK(channel); ++ ctrl_on |= KTD202X_CHANNEL_CTRL_ON(channel); ++ ctrl_pwm1 |= KTD202X_CHANNEL_CTRL_PWM1(channel); ++ } ++ ++ /* Never off - brightness is already set, disable blinking */ ++ if (!*delay_off) { ++ ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, ++ ctrl_mask, ctrl_on); ++ goto out; ++ } ++ ++ /* Convert into values the HW will understand. */ ++ ++ /* Integer representation of time of flash period */ ++ num_steps = (*delay_on + *delay_off - KTD202X_FLASH_PERIOD_MIN_MS) / ++ KTD202X_FLASH_PERIOD_STEP_MS; ++ num_steps = clamp(num_steps, 0, KTD202X_FLASH_PERIOD_MAX_STEPS); ++ ++ /* Integer representation of percentage of LED ON time */ ++ on = (*delay_on * KTD202X_FLASH_ON_MAX) / (*delay_on + *delay_off); ++ ++ /* Actually used delay_{on,off} values */ ++ delay_total_ms = num_steps * KTD202X_FLASH_PERIOD_STEP_MS + KTD202X_FLASH_PERIOD_MIN_MS; ++ *delay_on = (delay_total_ms * on) / KTD202X_FLASH_ON_MAX; ++ *delay_off = delay_total_ms - *delay_on; ++ ++ /* Set timings */ ++ ret = regmap_write(led->chip->regmap, KTD202X_REG_FLASH_PERIOD, num_steps); ++ if (ret) ++ goto out; ++ ++ ret = regmap_write(led->chip->regmap, KTD202X_REG_PWM1_TIMER, on); ++ if (ret) ++ goto out; ++ ++ ret = regmap_update_bits(led->chip->regmap, KTD202X_REG_CHANNEL_CTRL, ++ ctrl_mask, ctrl_pwm1); ++out: ++ mutex_unlock(&led->chip->mutex); ++ return ret; ++} ++ ++static int ktd202x_blink_single_set(struct led_classdev *cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct ktd202x_led *led = container_of(cdev, struct ktd202x_led, cdev); ++ struct mc_subled info; ++ int ret; ++ ++ if (!cdev->brightness) { ++ ret = ktd202x_brightness_single_set(cdev, KTD202X_MAX_BRIGHTNESS); ++ if (ret) ++ return ret; ++ } ++ ++ /* If no blink specified, default to 1 Hz. */ ++ if (!*delay_off && !*delay_on) { ++ *delay_off = 500; ++ *delay_on = 500; ++ } ++ ++ /* Never on - just set to off */ ++ if (!*delay_on) ++ return ktd202x_brightness_single_set(cdev, LED_OFF); ++ ++ info.channel = led->index; ++ ++ return ktd202x_blink_set(led, delay_on, delay_off, &info, 1); ++} ++ ++static int ktd202x_blink_mc_set(struct led_classdev *cdev, ++ unsigned long *delay_on, ++ unsigned long *delay_off) ++{ ++ struct led_classdev_mc *mc = lcdev_to_mccdev(cdev); ++ struct ktd202x_led *led = container_of(mc, struct ktd202x_led, mcdev); ++ int ret; ++ ++ if (!cdev->brightness) { ++ ret = ktd202x_brightness_mc_set(cdev, KTD202X_MAX_BRIGHTNESS); ++ if (ret) ++ return ret; ++ } ++ ++ /* If no blink specified, default to 1 Hz. */ ++ if (!*delay_off && !*delay_on) { ++ *delay_off = 500; ++ *delay_on = 500; ++ } ++ ++ /* Never on - just set to off */ ++ if (!*delay_on) ++ return ktd202x_brightness_mc_set(cdev, LED_OFF); ++ ++ return ktd202x_blink_set(led, delay_on, delay_off, mc->subled_info, ++ mc->num_colors); ++} ++ ++static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np, ++ struct ktd202x_led *led, struct led_init_data *init_data) ++{ ++ struct led_classdev *cdev; ++ struct device_node *child; ++ struct mc_subled *info; ++ int num_channels; ++ int i = 0; ++ ++ num_channels = of_get_available_child_count(np); ++ if (!num_channels || num_channels > chip->num_leds) ++ return -EINVAL; ++ ++ info = devm_kcalloc(chip->dev, num_channels, sizeof(*info), GFP_KERNEL); ++ if (!info) ++ return -ENOMEM; ++ ++ for_each_available_child_of_node(np, child) { ++ u32 mono_color; ++ u32 reg; ++ int ret; ++ ++ ret = of_property_read_u32(child, "reg", ®); ++ if (ret != 0 || reg >= chip->num_leds) { ++ dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child); ++ of_node_put(child); ++ return -EINVAL; ++ } ++ ++ ret = of_property_read_u32(child, "color", &mono_color); ++ if (ret < 0 && ret != -EINVAL) { ++ dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child); ++ of_node_put(child); ++ return ret; ++ } ++ ++ info[i].color_index = mono_color; ++ info[i].channel = reg; ++ info[i].intensity = KTD202X_MAX_BRIGHTNESS; ++ i++; ++ } ++ ++ led->mcdev.subled_info = info; ++ led->mcdev.num_colors = num_channels; ++ ++ cdev = &led->mcdev.led_cdev; ++ cdev->brightness_set_blocking = ktd202x_brightness_mc_set; ++ cdev->blink_set = ktd202x_blink_mc_set; ++ ++ return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data); ++} ++ ++static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np, ++ struct ktd202x_led *led, struct led_init_data *init_data) ++{ ++ struct led_classdev *cdev; ++ u32 reg; ++ int ret; ++ ++ ret = of_property_read_u32(np, "reg", ®); ++ if (ret != 0 || reg >= chip->num_leds) { ++ dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np); ++ return -EINVAL; ++ } ++ led->index = reg; ++ ++ cdev = &led->cdev; ++ cdev->brightness_set_blocking = ktd202x_brightness_single_set; ++ cdev->blink_set = ktd202x_blink_single_set; ++ ++ return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data); ++} ++ ++static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index) ++{ ++ struct ktd202x_led *led = &chip->leds[index]; ++ struct led_init_data init_data = {}; ++ struct led_classdev *cdev; ++ u32 color; ++ int ret; ++ ++ /* Color property is optional in single color case */ ++ ret = of_property_read_u32(np, "color", &color); ++ if (ret < 0 && ret != -EINVAL) { ++ dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np); ++ return ret; ++ } ++ ++ led->chip = chip; ++ init_data.fwnode = of_fwnode_handle(np); ++ ++ if (color == LED_COLOR_ID_RGB) { ++ cdev = &led->mcdev.led_cdev; ++ ret = ktd202x_setup_led_rgb(chip, np, led, &init_data); ++ } else { ++ cdev = &led->cdev; ++ ret = ktd202x_setup_led_single(chip, np, led, &init_data); ++ } ++ ++ if (ret) { ++ dev_err(chip->dev, "unable to register %s\n", cdev->name); ++ return ret; ++ } ++ ++ cdev->max_brightness = KTD202X_MAX_BRIGHTNESS; ++ ++ return 0; ++} ++ ++static int ktd202x_probe_dt(struct ktd202x *chip) ++{ ++ struct device_node *np = dev_of_node(chip->dev), *child; ++ int count; ++ int i = 0; ++ ++ chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev); ++ ++ count = of_get_available_child_count(np); ++ if (!count || count > chip->num_leds) ++ return -EINVAL; ++ ++ regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); ++ ++ /* Allow the device to execute the complete reset */ ++ usleep_range(200, 300); ++ ++ for_each_available_child_of_node(np, child) { ++ int ret = ktd202x_add_led(chip, child, i); ++ ++ if (ret) { ++ of_node_put(child); ++ return ret; ++ } ++ i++; ++ } ++ ++ return 0; ++} ++ ++static const struct regmap_config ktd202x_regmap_config = { ++ .reg_bits = 8, ++ .val_bits = 8, ++ .max_register = 0x09, ++ .cache_type = REGCACHE_FLAT, ++ .reg_defaults = ktd202x_reg_defaults, ++ .num_reg_defaults = ARRAY_SIZE(ktd202x_reg_defaults), ++}; ++ ++static int ktd202x_probe(struct i2c_client *client) ++{ ++ struct device *dev = &client->dev; ++ struct ktd202x *chip; ++ int count; ++ int ret; ++ ++ count = device_get_child_node_count(dev); ++ if (!count || count > KTD202X_MAX_LEDS) ++ return dev_err_probe(dev, -EINVAL, "Incorrect number of leds (%d)", count); ++ ++ chip = devm_kzalloc(dev, struct_size(chip, leds, count), GFP_KERNEL); ++ if (!chip) ++ return -ENOMEM; ++ ++ chip->dev = dev; ++ i2c_set_clientdata(client, chip); ++ ++ chip->regmap = devm_regmap_init_i2c(client, &ktd202x_regmap_config); ++ if (IS_ERR(chip->regmap)) { ++ ret = dev_err_probe(dev, PTR_ERR(chip->regmap), ++ "Failed to allocate register map.\n"); ++ return ret; ++ } ++ ++ chip->regulators[0].supply = "vin"; ++ chip->regulators[1].supply = "vio"; ++ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators); ++ if (ret < 0) { ++ dev_err_probe(dev, ret, "Failed to request regulators.\n"); ++ return ret; ++ } ++ ++ ret = regulator_bulk_enable(ARRAY_SIZE(chip->regulators), chip->regulators); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to enable regulators.\n"); ++ return ret; ++ } ++ ++ ret = ktd202x_probe_dt(chip); ++ if (ret < 0) { ++ regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); ++ return ret; ++ } ++ ++ ret = regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); ++ if (ret) { ++ dev_err_probe(dev, ret, "Failed to disable regulators.\n"); ++ return ret; ++ } ++ ++ mutex_init(&chip->mutex); ++ ++ return 0; ++} ++ ++static void ktd202x_remove(struct i2c_client *client) ++{ ++ struct ktd202x *chip = i2c_get_clientdata(client); ++ ++ ktd202x_chip_disable(chip); ++ ++ mutex_destroy(&chip->mutex); ++} ++ ++static void ktd202x_shutdown(struct i2c_client *client) ++{ ++ struct ktd202x *chip = i2c_get_clientdata(client); ++ ++ /* Reset registers to make sure all LEDs are off before shutdown */ ++ regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); ++} ++ ++static const struct of_device_id ktd202x_match_table[] = { ++ { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS }, ++ { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, ktd202x_match_table); ++ ++static struct i2c_driver ktd202x_driver = { ++ .driver = { ++ .name = "leds-ktd202x", ++ .of_match_table = ktd202x_match_table, ++ }, ++ .probe = ktd202x_probe, ++ .remove = ktd202x_remove, ++ .shutdown = ktd202x_shutdown, ++}; ++module_i2c_driver(ktd202x_driver); ++ ++MODULE_AUTHOR("André Apitzsch "); ++MODULE_DESCRIPTION("Kinetic KTD2026/7 LED driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/generic/backport-6.6/861-v6.10-leds-rgb-leds-ktd202x-get-device-properties-through-fwnode.patch b/target/linux/generic/backport-6.6/861-v6.10-leds-rgb-leds-ktd202x-get-device-properties-through-fwnode.patch new file mode 100644 index 00000000000000..92b20c3b9c2ea2 --- /dev/null +++ b/target/linux/generic/backport-6.6/861-v6.10-leds-rgb-leds-ktd202x-get-device-properties-through-fwnode.patch @@ -0,0 +1,221 @@ +From f14aa5ea415b8add245e976bfab96a12986c6843 Mon Sep 17 00:00:00 2001 +From: Kate Hsuan +Date: Fri, 31 May 2024 13:41:19 +0200 +Subject: leds: rgb: leds-ktd202x: Get device properties through fwnode to + support ACPI +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This LED controller is installed on a Xiaomi pad2 and it is an x86 +platform. The original driver is based on the device tree and can't be +used for this ACPI based system. This patch migrated the driver to use +fwnode to access the properties. Moreover, the fwnode API supports the +device tree so this work won't affect the original implementations. + +Signed-off-by: Kate Hsuan +Tested-by: André Apitzsch # on BQ Aquaris M5 +Reviewed-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20240531114124.45346-2-hdegoede@redhat.com +Signed-off-by: Lee Jones +--- + drivers/leds/rgb/Kconfig | 1 - + drivers/leds/rgb/leds-ktd202x.c | 64 ++++++++++++++++++++++------------------- + 2 files changed, 34 insertions(+), 31 deletions(-) + +(limited to 'drivers/leds/rgb') + +--- a/drivers/leds/rgb/Kconfig ++++ b/drivers/leds/rgb/Kconfig +@@ -17,7 +17,6 @@ config LEDS_GROUP_MULTICOLOR + config LEDS_KTD202X + tristate "LED support for KTD202x Chips" + depends on I2C +- depends on OF + select REGMAP_I2C + help + This option enables support for the Kinetic KTD2026/KTD2027 +--- a/drivers/leds/rgb/leds-ktd202x.c ++++ b/drivers/leds/rgb/leds-ktd202x.c +@@ -99,7 +99,7 @@ struct ktd202x { + struct device *dev; + struct regmap *regmap; + bool enabled; +- int num_leds; ++ unsigned long num_leds; + struct ktd202x_led leds[] __counted_by(num_leds); + }; + +@@ -381,16 +381,19 @@ static int ktd202x_blink_mc_set(struct l + mc->num_colors); + } + +-static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct device_node *np, ++static int ktd202x_setup_led_rgb(struct ktd202x *chip, struct fwnode_handle *fwnode, + struct ktd202x_led *led, struct led_init_data *init_data) + { ++ struct fwnode_handle *child; + struct led_classdev *cdev; +- struct device_node *child; + struct mc_subled *info; + int num_channels; + int i = 0; + +- num_channels = of_get_available_child_count(np); ++ num_channels = 0; ++ fwnode_for_each_available_child_node(fwnode, child) ++ num_channels++; ++ + if (!num_channels || num_channels > chip->num_leds) + return -EINVAL; + +@@ -398,22 +401,22 @@ static int ktd202x_setup_led_rgb(struct + if (!info) + return -ENOMEM; + +- for_each_available_child_of_node(np, child) { ++ fwnode_for_each_available_child_node(fwnode, child) { + u32 mono_color; + u32 reg; + int ret; + +- ret = of_property_read_u32(child, "reg", ®); ++ ret = fwnode_property_read_u32(child, "reg", ®); + if (ret != 0 || reg >= chip->num_leds) { +- dev_err(chip->dev, "invalid 'reg' of %pOFn\n", child); +- of_node_put(child); +- return -EINVAL; ++ dev_err(chip->dev, "invalid 'reg' of %pfw\n", child); ++ fwnode_handle_put(child); ++ return ret; + } + +- ret = of_property_read_u32(child, "color", &mono_color); ++ ret = fwnode_property_read_u32(child, "color", &mono_color); + if (ret < 0 && ret != -EINVAL) { +- dev_err(chip->dev, "failed to parse 'color' of %pOF\n", child); +- of_node_put(child); ++ dev_err(chip->dev, "failed to parse 'color' of %pfw\n", child); ++ fwnode_handle_put(child); + return ret; + } + +@@ -433,16 +436,16 @@ static int ktd202x_setup_led_rgb(struct + return devm_led_classdev_multicolor_register_ext(chip->dev, &led->mcdev, init_data); + } + +-static int ktd202x_setup_led_single(struct ktd202x *chip, struct device_node *np, ++static int ktd202x_setup_led_single(struct ktd202x *chip, struct fwnode_handle *fwnode, + struct ktd202x_led *led, struct led_init_data *init_data) + { + struct led_classdev *cdev; + u32 reg; + int ret; + +- ret = of_property_read_u32(np, "reg", ®); ++ ret = fwnode_property_read_u32(fwnode, "reg", ®); + if (ret != 0 || reg >= chip->num_leds) { +- dev_err(chip->dev, "invalid 'reg' of %pOFn\n", np); ++ dev_err(chip->dev, "invalid 'reg' of %pfw\n", fwnode); + return -EINVAL; + } + led->index = reg; +@@ -454,7 +457,7 @@ static int ktd202x_setup_led_single(stru + return devm_led_classdev_register_ext(chip->dev, &led->cdev, init_data); + } + +-static int ktd202x_add_led(struct ktd202x *chip, struct device_node *np, unsigned int index) ++static int ktd202x_add_led(struct ktd202x *chip, struct fwnode_handle *fwnode, unsigned int index) + { + struct ktd202x_led *led = &chip->leds[index]; + struct led_init_data init_data = {}; +@@ -463,21 +466,21 @@ static int ktd202x_add_led(struct ktd202 + int ret; + + /* Color property is optional in single color case */ +- ret = of_property_read_u32(np, "color", &color); ++ ret = fwnode_property_read_u32(fwnode, "color", &color); + if (ret < 0 && ret != -EINVAL) { +- dev_err(chip->dev, "failed to parse 'color' of %pOF\n", np); ++ dev_err(chip->dev, "failed to parse 'color' of %pfw\n", fwnode); + return ret; + } + + led->chip = chip; +- init_data.fwnode = of_fwnode_handle(np); ++ init_data.fwnode = fwnode; + + if (color == LED_COLOR_ID_RGB) { + cdev = &led->mcdev.led_cdev; +- ret = ktd202x_setup_led_rgb(chip, np, led, &init_data); ++ ret = ktd202x_setup_led_rgb(chip, fwnode, led, &init_data); + } else { + cdev = &led->cdev; +- ret = ktd202x_setup_led_single(chip, np, led, &init_data); ++ ret = ktd202x_setup_led_single(chip, fwnode, led, &init_data); + } + + if (ret) { +@@ -490,15 +493,14 @@ static int ktd202x_add_led(struct ktd202 + return 0; + } + +-static int ktd202x_probe_dt(struct ktd202x *chip) ++static int ktd202x_probe_fw(struct ktd202x *chip) + { +- struct device_node *np = dev_of_node(chip->dev), *child; ++ struct fwnode_handle *child; ++ struct device *dev = chip->dev; + int count; + int i = 0; + +- chip->num_leds = (int)(unsigned long)of_device_get_match_data(chip->dev); +- +- count = of_get_available_child_count(np); ++ count = device_get_child_node_count(dev); + if (!count || count > chip->num_leds) + return -EINVAL; + +@@ -507,11 +509,11 @@ static int ktd202x_probe_dt(struct ktd20 + /* Allow the device to execute the complete reset */ + usleep_range(200, 300); + +- for_each_available_child_of_node(np, child) { ++ device_for_each_child_node(dev, child) { + int ret = ktd202x_add_led(chip, child, i); + + if (ret) { +- of_node_put(child); ++ fwnode_handle_put(child); + return ret; + } + i++; +@@ -554,6 +556,8 @@ static int ktd202x_probe(struct i2c_clie + return ret; + } + ++ chip->num_leds = (unsigned long)i2c_get_match_data(client); ++ + chip->regulators[0].supply = "vin"; + chip->regulators[1].supply = "vio"; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(chip->regulators), chip->regulators); +@@ -568,7 +572,7 @@ static int ktd202x_probe(struct i2c_clie + return ret; + } + +- ret = ktd202x_probe_dt(chip); ++ ret = ktd202x_probe_fw(chip); + if (ret < 0) { + regulator_bulk_disable(ARRAY_SIZE(chip->regulators), chip->regulators); + return ret; +@@ -605,7 +609,7 @@ static void ktd202x_shutdown(struct i2c_ + static const struct of_device_id ktd202x_match_table[] = { + { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS }, + { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS }, +- {}, ++ {} + }; + MODULE_DEVICE_TABLE(of, ktd202x_match_table); + diff --git a/target/linux/generic/backport-6.6/862-v6.10-leds-rgb-leds-ktd202x-i2c-id-tables-for-ktd2026-and-2027.patch b/target/linux/generic/backport-6.6/862-v6.10-leds-rgb-leds-ktd202x-i2c-id-tables-for-ktd2026-and-2027.patch new file mode 100644 index 00000000000000..223ccd8f50c764 --- /dev/null +++ b/target/linux/generic/backport-6.6/862-v6.10-leds-rgb-leds-ktd202x-i2c-id-tables-for-ktd2026-and-2027.patch @@ -0,0 +1,49 @@ +From 75bd07aef47e1a984229e6ec702e8b9aee0226e4 Mon Sep 17 00:00:00 2001 +From: Kate Hsuan +Date: Fri, 31 May 2024 13:41:20 +0200 +Subject: leds: rgb: leds-ktd202x: I2C ID tables for KTD2026 and 2027 + +Add an i2c_device_id id_table to match manually instantiated +(non device-tree / ACPI instantiated) KTD202x controllers as +found on some x86 boards. + +This table shows the maximum support LED channel for KTD2026 +(three LEDs) and KTD-2027 (4 LEDs). + +Link: https://www.kinet-ic.com/uploads/KTD2026-7-04h.pdf +Signed-off-by: Kate Hsuan +Reviewed-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20240531114124.45346-3-hdegoede@redhat.com +Signed-off-by: Lee Jones +--- + drivers/leds/rgb/leds-ktd202x.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +(limited to 'drivers/leds/rgb') + +--- a/drivers/leds/rgb/leds-ktd202x.c ++++ b/drivers/leds/rgb/leds-ktd202x.c +@@ -606,6 +606,13 @@ static void ktd202x_shutdown(struct i2c_ + regmap_write(chip->regmap, KTD202X_REG_RESET_CONTROL, KTD202X_RSTR_RESET); + } + ++static const struct i2c_device_id ktd202x_id[] = { ++ {"ktd2026", KTD2026_NUM_LEDS}, ++ {"ktd2027", KTD2027_NUM_LEDS}, ++ {} ++}; ++MODULE_DEVICE_TABLE(i2c, ktd202x_id); ++ + static const struct of_device_id ktd202x_match_table[] = { + { .compatible = "kinetic,ktd2026", .data = (void *)KTD2026_NUM_LEDS }, + { .compatible = "kinetic,ktd2027", .data = (void *)KTD2027_NUM_LEDS }, +@@ -621,6 +628,7 @@ static struct i2c_driver ktd202x_driver + .probe = ktd202x_probe, + .remove = ktd202x_remove, + .shutdown = ktd202x_shutdown, ++ .id_table = ktd202x_id, + }; + module_i2c_driver(ktd202x_driver); + diff --git a/target/linux/generic/backport-6.6/863-v6.10-leds-rgb-leds-ktd202x-initialize-mutex-earlier.patch b/target/linux/generic/backport-6.6/863-v6.10-leds-rgb-leds-ktd202x-initialize-mutex-earlier.patch new file mode 100644 index 00000000000000..533b0f0e170749 --- /dev/null +++ b/target/linux/generic/backport-6.6/863-v6.10-leds-rgb-leds-ktd202x-initialize-mutex-earlier.patch @@ -0,0 +1,62 @@ +From e1b08c6f5b92d408a9fcc1030a340caeb9852250 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 31 May 2024 13:41:21 +0200 +Subject: leds: rgb: leds-ktd202x: Initialize mutex earlier + +The mutex must be initialized before the LED class device is registered +otherwise there is a race where it may get used before it is initialized: + + DEBUG_LOCKS_WARN_ON(lock->magic != lock) + WARNING: CPU: 2 PID: 2045 at kernel/locking/mutex.c:587 __mutex_lock + ... + RIP: 0010:__mutex_lock+0x7db/0xc10 + ... + set_brightness_delayed_set_brightness.part.0+0x17/0x60 + set_brightness_delayed+0xf1/0x100 + process_one_work+0x222/0x5a0 + +Move the mutex_init() call earlier to avoid this race condition and +switch to devm_mutex_init() to avoid the need to add error-exit +cleanup to probe() if probe() fails later on. + +Signed-off-by: Hans de Goede +Reviewed-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20240531114124.45346-4-hdegoede@redhat.com +Signed-off-by: Lee Jones +--- + drivers/leds/rgb/leds-ktd202x.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +(limited to 'drivers/leds/rgb') + +--- a/drivers/leds/rgb/leds-ktd202x.c ++++ b/drivers/leds/rgb/leds-ktd202x.c +@@ -556,6 +556,10 @@ static int ktd202x_probe(struct i2c_clie + return ret; + } + ++ ret = devm_mutex_init(dev, &chip->mutex); ++ if (ret) ++ return ret; ++ + chip->num_leds = (unsigned long)i2c_get_match_data(client); + + chip->regulators[0].supply = "vin"; +@@ -584,8 +588,6 @@ static int ktd202x_probe(struct i2c_clie + return ret; + } + +- mutex_init(&chip->mutex); +- + return 0; + } + +@@ -594,8 +596,6 @@ static void ktd202x_remove(struct i2c_cl + struct ktd202x *chip = i2c_get_clientdata(client); + + ktd202x_chip_disable(chip); +- +- mutex_destroy(&chip->mutex); + } + + static void ktd202x_shutdown(struct i2c_client *client) diff --git a/target/linux/mediatek/dts/mt7981b-keenetic-kn-3911.dts b/target/linux/mediatek/dts/mt7981b-keenetic-kn-3911.dts new file mode 100644 index 00000000000000..8a9bf0f1a9bf45 --- /dev/null +++ b/target/linux/mediatek/dts/mt7981b-keenetic-kn-3911.dts @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT + +/dts-v1/; + +#include "mt7981.dtsi" + +/ { + model = "Keenetic KN-3911"; + compatible = "keenetic,kn-3911", "mediatek,mt7981"; + + aliases { + label-mac-device = &gmac0; + led-boot = &status_led; + led-failsafe = &status_led; + led-running = &status_led; + led-upgrade = &status_led; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-fn { + label = "fn"; + linux,code = ; + gpios = <&pio 0 GPIO_ACTIVE_LOW>; + }; + + button-reset { + label = "reset"; + linux,code = ; + gpios = <&pio 24 GPIO_ACTIVE_LOW>; + }; + + button-wps { + label = "wps"; + linux,code = ; + gpios = <&pio 29 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-leds { + compatible = "gpio-leds"; + + status_led: led-0 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 11 GPIO_ACTIVE_HIGH>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_WPS; + gpios = <&pio 12 GPIO_ACTIVE_LOW>; + }; + }; + + virtual_flash { + compatible = "mtd-concat"; + devices = <&firmware1 &firmware2>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "kernel"; + reg = <0x0 0x600000>; + }; + + partition@400000 { + label = "ubi"; + reg = <0x600000 0x0>; + }; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +ð { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins>; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + phy-handle = <&phy10>; + label = "lan"; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_factory_4 0>; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "2500base-x"; + phy-handle = <&phy11>; + label = "wan"; + + nvmem-cell-names = "mac-address"; + nvmem-cells = <&macaddr_factory_a 0>; + }; +}; + +&mdio_bus { + phy10: ethernet-phy@a { + reg = <0xa>; + interrupt-parent = <&pio>; + interrupts = <38 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&pio 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <20000>; + }; + + phy11: ethernet-phy@b { + reg = <0xb>; + interrupt-parent = <&pio>; + interrupts = <23 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&pio 27 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <20000>; + }; +}; + +&pio { + spi0_flash_pins: spi0-pins { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_flash_pins>; + status = "okay"; + + /* Winbond W25N01GVZEIG (128M) */ + spi_nand@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "spi-nand"; + reg = <0>; + + spi-max-frequency = <52000000>; + spi-tx-buswidth = <4>; + spi-rx-buswidth = <4>; + + spi-cal-enable; + spi-cal-mode = "read-data"; + spi-cal-datalen = <7>; + spi-cal-data = /bits/ 8 <0x53 0x50 0x49 0x4e 0x41 0x4e 0x44>; + spi-cal-addrlen = <5>; + spi-cal-addr = /bits/ 32 <0x0 0x0 0x0 0x0 0x0>; + + mediatek,nmbm; + mediatek,bmt-max-ratio = <1>; + mediatek,bmt-max-reserved-blocks = <64>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* bl2 */ + partition@0 { + label = "preloader"; + reg = <0x0 0x80000>; + read-only; + }; + + /* fip */ + partition@80000 { + label = "u-boot"; + reg = <0x80000 0x200000>; + read-only; + }; + + partition@280000 { + label = "u-config"; + reg = <0x280000 0x80000>; + read-only; + }; + + partition@300000 { + label = "rf-eeprom"; + reg = <0x300000 0x200000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + /* lan mac */ + macaddr_factory_4: macaddr@4 { + compatible = "mac-base"; + reg = <0x4 0x6>; + #nvmem-cell-cells = <1>; + }; + + /* wan mac */ + macaddr_factory_a: macaddr@a { + compatible = "mac-base"; + reg = <0xa 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + + firmware1: partition@500000 { + label = "firmware_1"; + reg = <0x500000 0x3500000>; + }; + + partition@3a00000 { + label = "config_1"; + reg = <0x3a00000 0x80000>; + read-only; + }; + + partition@3a80000 { + label = "dump"; + reg = <0x3a80000 0x80000>; + read-only; + }; + + partition@3c00000 { + label = "u-state"; + reg = <0x3c00000 0x20000>; + read-only; + }; + + partition@3e80000 { + label = "u-config_res"; + reg = <0x3e80000 0x80000>; + read-only; + }; + + partition@3f00000 { + label = "rf-eeprom_res"; + reg = <0x3f00000 0x200000>; + read-only; + }; + + firmware2: partition@4100000 { + label = "firmware_2"; + reg = <0x4140000 0x3500000>; + }; + + partition@7600000 { + label = "config_2"; + reg = <0x7600000 0x80000>; + read-only; + }; + }; + }; +}; + +&wifi { + nvmem-cell-names = "eeprom"; + nvmem-cells = <&eeprom_factory_0>; + status = "okay"; +}; + +&sgmiisys0 { + /delete-node/ mediatek,pnswap; +}; diff --git a/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-common.dtsi b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-common.dtsi new file mode 100644 index 00000000000000..5522c58af21ed4 --- /dev/null +++ b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-common.dtsi @@ -0,0 +1,252 @@ +// SPDX-License-Identifier: (GL-2.0 OR MIT) + +/dts-v1/; +#include +#include +#include + +#include "mt7986b.dtsi" + +/ { + aliases: aliases { + led-boot = &led_status_green; + led-failsafe = &led_status_green; + led-running = &led_status_green; + led-upgrade = &led_status_green; + + serial0 = &uart0; + }; + + chosen: chosen { + stdout-path = "serial0:115200n8"; + }; + + memory { + reg = <0 0x40000000 0 0x20000000>; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + gpios = <&pio 10 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <2>; + gpios = <&pio 7 GPIO_ACTIVE_LOW>; + }; + + led-1 { + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + gpios = <&pio 9 GPIO_ACTIVE_LOW>; + }; + + led-2 { + color = ; + function = LED_FUNCTION_LAN; + function-enumerator = <0>; + gpios = <&pio 12 GPIO_ACTIVE_LOW>; + }; + + led-3 { + color = ; + function = LED_FUNCTION_WAN; + gpios = <&pio 13 GPIO_ACTIVE_LOW>; + }; + + led-4 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 16 GPIO_ACTIVE_HIGH>; + panic-indicator; + }; + + led_status_green: led-5 { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&pio 17 GPIO_ACTIVE_HIGH>; + }; + }; +}; + +&crypto { + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-handle = <&phy6>; + phy-mode = "2500base-x"; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + }; +}; + +&mdio { + #address-cells = <1>; + #size-cells = <0>; + + reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; + reset-delay-us = <1500000>; + reset-post-delay-us = <1000000>; + + /* WAN/LAN 2.5Gbps phy + MaxLinear GPY211C0VC (SLNW8) */ + phy6: phy@6 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <6>; + }; + + switch: switch@1f { + compatible = "mediatek,mt7531"; + reg = <31>; + reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; + }; +}; + +&switch { + ports { + #address-cells = <1>; + #size-cells = <0>; + + /* WAN/LAN 1Gbps port */ + port@0 { + reg = <0>; + label = "lan0"; + }; + + /* LAN1 port */ + port@1 { + reg = <1>; + label = "lan1"; + }; + + /* LAN2 port */ + port@2 { + reg = <2>; + label = "lan2"; + }; + + port@6 { + reg = <6>; + ethernet = <&gmac0>; + phy-mode = "2500base-x"; + + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + }; +}; + +&pio { + spi_flash_pins: spi-flash-pins-33-to-38 { + mux { + function = "spi"; + groups = "spi0", "spi0_wp_hold"; + }; + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = <8>; + mediatek,pull-up-adv = <0>; /* bias-disable */ + }; + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = <8>; + mediatek,pull-down-adv = <0>; /* bias-disable */ + }; + }; + + wf_2g_5g_pins: wf_2g_5g-pins { + mux { + function = "wifi"; + groups = "wf_2g", "wf_5g"; + }; + conf { + pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", + "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", + "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", + "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", + "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", + "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", + "WF1_TOP_CLK", "WF1_TOP_DATA"; + drive-strength = <4>; + }; + }; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + + spi_nand_flash: flash@0 { + compatible = "spi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + + spi-max-frequency = <20000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + + partitions: partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&wifi { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&wf_2g_5g_pins>; + + ieee80211-freq-limit = <2400000 2500000>, <5170000 5835000>; +}; diff --git a/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-ubi.dts b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-ubi.dts new file mode 100644 index 00000000000000..cfa195034d6d32 --- /dev/null +++ b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1-ubi.dts @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: (GL-2.0 OR MIT) + +#include "mt7986b-mercusys-mr90x-v1-common.dtsi" + +/ { + compatible = "mercusys,mr90x-v1-ubi", "mediatek,mt7986b"; + model = "MERCUSYS MR90X v1 (UBI)"; +}; + +&aliases { + label-mac-device = &gmac0; +}; + +&chosen { + bootargs-append = " root=/dev/fit0 rootwait"; + rootdisk = <&ubi_fit>; +}; + +&gmac0 { + nvmem-cells = <&macaddr_factory_8000 0>; + nvmem-cell-names = "mac-address"; +}; + +&gmac1 { + nvmem-cells = <&macaddr_factory_8000 1>; + nvmem-cell-names = "mac-address"; +}; + +&partitions { + partition@0 { + label = "boot"; + reg = <0x0 0x200000>; + read-only; + + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bl2"; + reg = <0x0 0x100000>; + read-only; + }; + + partition@100000 { + label = "factory"; + reg = <0x100000 0x100000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x1000>; + }; + + macaddr_factory_8000: macaddr@8000 { + compatible = "mac-base"; + reg = <0x8000 0x6>; + #nvmem-cell-cells = <1>; + }; + }; + }; + }; + + partition@200000 { + compatible = "linux,ubi"; + reg = <0x200000 0x7e00000>; + label = "ubi"; + + volumes { + ubi_fit: ubi-volume-fit { + volname = "fit"; + }; + + ubi_ubootenv: ubi-volume-ubootenv { + volname = "ubootenv"; + }; + + ubi_ubootenv2: ubi-volume-ubootenv2 { + volname = "ubootenv2"; + }; + }; + }; +}; + +&trng { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&ubi_ubootenv { + nvmem-layout { + compatible = "u-boot,env-redundant-bool"; + }; +}; + +&ubi_ubootenv2 { + nvmem-layout { + compatible = "u-boot,env-redundant-bool"; + }; +}; + +&wifi { + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; + + band@0 { + reg = <0>; + nvmem-cells = <&macaddr_factory_8000 0>; + nvmem-cell-names = "mac-address"; + }; + + band@1 { + reg = <1>; + nvmem-cells = <&macaddr_factory_8000 (-1)>; + nvmem-cell-names = "mac-address"; + }; +}; diff --git a/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts index f0a995820ec1a4..16d890a3933531 100644 --- a/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts +++ b/target/linux/mediatek/dts/mt7986b-mercusys-mr90x-v1.dts @@ -1,286 +1,44 @@ // SPDX-License-Identifier: (GL-2.0 OR MIT) -/dts-v1/; -#include -#include -#include - -#include "mt7986b.dtsi" +#include "mt7986b-mercusys-mr90x-v1-common.dtsi" / { compatible = "mercusys,mr90x-v1", "mediatek,mt7986b"; model = "MERCUSYS MR90X v1"; - - aliases { - serial0 = &uart0; - - led-boot = &led_status_green; - led-failsafe = &led_status_green; - led-running = &led_status_green; - led-upgrade = &led_status_green; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - memory { - reg = <0 0x40000000 0 0x20000000>; - }; - - keys { - compatible = "gpio-keys"; - - reset { - label = "reset"; - gpios = <&pio 10 GPIO_ACTIVE_LOW>; - linux,code = ; - }; - }; - - leds { - compatible = "gpio-leds"; - - led-0 { - color = ; - function = LED_FUNCTION_LAN; - function-enumerator = <2>; - gpios = <&pio 7 GPIO_ACTIVE_LOW>; - }; - - led-1 { - color = ; - function = LED_FUNCTION_LAN; - function-enumerator = <1>; - gpios = <&pio 9 GPIO_ACTIVE_LOW>; - }; - - led-2 { - color = ; - function = LED_FUNCTION_LAN; - function-enumerator = <0>; - gpios = <&pio 12 GPIO_ACTIVE_LOW>; - }; - - led-3 { - color = ; - function = LED_FUNCTION_WAN; - gpios = <&pio 13 GPIO_ACTIVE_LOW>; - }; - - led-4 { - color = ; - function = LED_FUNCTION_STATUS; - gpios = <&pio 16 GPIO_ACTIVE_HIGH>; - panic-indicator; - }; - - led_status_green: led-5 { - color = ; - function = LED_FUNCTION_STATUS; - gpios = <&pio 17 GPIO_ACTIVE_HIGH>; - }; - }; }; -&crypto { - status = "okay"; -}; - -ð { - status = "okay"; - - gmac0: mac@0 { - compatible = "mediatek,eth-mac"; - reg = <0>; - phy-mode = "2500base-x"; - - fixed-link { - speed = <2500>; - full-duplex; - pause; - }; +&partitions { + partition@0 { + label = "boot"; + reg = <0x0 0x200000>; + read-only; }; - gmac1: mac@1 { - compatible = "mediatek,eth-mac"; - reg = <1>; - phy-handle = <&phy6>; - phy-mode = "2500base-x"; + partition@200000 { + label = "u-boot-env"; + reg = <0x200000 0x100000>; }; - mdio: mdio-bus { - #address-cells = <1>; - #size-cells = <0>; + partition@300000 { + label = "ubi0"; + reg = <0x300000 0x3200000>; }; -}; - -&mdio { - #address-cells = <1>; - #size-cells = <0>; - - reset-gpios = <&pio 6 GPIO_ACTIVE_LOW>; - reset-delay-us = <1500000>; - reset-post-delay-us = <1000000>; - /* WAN/LAN 2.5Gbps phy - MaxLinear GPY211C0VC (SLNW8) */ - phy6: phy@6 { - compatible = "ethernet-phy-ieee802.3-c45"; - reg = <6>; + partition@3500000 { + label = "ubi1"; + reg = <0x3500000 0x3200000>; + read-only; }; - switch: switch@1f { - compatible = "mediatek,mt7531"; - reg = <31>; - reset-gpios = <&pio 5 GPIO_ACTIVE_HIGH>; + partition@6700000 { + label = "userconfig"; + reg = <0x6700000 0x800000>; + read-only; }; -}; - -&switch { - ports { - #address-cells = <1>; - #size-cells = <0>; - - /* WAN/LAN 1Gbps port */ - port@0 { - reg = <0>; - label = "lan0"; - }; - /* LAN1 port */ - port@1 { - reg = <1>; - label = "lan1"; - }; - - /* LAN2 port */ - port@2 { - reg = <2>; - label = "lan2"; - }; - - port@6 { - reg = <6>; - ethernet = <&gmac0>; - phy-mode = "2500base-x"; - - fixed-link { - speed = <2500>; - full-duplex; - pause; - }; - }; - }; -}; - -&pio { - spi_flash_pins: spi-flash-pins-33-to-38 { - mux { - function = "spi"; - groups = "spi0", "spi0_wp_hold"; - }; - conf-pu { - pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; - drive-strength = <8>; - mediatek,pull-up-adv = <0>; /* bias-disable */ - }; - conf-pd { - pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; - drive-strength = <8>; - mediatek,pull-down-adv = <0>; /* bias-disable */ - }; - }; - - wf_2g_5g_pins: wf_2g_5g-pins { - mux { - function = "wifi"; - groups = "wf_2g", "wf_5g"; - }; - conf { - pins = "WF0_HB1", "WF0_HB2", "WF0_HB3", "WF0_HB4", - "WF0_HB0", "WF0_HB0_B", "WF0_HB5", "WF0_HB6", - "WF0_HB7", "WF0_HB8", "WF0_HB9", "WF0_HB10", - "WF0_TOP_CLK", "WF0_TOP_DATA", "WF1_HB1", - "WF1_HB2", "WF1_HB3", "WF1_HB4", "WF1_HB0", - "WF1_HB5", "WF1_HB6", "WF1_HB7", "WF1_HB8", - "WF1_TOP_CLK", "WF1_TOP_DATA"; - drive-strength = <4>; - }; - }; -}; - -&spi0 { - pinctrl-names = "default"; - pinctrl-0 = <&spi_flash_pins>; - status = "okay"; - - spi_nand_flash: flash@0 { - compatible = "spi-nand"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0>; - - spi-max-frequency = <20000000>; - spi-tx-bus-width = <4>; - spi-rx-bus-width = <4>; - - partitions: partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "boot"; - reg = <0x0 0x200000>; - read-only; - }; - - partition@200000 { - label = "u-boot-env"; - reg = <0x200000 0x100000>; - }; - - partition@300000 { - label = "ubi0"; - reg = <0x300000 0x3200000>; - }; - - partition@3500000 { - label = "ubi1"; - reg = <0x3500000 0x3200000>; - read-only; - }; - - partition@6700000 { - label = "userconfig"; - reg = <0x6700000 0x800000>; - read-only; - }; - - partition@6f00000 { - label = "tp_data"; - reg = <0x6f00000 0x400000>; - read-only; - }; - }; + partition@6f00000 { + label = "tp_data"; + reg = <0x6f00000 0x400000>; + read-only; }; }; - -&trng { - status = "okay"; -}; - -&uart0 { - status = "okay"; -}; - -&watchdog { - status = "okay"; -}; - -&wifi { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&wf_2g_5g_pins>; -}; diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds index 38c4b7525b60e7..64df50eb0a18e8 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/01_leds @@ -49,7 +49,8 @@ glinet,gl-xe3000) ucidef_set_led_netdev "wlan2g" "WLAN2G" "green:wifi2g" "phy0-ap0" ucidef_set_led_netdev "wlan5g" "WLAN5G" "green:wifi5g" "phy1-ap0" ;; -mercusys,mr90x-v1) +mercusys,mr90x-v1|\ +mercusys,mr90x-v1-ubi) ucidef_set_led_netdev "lan-0" "lan-0" "green:lan-0" "lan0" "link tx rx" ucidef_set_led_netdev "lan-1" "lan-1" "green:lan-1" "lan1" "link tx rx" ucidef_set_led_netdev "lan-2" "lan-2" "green:lan-2" "lan2" "link tx rx" diff --git a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network index 1480dbcbc78c23..ba785644022cdf 100644 --- a/target/linux/mediatek/filogic/base-files/etc/board.d/02_network +++ b/target/linux/mediatek/filogic/base-files/etc/board.d/02_network @@ -90,6 +90,13 @@ mediatek_setup_interfaces() dlink,aquila-pro-ai-m30-a1) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4" internet ;; + keenetic,kn-3911|\ + smartrg,sdg-8622|\ + smartrg,sdg-8632|\ + smartrg,sdg-8733a|\ + yuncore,ax835) + ucidef_set_interfaces_lan_wan lan wan + ;; mediatek,mt7986a-rfb) ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 lan4 lan6" "eth1 wan" ;; @@ -99,15 +106,10 @@ mediatek_setup_interfaces() mediatek,mt7988a-rfb) ucidef_set_interfaces_lan_wan "lan0 lan1 lan2 lan3 eth2" eth1 ;; - mercusys,mr90x-v1) + mercusys,mr90x-v1|\ + mercusys,mr90x-v1-ubi) ucidef_set_interfaces_lan_wan "lan0 lan1 lan2" eth1 ;; - smartrg,sdg-8622|\ - smartrg,sdg-8632|\ - smartrg,sdg-8733a|\ - yuncore,ax835) - ucidef_set_interfaces_lan_wan lan wan - ;; tplink,tl-xdr6086|\ wavlink,wl-wn586x3) ucidef_set_interfaces_lan_wan "lan1 lan2" eth1 diff --git a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac index 5e83a167de9704..a3b76712232936 100644 --- a/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac +++ b/target/linux/mediatek/filogic/base-files/etc/hotplug.d/ieee80211/11_fix_wifi_mac @@ -115,6 +115,10 @@ case "$board" in jdcloud,re-cp-03) [ "$PHYNBR" = "1" ] && mmc_get_mac_binary factory 0xa > /sys${DEVPATH}/macaddress ;; + keenetic,kn-3911) + [ "$PHYNBR" = "1" ] && \ + macaddr_setbit_la "$(mtd_get_mac_binary rf-eeprom 0x4)" > /sys${DEVPATH}/macaddress + ;; mercusys,mr90x-v1|\ tplink,re6000xd) addr=$(get_mac_binary "/tmp/tp_data/default-mac" 0) diff --git a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh index 0040ffbb266627..fb48ffc49f090d 100755 --- a/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh +++ b/target/linux/mediatek/filogic/base-files/lib/upgrade/platform.sh @@ -76,6 +76,7 @@ platform_do_upgrade() { jdcloud,re-cp-03|\ mediatek,mt7981-rfb|\ mediatek,mt7988a-rfb|\ + mercusys,mr90x-v1-ubi|\ nokia,ea0326gmp|\ openwrt,one|\ netcore,n60|\ diff --git a/target/linux/mediatek/filogic/config-6.6 b/target/linux/mediatek/filogic/config-6.6 index 2e8fa401507abe..69b5ec6fa1421c 100644 --- a/target/linux/mediatek/filogic/config-6.6 +++ b/target/linux/mediatek/filogic/config-6.6 @@ -6,6 +6,7 @@ CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_ARCH_FORCE_MAX_ORDER=10 +CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_KEEP_MEMBLOCK=y CONFIG_ARCH_MEDIATEK=y CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y @@ -49,7 +50,6 @@ CONFIG_ARM_MEDIATEK_CPUFREQ_HW=m CONFIG_ARM_PMU=y CONFIG_ARM_PMUV3=y CONFIG_ARM_PSCI_FW=y -CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH=y CONFIG_ATA=y CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y CONFIG_BLK_DEV_LOOP=y @@ -105,8 +105,11 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_CPU_MITIGATIONS=y +CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y CONFIG_CPU_THERMAL=y CONFIG_CRC16=y @@ -318,7 +321,7 @@ CONFIG_JBD2=y CONFIG_JUMP_LABEL=y CONFIG_LEDS_PWM=y CONFIG_LEDS_SMARTRG_LED=y -CONFIG_LIBCRC32C=m +CONFIG_LEDS_TRIGGER_PATTERN=y CONFIG_LIBFDT=y CONFIG_LOCK_DEBUGGING_SUPPORT=y CONFIG_LOCK_SPIN_ON_OWNER=y @@ -362,6 +365,7 @@ CONFIG_MTD_UBI_BLOCK=y CONFIG_MTD_UBI_FASTMAP=y CONFIG_MTD_UBI_NVMEM=y CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_VIRT_CONCAT=y # CONFIG_MTK_CMDQ is not set CONFIG_MTK_CPUX_TIMER=y CONFIG_MTK_CQDMA=y @@ -735,6 +739,7 @@ CONFIG_THREAD_INFO_IN_TASK=y CONFIG_TICK_CPU_ACCOUNTING=y CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y +CONFIG_TOOLS_SUPPORT_RELR=y CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y CONFIG_TREE_RCU=y CONFIG_TREE_SRCU=y diff --git a/target/linux/mediatek/filogic/target.mk b/target/linux/mediatek/filogic/target.mk index 0e001cfce9fae7..043906510d5b79 100644 --- a/target/linux/mediatek/filogic/target.mk +++ b/target/linux/mediatek/filogic/target.mk @@ -4,6 +4,7 @@ BOARDNAME:=Filogic 8x0 (MT798x) CPU_TYPE:=cortex-a53 DEFAULT_PACKAGES += fitblk kmod-thermal kmod-phy-aquantia kmod-crypto-hw-safexcel wpad-basic-mbedtls uboot-envtools KERNELNAME:=Image dtbs +DEFAULT_PROFILE:=openwrt_one define Target/Description Build firmware images for MediaTek Filogic ARM based boards. diff --git a/target/linux/mediatek/image/filogic.mk b/target/linux/mediatek/image/filogic.mk index 672790f1a77698..5498922f6edf6b 100644 --- a/target/linux/mediatek/image/filogic.mk +++ b/target/linux/mediatek/image/filogic.mk @@ -887,6 +887,26 @@ define Device/jdcloud_re-cp-03 endef TARGET_DEVICES += jdcloud_re-cp-03 +define Device/keenetic_kn-3911 + DEVICE_VENDOR := Keenetic + DEVICE_MODEL := KN-3911 + DEVICE_DTS := mt7981b-keenetic-kn-3911 + DEVICE_DTS_DIR := ../dts + DEVICE_PACKAGES := kmod-mt7915e kmod-mt7981-firmware mt7981-wo-firmware kmod-phy-airoha-en8811h + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_SIZE := 6144k + IMAGE_SIZE := 108544k + KERNEL := kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb | \ + append-squashfs4-fakeroot + IMAGES += factory.bin + IMAGE/factory.bin := append-kernel | pad-to $$(KERNEL_SIZE) | \ + append-ubi | check-size | zyimage -d 0x803911 -v "KN-3911" + IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata +endef +TARGET_DEVICES += keenetic_kn-3911 + define Device/mediatek_mt7981-rfb DEVICE_VENDOR := MediaTek DEVICE_MODEL := MT7981 rfb @@ -1059,6 +1079,34 @@ define Device/mercusys_mr90x-v1 endef TARGET_DEVICES += mercusys_mr90x-v1 +define Device/mercusys_mr90x-v1-ubi + DEVICE_VENDOR := MERCUSYS + DEVICE_MODEL := MR90X v1 (UBI) + DEVICE_DTS := mt7986b-mercusys-mr90x-v1-ubi + DEVICE_DTS_DIR := ../dts + DEVICE_DTC_FLAGS := --pad 4096 + DEVICE_DTS_LOADADDR := 0x43f00000 + DEVICE_PACKAGES := kmod-mt7915e kmod-mt7986-firmware mt7986-wo-firmware + UBINIZE_OPTS := -E 5 + BLOCKSIZE := 128k + PAGESIZE := 2048 + KERNEL_IN_UBI := 1 + UBOOTENV_IN_UBI := 1 + IMAGES := sysupgrade.itb + KERNEL_INITRAMFS_SUFFIX := -recovery.itb + KERNEL := kernel-bin | gzip + KERNEL_INITRAMFS := kernel-bin | lzma | \ + fit lzma $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb with-initrd | \ + pad-to 64k + IMAGE/sysupgrade.itb := append-kernel | \ + fit gzip $$(KDIR)/image-$$(firstword $$(DEVICE_DTS)).dtb external-with-rootfs | \ + append-metadata + ARTIFACTS := bl31-uboot.fip preloader.bin + ARTIFACT/bl31-uboot.fip := mt7986-bl31-uboot mercusys_mr90x-v1 + ARTIFACT/preloader.bin := mt7986-bl2 spim-nand-ubi-ddr3 +endef +TARGET_DEVICES += mercusys_mr90x-v1-ubi + define Device/netcore_n60 DEVICE_VENDOR := Netcore DEVICE_MODEL := N60 diff --git a/target/linux/mediatek/patches-6.6/999-3001-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch b/target/linux/mediatek/patches-6.6/999-3001-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch new file mode 100644 index 00000000000000..e60da66e15483d --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3001-mtk-wed-add-dma-mask-limitation-and-GFP_DMA32-for-bo.patch @@ -0,0 +1,40 @@ +From d8ad903337b79bc32ae138bf9ef04f31613e4bf2 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Mon, 21 Oct 2024 12:37:18 +0800 +Subject: [PATCH] mtk: wed: add dma mask limitation and GFP_DMA32 for board >= + 4GB dram + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -670,7 +670,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_d + void *buf; + int s; + +- page = __dev_alloc_page(GFP_KERNEL); ++ page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0); + if (!page) + return -ENOMEM; + +@@ -793,7 +793,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_we + struct page *page; + int s; + +- page = __dev_alloc_page(GFP_KERNEL); ++ page = __dev_alloc_pages(GFP_KERNEL | GFP_DMA32, 0); + if (!page) + return -ENOMEM; + +@@ -2435,6 +2435,9 @@ mtk_wed_attach(struct mtk_wed_device *de + dev->wdma_idx = hw->index; + dev->version = hw->version; + dev->hw->pcie_base = mtk_wed_get_pcie_base(dev); ++ ret = dma_set_mask_and_coherent(hw->dev, DMA_BIT_MASK(32)); ++ if (ret) ++ return ret; + + if (hw->eth->dma_dev == hw->eth->dev && + of_dma_is_coherent(hw->eth->dev->of_node)) diff --git a/target/linux/mediatek/patches-6.6/999-3002-fix-SER-case-call-trace-due-to-double-free-hwrro-buf.patch b/target/linux/mediatek/patches-6.6/999-3002-fix-SER-case-call-trace-due-to-double-free-hwrro-buf.patch new file mode 100644 index 00000000000000..6ed794f3894c40 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3002-fix-SER-case-call-trace-due-to-double-free-hwrro-buf.patch @@ -0,0 +1,19 @@ +From cd4c463856af91231164f8731e9726aa2f831242 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Fri, 27 Sep 2024 13:46:33 +0800 +Subject: [PATCH 1/6] fix SER case call trace due to double free hwrro buffer + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -1735,7 +1735,6 @@ mtk_wed_rx_reset(struct mtk_wed_device * + false); + } + mtk_wed_free_rx_buffer(dev); +- mtk_wed_hwrro_free_buffer(dev); + + return 0; + } diff --git a/target/linux/mediatek/patches-6.6/999-3003-refactor-mtk_wed_assgin-not-base-on-pci-domain.patch b/target/linux/mediatek/patches-6.6/999-3003-refactor-mtk_wed_assgin-not-base-on-pci-domain.patch new file mode 100644 index 00000000000000..8836485fd7b6dc --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3003-refactor-mtk_wed_assgin-not-base-on-pci-domain.patch @@ -0,0 +1,64 @@ +From 73c2090956a1aac2314c6003c35f958dfd0f3a8f Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Fri, 27 Sep 2024 14:17:12 +0800 +Subject: [PATCH 2/6] refactor mtk_wed_assgin not base on pci domain + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 31 +++++++------------------ + 1 file changed, 8 insertions(+), 23 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -488,34 +488,21 @@ void mtk_wed_fe_reset_complete(void) + static struct mtk_wed_hw * + mtk_wed_assign(struct mtk_wed_device *dev) + { +- struct mtk_wed_hw *hw; + int i; + +- if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) { +- hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)]; +- if (!hw) +- return NULL; ++ for (i = 0; i < ARRAY_SIZE(hw_list); i++) { ++ struct mtk_wed_hw *hw = hw_list[i]; + +- if (!hw->wed_dev) +- goto out; ++ if (!hw || hw->wed_dev) ++ continue; + +- if (mtk_wed_is_v1(hw)) +- return NULL; ++ hw->wed_dev = dev; ++ hw->pcie_base = MTK_WED_PCIE_BASE; + +- /* MT7986 WED devices do not have any pcie slot restrictions */ +- } +- /* MT7986 PCIE or AXI */ +- for (i = 0; i < ARRAY_SIZE(hw_list); i++) { +- hw = hw_list[i]; +- if (hw && !hw->wed_dev) +- goto out; ++ return hw; + } + + return NULL; +- +-out: +- hw->wed_dev = dev; +- return hw; + } + + static int +@@ -2403,9 +2390,7 @@ mtk_wed_attach(struct mtk_wed_device *de + RCU_LOCKDEP_WARN(!rcu_read_lock_held(), + "mtk_wed_attach without holding the RCU read lock"); + +- if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE && +- pci_domain_nr(dev->wlan.pci_dev->bus) > 1) || +- !try_module_get(THIS_MODULE)) ++ if (!try_module_get(THIS_MODULE)) + ret = -ENODEV; + + rcu_read_unlock(); diff --git a/target/linux/mediatek/patches-6.6/999-3004-fix-wdma-rx-hang-on-wed1-after-SER.patch b/target/linux/mediatek/patches-6.6/999-3004-fix-wdma-rx-hang-on-wed1-after-SER.patch new file mode 100644 index 00000000000000..eaccaa2a8b9426 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3004-fix-wdma-rx-hang-on-wed1-after-SER.patch @@ -0,0 +1,42 @@ +From c52a1e697f0bd2bd1ceb82140cb73a0887c6224b Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Fri, 27 Sep 2024 16:58:22 +0800 +Subject: [PATCH 3/6] fix wdma rx hang on wed1 after SER + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -250,7 +250,7 @@ mtk_wdma_rx_reset(struct mtk_wed_device + wdma_w32(dev, MTK_WDMA_RESET_IDX, 0); + + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) { +- if (dev->rx_wdma[i].desc) ++ if (!dev->rx_wdma[i].desc) + continue; + + wdma_w32(dev, +@@ -1785,6 +1785,21 @@ mtk_wed_reset_dma(struct mtk_wed_device + wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, + MTK_WED_WDMA_RX_PREF_DDONE2_EN); + ++ /* Reset prefetch index */ ++ wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, ++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | ++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); ++ ++ wed_clr(dev, MTK_WED_WDMA_RX_PREF_CFG, ++ MTK_WED_WDMA_RX_PREF_RX0_SIDX_CLR | ++ MTK_WED_WDMA_RX_PREF_RX1_SIDX_CLR); ++ ++ /* Reset prefetch FIFO */ ++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, ++ MTK_WED_WDMA_RX_PREF_FIFO_RX0_CLR | ++ MTK_WED_WDMA_RX_PREF_FIFO_RX1_CLR); ++ wed_w32(dev, MTK_WED_WDMA_RX_PREF_FIFO_CFG, 0); ++ + /* 2. Reset dma index */ + wed_w32(dev, MTK_WED_WDMA_RESET_IDX, + MTK_WED_WDMA_RESET_IDX_RX_ALL); diff --git a/target/linux/mediatek/patches-6.6/999-3005-Fix-reinsert-wifi-module-cause-memory-leak-issue.patch b/target/linux/mediatek/patches-6.6/999-3005-Fix-reinsert-wifi-module-cause-memory-leak-issue.patch new file mode 100644 index 00000000000000..f1d89809a982c8 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3005-Fix-reinsert-wifi-module-cause-memory-leak-issue.patch @@ -0,0 +1,69 @@ +From d83af8f83169ec2ebef82af5d8cad95dc27ce455 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Tue, 1 Oct 2024 14:07:22 +0800 +Subject: [PATCH 4/6] Fix reinsert wifi module cause memory leak issue + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -929,6 +929,16 @@ mtk_wed_free_ring(struct mtk_wed_device + static void + mtk_wed_free_rx_rings(struct mtk_wed_device *dev) + { ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(dev->rx_ring); i++) ++ if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED)) ++ mtk_wed_free_ring(dev, &dev->rx_ring[i]); ++ ++ for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++) ++ if ((dev->tx_wdma[i].flags & MTK_WED_RING_CONFIGURED)) ++ mtk_wed_free_ring(dev, &dev->tx_wdma[i]); ++ + mtk_wed_free_rx_buffer(dev); + mtk_wed_free_ring(dev, &dev->rro.ring); + } +@@ -939,9 +949,12 @@ mtk_wed_free_tx_rings(struct mtk_wed_dev + int i; + + for (i = 0; i < ARRAY_SIZE(dev->tx_ring); i++) +- mtk_wed_free_ring(dev, &dev->tx_ring[i]); ++ if ((dev->tx_ring[i].flags & MTK_WED_RING_CONFIGURED)) ++ mtk_wed_free_ring(dev, &dev->tx_ring[i]); ++ + for (i = 0; i < ARRAY_SIZE(dev->rx_wdma); i++) +- mtk_wed_free_ring(dev, &dev->rx_wdma[i]); ++ if ((dev->rx_wdma[i].flags & MTK_WED_RING_CONFIGURED)) ++ mtk_wed_free_ring(dev, &dev->rx_wdma[i]); + } + + static void +@@ -1906,6 +1919,8 @@ mtk_wed_wdma_rx_ring_setup(struct mtk_we + dev->hw->soc->wdma_desc_size, true)) + return -ENOMEM; + ++ wdma->flags |= MTK_WED_RING_CONFIGURED; ++ + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_BASE, + wdma->desc_phys); + wdma_w32(dev, MTK_WDMA_RING_RX(idx) + MTK_WED_RING_OFS_COUNT, +@@ -1952,6 +1967,8 @@ mtk_wed_wdma_tx_ring_setup(struct mtk_we + } + } + ++ wdma->flags |= MTK_WED_RING_CONFIGURED; ++ + wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_BASE, + wdma->desc_phys); + wdma_w32(dev, MTK_WDMA_RING_TX(idx) + MTK_WED_RING_OFS_COUNT, +@@ -2507,6 +2524,7 @@ mtk_wed_tx_ring_setup(struct mtk_wed_dev + + ring->reg_base = MTK_WED_RING_TX(idx); + ring->wpdma = regs; ++ ring->flags |= MTK_WED_RING_CONFIGURED; + + if (mtk_wed_is_v3_or_greater(dev->hw) && idx == 1) { + /* reset prefetch index */ diff --git a/target/linux/mediatek/patches-6.6/999-3006-Fix-Eagle-mlo-tx-T.P-too-low-issue.patch b/target/linux/mediatek/patches-6.6/999-3006-Fix-Eagle-mlo-tx-T.P-too-low-issue.patch new file mode 100644 index 00000000000000..ff42670a8dca84 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/999-3006-Fix-Eagle-mlo-tx-T.P-too-low-issue.patch @@ -0,0 +1,20 @@ +From 7385f88aec1d6b3717fd7a53709d6852e50c2816 Mon Sep 17 00:00:00 2001 +From: Rex Lu +Date: Tue, 1 Oct 2024 14:20:09 +0800 +Subject: [PATCH 5/6] Fix Eagle mlo tx T.P too low issue + +--- + drivers/net/ethernet/mediatek/mtk_wed.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/mediatek/mtk_wed.c ++++ b/drivers/net/ethernet/mediatek/mtk_wed.c +@@ -2134,7 +2134,7 @@ mtk_wed_dma_enable(struct mtk_wed_device + MTK_WED_WDMA_RX_PREF_DDONE2_EN); + wed_set(dev, MTK_WED_WDMA_RX_PREF_CFG, MTK_WED_WDMA_RX_PREF_EN); + +- wed_clr(dev, MTK_WED_WPDMA_GLO_CFG, ++ wed_set(dev, MTK_WED_WPDMA_GLO_CFG, + MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK_LAST); + wed_set(dev, MTK_WED_WPDMA_GLO_CFG, + MTK_WED_WPDMA_GLO_CFG_TX_DDONE_CHK | diff --git a/target/linux/ramips/dts/mt7628an_keenetic_kn-3211.dts b/target/linux/ramips/dts/mt7628an_keenetic_kn-3211.dts new file mode 100644 index 00000000000000..1a06cd94bc6bd1 --- /dev/null +++ b/target/linux/ramips/dts/mt7628an_keenetic_kn-3211.dts @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +#include "mt7628an.dtsi" + +#include +#include +#include + +/ { + compatible = "keenetic,kn-3211", "mediatek,mt7628an-soc"; + model = "Keenetic KN-3211"; + + aliases { + led-boot = &led_status_green; + led-failsafe = &led_status_red; + led-running = &led_status_green; + led-upgrade = &led_status_blue; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + }; + + leds { + compatible = "gpio-leds"; + + led_status_blue: status_blue { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 4 GPIO_ACTIVE_LOW>; + }; + + led_status_green: status_green { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 11 GPIO_ACTIVE_HIGH>; + }; + + led_status_red: status_red { + function = LED_FUNCTION_STATUS; + color = ; + gpios = <&gpio 38 GPIO_ACTIVE_LOW>; + }; + }; + + keys { + compatible = "gpio-keys"; + + wps { + label = "wps"; + gpios = <&gpio 37 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + virtual_flash { + compatible = "mtd-concat"; + devices = <&firmware1 &firmware2>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + compatible = "denx,uimage"; + label = "firmware"; + reg = <0x0 0x1ec0000>; + }; + }; + }; +}; + +&state_default { + gpio { + groups = "i2s", "i2c", "gpio", "refclk", "wdt", "wled_an"; + function = "gpio"; + }; +}; + +&usbphy { + status = "disabled"; +}; + +&ehci { + status = "disabled"; +}; + +&ohci { + status = "disabled"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <32000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x30000>; + read-only; + }; + + partition@30000 { + label = "u-config"; + reg = <0x30000 0x10000>; + read-only; + }; + + partition@40000 { + label = "rf-eeprom"; + reg = <0x40000 0x10000>; + read-only; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eeprom_factory_0: eeprom@0 { + reg = <0x0 0x400>; + }; + + eeprom_factory_400: eeprom@400 { + reg = <0x400 0x4da8>; + }; + + macaddr_factory_4: macaddr@4 { + reg = <0x4 0x6>; + }; + }; + }; + + firmware1: partition@50000 { + label = "firmware_1"; + reg = <0x50000 0xf60000>; + }; + + partition@fb0000 { + label = "config_1"; + reg = <0xfb0000 0x40000>; + read-only; + }; + + partition@ff0000 { + label = "dump"; + reg = <0xff0000 0x10000>; + read-only; + }; + + partition@1000000 { + label = "u-state"; + reg = <0x1000000 0x30000>; + read-only; + }; + + partition@1030000 { + label = "u-config_res"; + reg = <0x1030000 0x10000>; + read-only; + }; + + partition@1040000 { + label = "rf-eeprom_res"; + reg = <0x1040000 0x10000>; + read-only; + }; + + firmware2: partition@1050000 { + label = "firmware_2"; + reg = <0x1050000 0xf60000>; + }; + + partition@1fb0000 { + label = "config_2"; + reg = <0x1fb0000 0x40000>; + read-only; + }; + }; + }; +}; + +ðernet { + nvmem-cells = <&macaddr_factory_4>; + nvmem-cell-names = "mac-address"; +}; + +&esw { + mediatek,portmap = <0x3e>; +}; + +&wmac { + status = "okay"; + + nvmem-cells = <&eeprom_factory_0>; + nvmem-cell-names = "eeprom"; +}; + +&pcie { + status = "okay"; +}; + +&pcie0 { + wifi@0,0 { + compatible = "mediatek,mt76"; + reg = <0x0000 0 0 0 0>; + nvmem-cells = <&eeprom_factory_400>; + nvmem-cell-names = "eeprom"; + ieee80211-freq-limit = <5000000 6000000>; + }; +}; diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile index 569717694345c4..53b9c314ef65ec 100644 --- a/target/linux/ramips/image/Makefile +++ b/target/linux/ramips/image/Makefile @@ -167,10 +167,6 @@ define Build/wrg-header mv $@.new $@ endef -define Build/zyimage - $(STAGING_DIR_HOST)/bin/zyimage $(1) $@ -endef - define Device/Default PROFILES = Default BLOCKSIZE := 64k diff --git a/target/linux/ramips/image/mt76x8.mk b/target/linux/ramips/image/mt76x8.mk index 7e343bf0164fb0..25a7344afbe5e1 100644 --- a/target/linux/ramips/image/mt76x8.mk +++ b/target/linux/ramips/image/mt76x8.mk @@ -365,6 +365,16 @@ define Device/keenetic_kn-1613 endef TARGET_DEVICES += keenetic_kn-1613 +define Device/keenetic_kn-3211 + IMAGE_SIZE := 31488k + DEVICE_VENDOR := Keenetic + DEVICE_MODEL := KN-3211 + IMAGES += factory.bin + IMAGE/factory.bin := $$(sysupgrade_bin) | pad-to $$$$(BLOCKSIZE) | \ + check-size | zyimage -d 0x803211 -v "KN-3211" +endef +TARGET_DEVICES += keenetic_kn-3211 + define Device/kroks_kndrt31r16 IMAGE_SIZE := 16064k DEVICE_VENDOR := Kroks diff --git a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network index 616baa80c055c7..e57643690a172c 100644 --- a/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network +++ b/target/linux/ramips/mt76x8/base-files/etc/board.d/02_network @@ -134,6 +134,10 @@ ramips_setup_interfaces() ucidef_add_switch "switch0" \ "1:lan" "2:lan" "3:lan" "0:wan" "6@eth0" ;; + keenetic,kn-3211) + ucidef_add_switch "switch0" \ + "2:lan" "6@eth0" + ;; kroks,kndrt31r19) ucidef_add_switch "switch0" \ "0:lan" "6@eth0" @@ -280,6 +284,7 @@ ramips_setup_macs() wan_mac=$(mtd_get_mac_binary factory 0x2e) ;; keenetic,kn-1613|\ + keenetic,kn-3211|\ zyxel,keenetic-extra-ii) wan_mac=$(mtd_get_mac_binary rf-eeprom 0x28) ;; diff --git a/tools/ccache/Makefile b/tools/ccache/Makefile index 47c24a5c98864a..447bc3ea432f04 100644 --- a/tools/ccache/Makefile +++ b/tools/ccache/Makefile @@ -7,11 +7,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ccache -PKG_VERSION:=4.10 +PKG_VERSION:=4.10.2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/ccache/ccache/releases/download/v$(PKG_VERSION) -PKG_HASH:=16972ba62c8499045edc3ae7d7b8a0b419a961567f5ff0f01bf5a44194204775 +PKG_HASH:=108100960bb7e64573ea925af2ee7611701241abb36ce0aae3354528403a7d87 include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/cmake.mk diff --git a/tools/ccache/patches/100-honour-copts.patch b/tools/ccache/patches/100-honour-copts.patch index a40665ea25836c..c07c8ce8eb3a25 100644 --- a/tools/ccache/patches/100-honour-copts.patch +++ b/tools/ccache/patches/100-honour-copts.patch @@ -1,6 +1,6 @@ --- a/src/ccache/ccache.cpp +++ b/src/ccache/ccache.cpp -@@ -1906,6 +1906,7 @@ get_manifest_key(Context& ctx, Hash& has +@@ -1914,6 +1914,7 @@ get_manifest_key(Context& ctx, Hash& has "OBJCPLUS_INCLUDE_PATH", // Clang "CLANG_CONFIG_FILE_SYSTEM_DIR", // Clang "CLANG_CONFIG_FILE_USER_DIR", // Clang