diff --git a/include/image.mk b/include/image.mk index 9a4dff2167..058af2d269 100644 --- a/include/image.mk +++ b/include/image.mk @@ -2,6 +2,7 @@ # # Copyright (C) 2006-2020 OpenWrt.org + override TARGET_BUILD= include $(INCLUDE_DIR)/prereq.mk include $(INCLUDE_DIR)/kernel.mk @@ -175,13 +176,17 @@ endif # Disable noisy checks by default as in upstream DTC_WARN_FLAGS := \ - -Wno-interrupt_provider \ - -Wno-unique_unit_address \ -Wno-unit_address_vs_reg \ + -Wno-simple_bus_reg \ + -Wno-unit_address_format \ + -Wno-pci_bridge \ + -Wno-pci_device_bus_num \ + -Wno-pci_device_reg \ -Wno-avoid_unnecessary_addr_size \ -Wno-alias_paths \ -Wno-graph_child_address \ - -Wno-simple_bus_reg + -Wno-graph_port \ + -Wno-unique_unit_address DTC_FLAGS += $(DTC_WARN_FLAGS) DTCO_FLAGS += $(DTC_WARN_FLAGS) diff --git a/include/target.mk b/include/target.mk index 49e5a4ecc4..68556a2e90 100644 --- a/include/target.mk +++ b/include/target.mk @@ -176,16 +176,16 @@ ifneq ($(TARGET_BUILD)$(if $(DUMP),,1),) endif GENERIC_PLATFORM_DIR := $(TOPDIR)/target/linux/generic -GENERIC_BACKPORT_DIR := $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) -GENERIC_PATCH_DIR := $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) -GENERIC_HACK_DIR := $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) -GENERIC_FILES_DIR := $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(KERNEL_PATCHVER)),"$(dir)") +GENERIC_BACKPORT_DIR ?= $(GENERIC_PLATFORM_DIR)/backport$(if $(wildcard $(GENERIC_PLATFORM_DIR)/backport-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) +GENERIC_PATCH_DIR ?= $(GENERIC_PLATFORM_DIR)/pending$(if $(wildcard $(GENERIC_PLATFORM_DIR)/pending-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) +GENERIC_HACK_DIR ?= $(GENERIC_PLATFORM_DIR)/hack$(if $(wildcard $(GENERIC_PLATFORM_DIR)/hack-$(KERNEL_PATCHVER)),-$(KERNEL_PATCHVER)) +GENERIC_FILES_DIR ?= $(foreach dir,$(wildcard $(GENERIC_PLATFORM_DIR)/files $(GENERIC_PLATFORM_DIR)/files-$(KERNEL_PATCHVER)),"$(dir)") __config_name_list = $(1)/config-$(KERNEL_PATCHVER) $(1)/config-default __config_list = $(firstword $(wildcard $(call __config_name_list,$(1)))) find_kernel_config=$(if $(__config_list),$(__config_list),$(lastword $(__config_name_list))) -GENERIC_LINUX_CONFIG = $(call find_kernel_config,$(GENERIC_PLATFORM_DIR)) +GENERIC_LINUX_CONFIG ?= $(call find_kernel_config,$(GENERIC_PLATFORM_DIR))$(CONFIG_FILE_SUFFIX) LINUX_TARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_DIR)) ifneq ($(PLATFORM_DIR),$(PLATFORM_SUBDIR)) LINUX_SUBTARGET_CONFIG = $(call find_kernel_config,$(PLATFORM_SUBDIR)) @@ -282,6 +282,7 @@ ifeq ($(DUMP),1) CPU_TYPE ?= generic CPU_CFLAGS_generic = -mcpu=generic CPU_CFLAGS_cortex-a53 = -mcpu=cortex-a53 + CPU_CFLAGS_cortex-a73 = -mcpu=cortex-a73+crypto endif ifeq ($(ARCH),arc) CPU_TYPE ?= arc700 diff --git a/package/kernel/linux/Makefile b/package/kernel/linux/Makefile index 39b9e82c27..0a31a5ac3f 100644 --- a/package/kernel/linux/Makefile +++ b/package/kernel/linux/Makefile @@ -47,7 +47,7 @@ define Package/kernel CATEGORY:=Kernel DEFAULT:=y TITLE:=Virtual kernel package - VERSION:=$(LINUX_VERSION)-$(LINUX_RELEASE)-$(LINUX_VERMAGIC) + VERSION:=$(LINUX_VERSION)~$(LINUX_VERMAGIC)-r$(LINUX_RELEASE) URL:=http://www.kernel.org/ PKG_FLAGS:=nonshared endef diff --git a/package/utils/iwinfo/Makefile b/package/utils/iwinfo/Makefile new file mode 100644 index 0000000000..1b4745ec2a --- /dev/null +++ b/package/utils/iwinfo/Makefile @@ -0,0 +1,121 @@ +# +# Copyright (C) 2010-2016 Jo-Philipp Wich +# +# This is free software, licensed under the GPL 2 license. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=libiwinfo +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=$(PROJECT_GIT)/project/iwinfo.git +PKG_SOURCE_DATE:=2023-07-01 +PKG_SOURCE_VERSION:=ca79f64154b107f192ec3c1ba631816cb8b07922 +PKG_MIRROR_HASH:=5eddf584a1c3ed5637162d6bfc573ed1ce3691fcb38bdd55bf9f1e11e82ccc46 +PKG_MAINTAINER:=Jo-Philipp Wich +PKG_LICENSE:=GPL-2.0 + +PKG_BUILD_FLAGS:=no-lto + +IWINFO_ABI_VERSION:=20230701 + +include $(INCLUDE_DIR)/package.mk + + +define Package/libiwinfo + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Generalized Wireless Information Library (iwinfo) + DEPENDS:=+libnl-tiny +libuci +libubus +libiwinfo-data + ABI_VERSION:=$(IWINFO_ABI_VERSION) +endef + +define Package/libiwinfo/description + Wireless information library with simplified API for nl80211 + and wext driver interfaces. +endef + + +define Package/libiwinfo-lua + SUBMENU:=Lua + SECTION:=lang + CATEGORY:=Languages + TITLE:=libiwinfo Lua binding + DEPENDS:=+libiwinfo +liblua +endef + +define Package/libiwinfo-lua/description + This is the Lua binding for the iwinfo library. It provides access to all enabled + backends. +endef + + +define Package/libiwinfo-data + TITLE:=libiwinfo Lua binding + HIDDEN:=1 +endef + + +define Package/iwinfo + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Generalized Wireless Information utility + DEPENDS:=+libiwinfo +endef + +define Package/iwinfo/description + Command line frontend for the wireless information library. +endef + + +define Build/Configure +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include/libnl-tiny \ + -I$(STAGING_DIR)/usr/include \ + -D_GNU_SOURCE + +MAKE_FLAGS += \ + FPIC="$(FPIC)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + BACKENDS="nl80211 mtk" \ + SOVERSION="$(IWINFO_ABI_VERSION)" + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/iwinfo + $(CP) $(PKG_BUILD_DIR)/include/iwinfo.h $(1)/usr/include/ + $(CP) $(PKG_BUILD_DIR)/include/iwinfo/* $(1)/usr/include/iwinfo/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/libiwinfo.so* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/lib/lua + $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.so $(1)/usr/lib/lua/iwinfo.so +endef + +define Package/libiwinfo/install + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_BIN) $(PKG_BUILD_DIR)/libiwinfo.so.$(IWINFO_ABI_VERSION) $(1)/usr/lib/libiwinfo.so.$(IWINFO_ABI_VERSION) +endef + +define Package/libiwinfo-lua/install + $(INSTALL_DIR) $(1)/usr/lib/lua + $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo.so $(1)/usr/lib/lua/iwinfo.so +endef + +define Package/libiwinfo-data/install + $(INSTALL_DIR) $(1)/usr/share/libiwinfo + $(INSTALL_DATA) $(PKG_BUILD_DIR)/devices.txt $(1)/usr/share/libiwinfo/devices.txt +endef + +define Package/iwinfo/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/iwinfo $(1)/usr/bin/iwinfo +endef + +$(eval $(call BuildPackage,libiwinfo)) +$(eval $(call BuildPackage,libiwinfo-lua)) +$(eval $(call BuildPackage,libiwinfo-data)) +$(eval $(call BuildPackage,iwinfo)) diff --git a/package/utils/iwinfo/patches/0001-support-mt798x.patch b/package/utils/iwinfo/patches/0001-support-mt798x.patch new file mode 100644 index 0000000000..89d34d3b2d --- /dev/null +++ b/package/utils/iwinfo/patches/0001-support-mt798x.patch @@ -0,0 +1,228 @@ +diff -u -r a/api/wext.h b/api/wext.h +--- a/api/wext.h 2023-06-26 03:58:09.000000000 +0800 ++++ b/api/wext.h 2024-09-22 23:32:30.698447416 +0800 +@@ -677,7 +677,7 @@ + */ + struct iw_param + { +- int32_t value; /* The value of the parameter itself */ ++ uint64_t value; /* The value of the parameter itself */ + uint8_t fixed; /* Hardware should not use auto select */ + uint8_t disabled; /* Disable the feature */ + uint16_t flags; /* Various specifc flags (if any) */ +@@ -987,6 +987,8 @@ + /* Old Frequency (backward compat - moved lower ) */ + uint16_t old_num_channels; + uint8_t old_num_frequency; ++ ++ uint8_t scan_capa; /* IW_SCAN_CAPA_* bit field */ + + /* Wireless event capability bitmasks */ + uint32_t event_capa[6]; +@@ -1013,7 +1015,7 @@ + + /* Rates */ + uint8_t num_bitrates; /* Number of entries in the list */ +- int32_t bitrate[IW_MAX_BITRATES]; /* list, in bps */ ++ uint64_t bitrate[IW_MAX_BITRATES]; /* list, in bps */ + + /* RTS threshold */ + int32_t min_rts; /* Minimal RTS threshold */ +diff -u -r a/devices.txt b/devices.txt +--- a/devices.txt 2023-06-26 03:58:09.000000000 +0800 ++++ b/devices.txt 2024-09-22 23:33:42.870929802 +0800 +@@ -185,6 +185,8 @@ + 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 0x7986 0x14c3 0x7986 0 0 "MediaTek" "MT7986" ++0x14c3 0x7981 0x14c3 0x7981 0 0 "MediaTek" "MT7981" + 0x14c3 0x7915 0x14c3 0x7915 0 0 "MediaTek" "MT7915E" + 0x14e4 0xaa52 0x14e4 0xaa52 0 0 "Broadcom" "BCM43602" + 0x02d0 0xa9a6 0x0000 0x0000 0 0 "Cypress" "CYW43455" +diff -u -r a/Makefile b/Makefile +--- a/Makefile 2023-06-26 03:58:09.000000000 +0800 ++++ b/Makefile 2024-09-20 21:16:45.926991219 +0800 +@@ -32,6 +32,11 @@ + IWINFO_LIB_OBJ += iwinfo_madwifi.o + endif + ++ifneq ($(filter mtk,$(IWINFO_BACKENDS)),) ++ IWINFO_CFLAGS += -DUSE_MTK ++ IWINFO_LIB_OBJ += iwinfo_mtk.o iwinfo_mtk_rate.o ++endif ++ + ifneq ($(filter nl80211,$(IWINFO_BACKENDS)),) + IWINFO_CFLAGS += -DUSE_NL80211 + IWINFO_CLI_LDFLAGS += -lnl-tiny +--- a/include/iwinfo.h ++++ b/include/iwinfo.h +@@ -313,6 +313,7 @@ extern const struct iwinfo_ops wext_ops; + extern const struct iwinfo_ops madwifi_ops; + extern const struct iwinfo_ops nl80211_ops; + extern const struct iwinfo_ops wl_ops; ++extern const struct iwinfo_ops mtk_ops; + + #include "iwinfo/utils.h" + +--- a/iwinfo_lib.c ++++ b/iwinfo_lib.c +@@ -347,6 +347,9 @@ static const struct iwinfo_ops *backends + #ifdef USE_WEXT + &wext_ops, + #endif ++#ifdef USE_MTK ++ &mtk_ops, ++#endif + }; + + const char * iwinfo_type(const char *ifname) +--- a/include/iwinfo/lua.h ++++ b/include/iwinfo/lua.h +@@ -41,6 +41,9 @@ + #define IWINFO_NL80211_META "iwinfo.nl80211" + #endif + ++#ifdef USE_MTK ++#define IWINFO_MTK_META "iwinfo.mtk" ++#endif + + #define LUA_REG(type,op) \ + { #op, iwinfo_L_##type##_##op } +--- a/iwinfo_lua.c ++++ b/iwinfo_lua.c +@@ -775,6 +775,35 @@ LUA_WRAP_STRUCT_OP(nl80211,mbssid_suppor + LUA_WRAP_STRUCT_OP(nl80211,hardware_id) + #endif + ++#ifdef USE_MTK ++LUA_WRAP_INT_OP(mtk,channel) ++LUA_WRAP_INT_OP(mtk,frequency) ++LUA_WRAP_INT_OP(mtk,frequency_offset) ++LUA_WRAP_INT_OP(mtk,txpower) ++LUA_WRAP_INT_OP(mtk,txpower_offset) ++LUA_WRAP_INT_OP(mtk,bitrate) ++LUA_WRAP_INT_OP(mtk,signal) ++LUA_WRAP_INT_OP(mtk,noise) ++LUA_WRAP_INT_OP(mtk,quality) ++LUA_WRAP_INT_OP(mtk,quality_max) ++LUA_WRAP_STRING_OP(mtk,ssid) ++LUA_WRAP_STRING_OP(mtk,bssid) ++LUA_WRAP_STRING_OP(mtk,country) ++LUA_WRAP_STRING_OP(mtk,hardware_name) ++LUA_WRAP_STRING_OP(mtk,phyname) ++LUA_WRAP_STRUCT_OP(mtk,mode) ++LUA_WRAP_STRUCT_OP(mtk,assoclist) ++LUA_WRAP_STRUCT_OP(mtk,txpwrlist) ++LUA_WRAP_STRUCT_OP(mtk,scanlist) ++LUA_WRAP_STRUCT_OP(mtk,freqlist) ++LUA_WRAP_STRUCT_OP(mtk,countrylist) ++LUA_WRAP_STRUCT_OP(mtk,hwmodelist) ++LUA_WRAP_STRUCT_OP(mtk,htmodelist) ++LUA_WRAP_STRUCT_OP(mtk,encryption) ++LUA_WRAP_STRUCT_OP(mtk,mbssid_support) ++LUA_WRAP_STRUCT_OP(mtk,hardware_id) ++#endif ++ + /* Wext */ + #ifdef USE_WEXT + LUA_WRAP_INT_OP(wext,channel) +@@ -904,6 +933,38 @@ static const luaL_reg R_nl80211[] = { + }; + #endif + ++#ifdef USE_MTK ++static const luaL_reg R_mtk[] = { ++ LUA_REG(mtk,channel), ++ LUA_REG(mtk,frequency), ++ LUA_REG(mtk,frequency_offset), ++ LUA_REG(mtk,txpower), ++ LUA_REG(mtk,txpower_offset), ++ LUA_REG(mtk,bitrate), ++ LUA_REG(mtk,signal), ++ LUA_REG(mtk,noise), ++ LUA_REG(mtk,quality), ++ LUA_REG(mtk,quality_max), ++ LUA_REG(mtk,mode), ++ LUA_REG(mtk,ssid), ++ LUA_REG(mtk,bssid), ++ LUA_REG(mtk,country), ++ LUA_REG(mtk,assoclist), ++ LUA_REG(mtk,txpwrlist), ++ LUA_REG(mtk,scanlist), ++ LUA_REG(mtk,freqlist), ++ LUA_REG(mtk,countrylist), ++ LUA_REG(mtk,hwmodelist), ++ LUA_REG(mtk,htmodelist), ++ LUA_REG(mtk,encryption), ++ LUA_REG(mtk,mbssid_support), ++ LUA_REG(mtk,hardware_id), ++ LUA_REG(mtk,hardware_name), ++ LUA_REG(mtk,phyname), ++ { NULL, NULL } ++}; ++#endif ++ + /* Wext table */ + #ifdef USE_WEXT + static const luaL_reg R_wext[] = { +@@ -975,6 +1036,15 @@ LUALIB_API int luaopen_iwinfo(lua_State + lua_setfield(L, -2, "nl80211"); + #endif + ++#ifdef USE_MTK ++ luaL_newmetatable(L, IWINFO_MTK_META); ++ luaL_register(L, NULL, R_common); ++ luaL_register(L, NULL, R_mtk); ++ lua_pushvalue(L, -1); ++ lua_setfield(L, -2, "__index"); ++ lua_setfield(L, -2, "mtk"); ++#endif ++ + #ifdef USE_WEXT + luaL_newmetatable(L, IWINFO_WEXT_META); + luaL_register(L, NULL, R_common); +--- a/iwinfo_utils.c ++++ b/iwinfo_utils.c +@@ -176,6 +176,7 @@ int iwinfo_hardware_id_from_mtd(struct i + { + FILE *mtd; + uint16_t *bc; ++ uint16_t ident; + + int fd, off; + unsigned int len; +@@ -188,7 +189,7 @@ int iwinfo_hardware_id_from_mtd(struct i + { + if (fscanf(mtd, "mtd%d: %x %*x %127s", &off, &len, buf) < 3 || + (strcmp(buf, "\"boardconfig\"") && strcmp(buf, "\"EEPROM\"") && +- strcmp(buf, "\"factory\""))) ++ strcmp(buf, "\"factory\"") && strcmp(buf, "\"Factory\""))) + { + off = -1; + continue; +@@ -207,6 +208,24 @@ int iwinfo_hardware_id_from_mtd(struct i + if ((fd = open(buf, O_RDONLY)) < 0) + return -1; + ++ if (read(fd, &ident, sizeof(ident)) != -1) ++ { ++ if (ident == 0x7981 || ident == 0x7986 ++ || ident == 0x8179 || ident == 0x8679) ++ { ++ if ((ident & 0xff) == 0x79) ++ id->device_id = (ident >> 8) | (ident & 0x00ff) << 8; ++ else ++ id->device_id = ident; ++ id->vendor_id = 0x14c3; ++ id->subsystem_vendor_id = 0x14c3; ++ id->subsystem_device_id = id->device_id; ++ close(fd); ++ return 0; ++ } ++ } ++ lseek(fd, 0, SEEK_SET); ++ + bc = mmap(NULL, len, PROT_READ, MAP_PRIVATE|MAP_LOCKED, fd, 0); + + if ((void *)bc != MAP_FAILED) diff --git a/package/utils/iwinfo/src/iwinfo_mtk.c b/package/utils/iwinfo/src/iwinfo_mtk.c new file mode 100644 index 0000000000..39358dfd6d --- /dev/null +++ b/package/utils/iwinfo/src/iwinfo_mtk.c @@ -0,0 +1,1104 @@ +#include +#include "iwinfo.h" +#include "iwinfo_wext.h" +#include "mtwifi.h" + +#include "iwinfo_mtk_ccode.c" + +static inline int mtk_ioctl(const char *ifname, int cmd, struct iwreq *wrq) +{ + strncpy(wrq->ifr_name, ifname, IFNAMSIZ); + return iwinfo_ioctl(cmd, wrq); +} + +static const char *mtk_dev2phy(const char *devname) +{ + const char *phy = NULL; + struct uci_section *s; + + if (strstr(devname,"ra") || strstr(devname,"apcli")) + return devname; + + s = iwinfo_uci_get_radio(devname, "mtwifi"); + if (!s) + goto out; + + phy = uci_lookup_option_string(uci_ctx, s, "phy"); + +out: + iwinfo_uci_free(); + return phy; +} + +static int mtk_probe(const char *dev) +{ + const char *phy = NULL; + struct uci_section *s; + + if (strstr(dev,"ra") || strstr(dev,"apcli")) + return true; + + s = iwinfo_uci_get_radio(dev, "mtwifi"); + if (!s) + goto out; + + phy = uci_lookup_option_string(uci_ctx, s, "phy"); + if (phy) { + iwinfo_uci_free(); + return true; + } + +out: + iwinfo_uci_free(); + return false; +} + +static void mtk_close(void) +{ + iwinfo_close(); +} + +static int mtk_is_ifup(const char *ifname) +{ + struct ifreq ifr; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); + + if (iwinfo_ioctl(SIOCGIFFLAGS, &ifr) >= 0) + { + if (ifr.ifr_flags & IFF_UP) + return 1; + } + + return 0; +} + +static int mtk_get_mode(const char *dev, int *buf) +{ + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if(mtk_ioctl(ifname, SIOCGIWMODE, &wrq) >= 0) + { + switch(wrq.u.mode) + { + case 1: + *buf = IWINFO_OPMODE_ADHOC; + break; + + case 2: + *buf = IWINFO_OPMODE_CLIENT; + break; + + case 3: + *buf = IWINFO_OPMODE_MASTER; + break; + + case 6: + *buf = IWINFO_OPMODE_MONITOR; + break; + + default: + *buf = IWINFO_OPMODE_UNKNOWN; + break; + } + + return 0; + } + + return -1; +} + +static int mtk_get_ssid(const char *dev, char *buf) +{ + struct iwreq wrq = {}; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + wrq.u.essid.pointer = buf; + wrq.u.essid.length = IW_ESSID_MAX_SIZE; + + if(mtk_ioctl(ifname, SIOCGIWESSID, &wrq) >= 0) + return 0; + + return -1; +} + +static int mtk_get_bssid(const char *dev, char *buf) +{ + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if(mtk_ioctl(ifname, SIOCGIWAP, &wrq) >= 0) + { + sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + (uint8_t)wrq.u.ap_addr.sa_data[0], (uint8_t)wrq.u.ap_addr.sa_data[1], + (uint8_t)wrq.u.ap_addr.sa_data[2], (uint8_t)wrq.u.ap_addr.sa_data[3], + (uint8_t)wrq.u.ap_addr.sa_data[4], (uint8_t)wrq.u.ap_addr.sa_data[5]); + + return 0; + } + + return -1; +} + +static int mtk_get_bitrate(const char *dev, int *buf) +{ + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if(mtk_ioctl(ifname, SIOCGIWRATE, &wrq) >= 0) + { + *buf = (wrq.u.bitrate.value / 1000); + return 0; + } + + return -1; +} + +static int mtk_get_channel(const char *dev, int *buf) +{ + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (mtk_ioctl(ifname, SIOCGIWFREQ, &wrq) >= 0) + { + *buf = wrq.u.freq.m; + return 0; + } + + return -1; +} + +static int mtk_get_center_chan1(const char *dev, int *buf) +{ + /* Not Supported */ + return -1; +} + +static int mtk_get_center_chan2(const char *dev, int *buf) +{ + /* Not Supported */ + return -1; +} + +static int mtk_get_frequency(const char *dev, int *buf) +{ + int channel; + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (mtk_ioctl(ifname, SIOCGIWFREQ, &wrq) >= 0) + { + channel = wrq.u.freq.m; + + if (channel <= 0) + return -1; + + if (channel > 14) { + if (channel >= 182 && channel <= 196) + *buf = 4000 + channel * 5; + else + *buf = 5000 + channel * 5; + } else if (channel == 14) { + *buf = 2484; + } else { + *buf = 2407 + channel * 5; + } + + return 0; + } + + return -1; + +} + +static int mtk_get_txpower(const char *dev, int *buf) +{ + struct iwreq wrq; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + wrq.u.txpower.flags = 0; + + if(mtk_ioctl(ifname, SIOCGIWTXPOW, &wrq) >= 0) + { + *buf = wrq.u.txpower.value; + return 0; + } + + return -1; +} + +static int mtk_get_signal(const char *dev, int *buf) +{ + return mtk_get_txpower(dev, buf); +} + +static int mtk_get_noise(const char *dev, int *buf) +{ + return -1; +} + +static int mtk_get_quality(const char *dev, int *buf) +{ + *buf = 100; + return 0; +} + +static int mtk_get_quality_max(const char *dev, int *buf) +{ + *buf = 100; + return 0; +} + +static void fill_rate_info(HTTRANSMIT_SETTING HTSetting, struct iwinfo_rate_entry *re, + unsigned int mcs, unsigned int nss) +{ + unsigned long DataRate = 0; + + if (HTSetting.field.MODE >= MODE_HTMIX && HTSetting.field.MODE < MODE_HE) + { + if (HTSetting.field.ShortGI) + re->is_short_gi = 1; + } + + if (HTSetting.field.MODE >= MODE_HTMIX && HTSetting.field.MODE <= MODE_HTGREENFIELD) + re->is_ht = 1; + else if (HTSetting.field.MODE == MODE_VHT) + re->is_vht = 1; + else if (HTSetting.field.MODE >= MODE_HE) + re->is_he = 1; + + if (HTSetting.field.MODE >= MODE_HE) + re->he_gi = HTSetting.field.ShortGI; + + if (HTSetting.field.BW == BW_20) + re->mhz = 20; + else if (HTSetting.field.BW == BW_40) + re->mhz = 40; + else if (HTSetting.field.BW == BW_80) + re->mhz = 80; + else if (HTSetting.field.BW == BW_160) + re->mhz = 160; + + re->is_40mhz = (re->mhz == 40); + + if (HTSetting.field.MODE >= MODE_HE) { + get_rate_he((mcs & 0xf), HTSetting.field.BW, nss, 0, &DataRate); + if (HTSetting.field.ShortGI == 1) + DataRate = (DataRate * 967) >> 10; + else if (HTSetting.field.ShortGI == 2) + DataRate = (DataRate * 870) >> 10; + } else { + getRate(HTSetting, &DataRate); + } + re->rate = (uint32_t)(DataRate * 1000); +} + +static void mtk_parse_rateinfo(RT_802_11_MAC_ENTRY *pe, + struct iwinfo_rate_entry *rx_rate, struct iwinfo_rate_entry *tx_rate) +{ + HTTRANSMIT_SETTING TxRate; + HTTRANSMIT_SETTING RxRate; + + unsigned int mcs = 0; + unsigned int nss = 0; + + unsigned int mcs_r = 0; + unsigned int nss_r = 0; + + TxRate.word = pe->TxRate.word; + RxRate.word = pe->LastRxRate.word; + + mcs = TxRate.field.MCS; + mcs_r = RxRate.field.MCS; + + if (TxRate.field.MODE >= MODE_VHT) { + nss = ((mcs & (0x3 << 4)) >> 4) + 1; + mcs = mcs & 0xF; + tx_rate->nss = nss; + } else { + mcs = mcs & 0x3f; + tx_rate->nss = 1; + } + tx_rate->mcs = mcs; + + if (RxRate.field.MODE >= MODE_VHT) { + nss_r = (((mcs_r & (0x3 << 4)) >> 4) + 1) / (RxRate.field.STBC + 1); + mcs_r = mcs_r & 0xF; + rx_rate->nss = nss_r; + } else { + rx_rate->nss = 1; + if (RxRate.field.MODE >= MODE_HTMIX) { + mcs_r = mcs_r & 0x3f; + } else if (RxRate.field.MODE == MODE_OFDM) { + mcs_r = mcs_r & 0xf; + RxRate.field.MCS = mcs_r; + } else if (RxRate.field.MODE == MODE_CCK) { + mcs_r = cck_to_mcs(mcs_r & 0x7); + RxRate.field.MCS = mcs_r; + } + } + rx_rate->mcs = mcs_r; + + fill_rate_info(TxRate, tx_rate, mcs, nss); + fill_rate_info(RxRate, rx_rate, mcs_r, nss_r); +} + +static int mtk_get_assoclist(const char *dev, char *buf, int *len) +{ + struct iwreq wrq = {}; + RT_802_11_MAC_TABLE *table; + int i; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + table = calloc(1, sizeof(RT_802_11_MAC_TABLE)); + if (!table) + return -1; + + wrq.u.data.pointer = (caddr_t)table; + wrq.u.data.length = sizeof(RT_802_11_MAC_TABLE); + + if (mtk_ioctl(ifname, RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT, &wrq) < 0) { + free(table); + return -1; + } + + *len = 0; + + for (i = 0; i < table->Num; i++) { + RT_802_11_MAC_ENTRY *pe = &(table->Entry[i]); + struct iwinfo_assoclist_entry *e = (struct iwinfo_assoclist_entry *)buf + i; + + memcpy(e->mac, pe->Addr, 6); + e->signal = pe->AvgRssi0; + e->signal_avg = pe->AvgRssi0; + e->connected_time = pe->ConnectedTime; + mtk_parse_rateinfo(pe, &e->rx_rate, &e->tx_rate); + + *len += sizeof(struct iwinfo_assoclist_entry); + } + + free(table); + return 0; +} + +static int mtk_get_txpwrlist(const char *dev, char *buf, int *len) +{ + return -1; +} + +static int mtk_get_scanlist_dump(const char *ifname, int index, char *data, size_t len) +{ + struct iwreq wrq = {}; + + snprintf(data, len, "%d", index); + + wrq.u.data.pointer = data; + wrq.u.data.length = len; + wrq.u.data.flags = GET_MAC_TABLE_STRUCT_FLAG_RAW_SSID; + + return mtk_ioctl(ifname, RTPRIV_IOCTL_GSITESURVEY, &wrq); +} + +enum { + SCAN_DATA_CH, + SCAN_DATA_SSID, + SCAN_DATA_BSSID, + SCAN_DATA_SECURITY, + SCAN_DATA_RSSI, + SCAN_DATA_SIG, + SCAN_DATA_NT, + SCAN_DATA_SSID_LEN, + SCAN_DATA_MAX +}; + +static int mtk_get_scanlist(const char *dev, char *buf, int *len) +{ + struct iwinfo_scanlist_entry *e = (struct iwinfo_scanlist_entry *)buf; + char *data = NULL; + unsigned int data_len = 5000; + int offsets[SCAN_DATA_MAX]; + char cmd[128]; + int index = 0; + int total = -1; + char *pos; + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + *len = 0; + + if ((data = (char *)malloc(data_len)) == NULL) + return -1; + + sprintf(cmd, "iwpriv %s set SiteSurvey=", ifname); + system(cmd); + + sleep(5); + + while (1) { + memset(data, 0, data_len); + if (mtk_get_scanlist_dump(ifname, index, data, sizeof(data))) { + free(data); + return -1; + } + + //printf("%s\n", data); + + sscanf(data, "\nTotal=%d", &total); + + strtok(data, "\n"); + pos = strtok(NULL, "\n"); + + offsets[SCAN_DATA_CH] = strstr(pos, "Ch ") - pos; + offsets[SCAN_DATA_SSID] = strstr(pos, "SSID ") - pos; + offsets[SCAN_DATA_BSSID] = strstr(pos, "BSSID ") - pos; + offsets[SCAN_DATA_SECURITY] = strstr(pos, "Security ") - pos; + offsets[SCAN_DATA_RSSI] = strstr(pos, "Rssi") - pos; + offsets[SCAN_DATA_SIG] = strstr(pos, "Siganl") - pos; + offsets[SCAN_DATA_NT] = strstr(pos, "NT") - pos; + offsets[SCAN_DATA_SSID_LEN] = strstr(pos, "SSID_Len") - pos; + + while (1) { + struct iwinfo_crypto_entry *crypto = &e->crypto; + const char *security; + uint8_t *mac = e->mac; + int ssid_len; + + pos = strtok(NULL, "\n"); + if (!pos) + break; + + sscanf(pos, "%d", &index); + + if (strncmp(pos + offsets[SCAN_DATA_NT], "In", 2)) + continue; + + security = pos + offsets[SCAN_DATA_SECURITY]; + if (!strstr(security, "PSK") && !strstr(security, "OPEN") && !strstr(security, "OWE")) + continue; + + memset(crypto, 0, sizeof(struct iwinfo_crypto_entry)); + + if (strstr(security, "PSK") || strstr(security, "OWE")) { + crypto->enabled = true; + + if (strstr(security, "WPAPSK")) { + crypto->wpa_version |= 1 << 0; + crypto->auth_suites |= IWINFO_KMGMT_PSK; + } + + if (strstr(security, "WPA2PSK")) { + crypto->wpa_version |= 1 << 1; + crypto->auth_suites |= IWINFO_KMGMT_PSK; + } + + if (strstr(security, "WPA3PSK")) { + crypto->wpa_version |= 1 << 2; + crypto->auth_suites |= IWINFO_KMGMT_SAE; + } + + if (strstr(security, "OWE")) { + crypto->wpa_version |= 1 << 2; + crypto->auth_suites |= IWINFO_KMGMT_OWE; + } + + if (strstr(security, "AES")) { + crypto->pair_ciphers |= IWINFO_CIPHER_CCMP; + } + + if (strstr(security, "CCMP256")) { + crypto->pair_ciphers |= IWINFO_CIPHER_CCMP256; + } + + if (strstr(security, "TKIP")) { + crypto->pair_ciphers |= IWINFO_CIPHER_TKIP; + } + + if (strstr(security, "GCMP128")) { + crypto->pair_ciphers |= IWINFO_CIPHER_GCMP; + } + + if (strstr(security, "GCMP256")) { + crypto->pair_ciphers |= IWINFO_CIPHER_GCMP256; + } + } + + e->mode = IWINFO_OPMODE_MASTER; + + sscanf(pos + offsets[SCAN_DATA_CH], "%"SCNu8, &e->channel); + sscanf(pos + offsets[SCAN_DATA_RSSI], "%"SCNu8, &e->signal); + sscanf(pos + offsets[SCAN_DATA_SIG], "%"SCNu8, &e->quality); + e->quality_max = 100; + + sscanf(pos + offsets[SCAN_DATA_BSSID], "%02"SCNx8":%02"SCNx8":%02"SCNx8":%02"SCNx8":%02"SCNx8":%02"SCNx8"", + mac + 0, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5); + + sscanf(pos + offsets[SCAN_DATA_SSID_LEN], "%d", &ssid_len); + memcpy(e->ssid, pos + offsets[SCAN_DATA_SSID], ssid_len); + + *len += sizeof(struct iwinfo_scanlist_entry); + e++; + + if (index + 1 == total) + break; + } + + if (index + 1 == total) + break; + else + index++; + } + + free(data); + return 0; +} + +static double wext_freq2float(const struct iw_freq *in) +{ + int i; + double res = (double) in->m; + for(i = 0; i < in->e; i++) res *= 10; + return res; +} + +static inline int wext_freq2mhz(const struct iw_freq *in) +{ + if( in->e == 6 ) + { + return in->m; + } + else + { + return (int)(wext_freq2float(in) / 1000000); + } +} + +static int mtk_get_freqlist(const char *dev, char *buf, int *len) +{ + struct iwreq wrq; + struct iw_range range; + struct iwinfo_freqlist_entry entry; + const char* ifname; + int i, bl; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (!mtk_is_ifup(ifname)) + return -1; + + wrq.u.data.pointer = (caddr_t) ⦥ + wrq.u.data.length = sizeof(struct iw_range); + wrq.u.data.flags = 0; + + if (mtk_ioctl(ifname, SIOCGIWRANGE, &wrq) >= 0) + { + bl = 0; + + for (i = 0; i < range.num_frequency; i++) + { + entry.mhz = wext_freq2mhz(&range.freq[i]); + entry.channel = range.freq[i].i; + entry.restricted = 0; + + memcpy(&buf[bl], &entry, sizeof(struct iwinfo_freqlist_entry)); + bl += sizeof(struct iwinfo_freqlist_entry); + } + + *len = bl; + return 0; + } + + return -1; +} + +static int mtk_get_country(const char *dev, char *buf) +{ + const char *ifname; + char data[4] = {0}; + struct iwreq wrq; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + wrq.u.data.length = sizeof(data); + wrq.u.data.pointer = &data; + wrq.u.data.flags = OID_802_11_COUNTRYCODE; + + if (mtk_ioctl(ifname, RT_PRIV_IOCTL, &wrq) >= 0) + { + memcpy(buf, data, 2); + return 0; + } + return -1; +} + +static int mtk_get_countrylist(const char *dev, char *buf, int *len) +{ + int count = sizeof(mtk_country_codes)/sizeof(mtk_country_codes[0]); + struct iwinfo_country_entry *c = (struct iwinfo_country_entry *)buf; + + for (int i=0; iiso3166 = mtk_country_codes[i][0]<<8 | mtk_country_codes[i][1]; + snprintf(c->ccode, sizeof(c->ccode), "%s", mtk_country_codes[i]); + c++; + } + + *len = (count * sizeof(struct iwinfo_country_entry)); + return 0; +} + +static int mtk_get_hwmodelist(const char *dev, int *buf) +{ + const char *ifname; + char chans[IWINFO_BUFSIZE] = { 0 }; + struct iwinfo_freqlist_entry *e = NULL; + struct uci_section *s; + const char* band = NULL; + int len = 0; + + *buf = 0; + + /* get hwmode base on uci band config */ + s = iwinfo_uci_get_radio(dev, "mtwifi"); + if (!s) + goto uciout; + + band = uci_lookup_option_string(uci_ctx, s, "band"); + +uciout: + iwinfo_uci_free(); + + if (band) { + if (!strcmp(band,"2g")) + *buf = (IWINFO_80211_N | IWINFO_80211_AX); + else if (!strcmp(band,"5g")) + *buf = (IWINFO_80211_AC | IWINFO_80211_AX); + return 0; + } + + /* get hwmode base on iwrange */ + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (!mtk_get_freqlist(ifname, chans, &len)) + { + for (e = (struct iwinfo_freqlist_entry *)chans; e->channel; e++ ) + { + if (e->channel <= 14 ) //2.4Ghz + { + *buf = (IWINFO_80211_N | IWINFO_80211_AX); + } + else //5Ghz + { + *buf = (IWINFO_80211_AC | IWINFO_80211_AX); + } + } + + return 0; + } + + return -1; +} + +static int mtk_get_htmodelist(const char *dev, int *buf) +{ + const char *ifname; + char chans[IWINFO_BUFSIZE] = { 0 }; + struct iwinfo_freqlist_entry *e = NULL; + struct uci_section *s; + const char* band = NULL; + int len = 0; + + *buf = 0; + + /* get htmode base on uci band config */ + s = iwinfo_uci_get_radio(dev, "mtwifi"); + if (!s) + goto uciout; + + band = uci_lookup_option_string(uci_ctx, s, "band"); + +uciout: + iwinfo_uci_free(); + + if (band) { + if (!strcmp(band,"2g")) + *buf = (IWINFO_HTMODE_HT20 | IWINFO_HTMODE_HT40 | IWINFO_HTMODE_HE20 | IWINFO_HTMODE_HE40); + else if (!strcmp(band,"5g")) + *buf = (IWINFO_HTMODE_VHT20 | IWINFO_HTMODE_VHT40 | IWINFO_HTMODE_VHT80 | IWINFO_HTMODE_VHT160 + | IWINFO_HTMODE_HE20 | IWINFO_HTMODE_HE40 | IWINFO_HTMODE_HE80 | IWINFO_HTMODE_HE160); + return 0; + } + + /* get htmode base on iwrange */ + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (!mtk_get_freqlist(ifname, chans, &len)) + { + for (e = (struct iwinfo_freqlist_entry *)chans; e->channel; e++ ) + { + if (e->channel <= 14 ) //2.4Ghz + { + *buf = (IWINFO_HTMODE_HT20 | IWINFO_HTMODE_HT40 | IWINFO_HTMODE_HE20 | IWINFO_HTMODE_HE40); + } + else //5Ghz + { + *buf = (IWINFO_HTMODE_VHT20 | IWINFO_HTMODE_VHT40 | IWINFO_HTMODE_VHT80 | IWINFO_HTMODE_VHT160 + | IWINFO_HTMODE_HE20 | IWINFO_HTMODE_HE40 | IWINFO_HTMODE_HE80 | IWINFO_HTMODE_HE160); + } + } + + return 0; + } + + return -1; +} + +static int mtk_get_htmode(const char *dev, int *buf) +{ + const char *ifname; + struct iwreq wrq; + unsigned char bw = 0; + unsigned long wmode = 0; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (!mtk_is_ifup(ifname)) + return -1; + + wrq.u.data.length = sizeof(bw); + wrq.u.data.pointer = &bw; + wrq.u.data.flags = OID_802_11_BW; + + if (mtk_ioctl(ifname, RT_PRIV_IOCTL, &wrq) >= 0) + { + wrq.u.data.length = sizeof(wmode); + wrq.u.data.pointer = &wmode; + wrq.u.data.flags = RT_OID_802_11_PHY_MODE; + + if (mtk_ioctl(ifname, RT_PRIV_IOCTL, &wrq) >= 0) + { + if (WMODE_CAP_AX(wmode)) { + switch (bw) { + case BW_20: *buf = IWINFO_HTMODE_HE20; break; + case BW_40: *buf = IWINFO_HTMODE_HE40; break; + case BW_80: *buf = IWINFO_HTMODE_HE80; break; + case BW_8080: *buf = IWINFO_HTMODE_HE80_80; break; + case BW_160: *buf = IWINFO_HTMODE_HE160; break; + } + } else if (WMODE_CAP_AC(wmode)) { + switch (bw) { + case BW_20: *buf = IWINFO_HTMODE_VHT20; break; + case BW_40: *buf = IWINFO_HTMODE_VHT40; break; + case BW_80: *buf = IWINFO_HTMODE_VHT80; break; + case BW_8080: *buf = IWINFO_HTMODE_VHT80_80; break; + case BW_160: *buf = IWINFO_HTMODE_VHT160; break; + } + } else if (WMODE_CAP_N(wmode)) { + switch (bw) { + case BW_20: *buf = IWINFO_HTMODE_HT20; break; + case BW_40: *buf = IWINFO_HTMODE_HT40; break; + } + } else { + *buf = IWINFO_HTMODE_NOHT; + } + return 0; + } + } + + return -1; +} + +static int mtk_get_encryption(const char *dev, char *buf) +{ + const char *ifname; + struct iwreq wrq; + struct security_info secinfo; + unsigned int authMode, encryMode; + struct iwinfo_crypto_entry *c = (struct iwinfo_crypto_entry *)buf; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + if (!mtk_is_ifup(ifname)) + return -1; + + wrq.u.data.length = sizeof(secinfo); + wrq.u.data.pointer = &secinfo; + wrq.u.data.flags = OID_802_11_SECURITY_TYPE; + + if (mtk_ioctl(ifname, RT_PRIV_IOCTL, &wrq) >= 0) + { + authMode = secinfo.auth_mode; + encryMode = secinfo.encryp_type; + + c->auth_algs |= IWINFO_AUTH_OPEN; + if (IS_AKM_SHARED(authMode)) + c->auth_algs |= IWINFO_AUTH_SHARED; + + if (IS_AKM_WPA1(authMode) || IS_AKM_FT_WPA2(authMode) || IS_AKM_WPANONE(authMode) || + IS_AKM_WPA3(authMode) || IS_AKM_WPA2(authMode) || IS_AKM_WPA3_192BIT(authMode)) + c->auth_suites |= IWINFO_KMGMT_8021x; + + if (IS_AKM_WPA1PSK(authMode) || IS_AKM_WPA2PSK(authMode) || IS_AKM_FT_WPA2PSK(authMode) || + IS_AKM_WPA2PSK_SHA256(authMode)) + c->auth_suites |= IWINFO_KMGMT_PSK; + + if (IS_AKM_FT_SAE_SHA256(authMode) || IS_AKM_SAE_SHA256(authMode)) + c->auth_suites |= IWINFO_KMGMT_SAE; + + if (IS_AKM_OWE(authMode)) + c->auth_suites |= IWINFO_KMGMT_OWE; + + if (IS_AKM_WPA1(authMode) || IS_AKM_WPA1PSK(authMode)) + c->wpa_version |= 1 << 0; + + if (IS_AKM_WPA2(authMode) || IS_AKM_WPA2PSK(authMode) || IS_AKM_FT_WPA2(authMode) || + IS_AKM_FT_WPA2PSK(authMode) || IS_AKM_WPA2_SHA256(authMode) || IS_AKM_WPA2PSK_SHA256(authMode) || + IS_AKM_FT_WPA2_SHA384(authMode)) + c->wpa_version |= 1 << 1; + + if (IS_AKM_WPA3(authMode) || IS_AKM_WPA3PSK(authMode) || + IS_AKM_WPA3_192BIT(authMode) || IS_AKM_OWE(authMode)) + c->wpa_version |= 1 << 2; + + if (IS_CIPHER_NONE(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_NONE; + + if (IS_CIPHER_WEP40(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_WEP40; + + if (IS_CIPHER_WEP104(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_WEP104; + + if (IS_CIPHER_TKIP(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_TKIP; + + if (IS_CIPHER_CCMP128(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_CCMP; + + if (IS_CIPHER_GCMP128(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_GCMP; + + if (IS_CIPHER_CCMP256(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_CCMP256; + + if (IS_CIPHER_GCMP256(encryMode)) + c->pair_ciphers |= IWINFO_CIPHER_GCMP256; + + c->group_ciphers = c->pair_ciphers; + + if (IS_AKM_OPEN(authMode) && IS_CIPHER_NONE(encryMode)) + c->enabled = 0; + else + c->enabled = 1; + + return 0; + } + + return -1; +} + +static int mtk_get_phyname(const char *dev, char *buf) +{ + const char *ifname; + + ifname = mtk_dev2phy(dev); + if (!ifname) + return -1; + + strcpy(buf, ifname); + + return 0; +} + +static int mtk_get_mbssid_support(const char *dev, int *buf) +{ + *buf = 1; + return 0; +} + +static int mtk_get_l1profile_attr(const char *attr, char *data, int len) +{ + FILE *fp; + char *key, *val, buf[512]; + + fp = fopen(MTK_L1_PROFILE_PATH, "r"); + if (!fp) + return -1; + + while (fgets(buf, sizeof(buf), fp)) + { + key = strtok(buf, " =\n"); + val = strtok(NULL, "\n"); + + if (!key || !val || !*key || *key == '#') + continue; + + if (!strcmp(key, attr)) + { + //printf("l1profile key=%s, val=%s\n", key, val); + snprintf(data, len, "%s", val); + fclose(fp); + return 0; + } + } + + fclose(fp); + return -1; +} + +static int mtk_get_hardware_id_from_l1profile(struct iwinfo_hardware_id *id) +{ + const char *attr = "INDEX0"; + char buf[16] = {0}; + + if (mtk_get_l1profile_attr(attr, buf, sizeof(buf)) < 0) + return -1; + + if (!strcmp(buf, "MT7981")) { + id->vendor_id = 0x14c3; + id->device_id = 0x7981; + id->subsystem_vendor_id = id->vendor_id; + id->subsystem_device_id = id->device_id; + } else if (!strcmp(buf, "MT7986")) { + id->vendor_id = 0x14c3; + id->device_id = 0x7986; + id->subsystem_vendor_id = id->vendor_id; + id->subsystem_device_id = id->device_id; + } else { + return -1; + } + + return 0; +} + +static int mtk_get_hardware_id(const char *dev, char *buf) +{ + struct iwinfo_hardware_id *id = (struct iwinfo_hardware_id *)buf; + int ret = 0; + + memset(id, 0, sizeof(*id)); + + ret = iwinfo_hardware_id_from_mtd(id); + if (ret != 0) + ret = mtk_get_hardware_id_from_l1profile(id); + + return ret; +} + +static const struct iwinfo_hardware_entry * +mtk_get_hardware_entry(const char *dev) +{ + struct iwinfo_hardware_id id; + + if (mtk_get_hardware_id(dev, (char *)&id)) + return NULL; + + return iwinfo_hardware(&id); +} + +static int mtk_get_hardware_name(const char *dev, char *buf) +{ + const struct iwinfo_hardware_entry *hw; + + if (!(hw = mtk_get_hardware_entry(dev))) + sprintf(buf, "%s", "MediaTek"); + else + sprintf(buf, "%s %s", hw->vendor_name, hw->device_name); + + return 0; +} + +static int mtk_get_txpower_offset(const char *dev, int *buf) +{ + /* Stub */ + *buf = 0; + return -1; +} + +static int mtk_get_frequency_offset(const char *dev, int *buf) +{ + /* Stub */ + *buf = 0; + return -1; +} + +const struct iwinfo_ops mtk_ops = { + .name = "mtk", + .probe = mtk_probe, + .channel = mtk_get_channel, + .center_chan1 = mtk_get_center_chan1, + .center_chan2 = mtk_get_center_chan2, + .frequency = mtk_get_frequency, + .frequency_offset = mtk_get_frequency_offset, + .txpower = mtk_get_txpower, + .txpower_offset = mtk_get_txpower_offset, + .bitrate = mtk_get_bitrate, + .signal = mtk_get_signal, + .noise = mtk_get_noise, + .quality = mtk_get_quality, + .quality_max = mtk_get_quality_max, + .mbssid_support = mtk_get_mbssid_support, + .hwmodelist = mtk_get_hwmodelist, + .htmodelist = mtk_get_htmodelist, + .htmode = mtk_get_htmode, + .mode = mtk_get_mode, + .ssid = mtk_get_ssid, + .bssid = mtk_get_bssid, + .country = mtk_get_country, + .countrylist = mtk_get_countrylist, + .hardware_id = mtk_get_hardware_id, + .hardware_name = mtk_get_hardware_name, + .encryption = mtk_get_encryption, + .phyname = mtk_get_phyname, + .assoclist = mtk_get_assoclist, + .txpwrlist = mtk_get_txpwrlist, + .scanlist = mtk_get_scanlist, + .freqlist = mtk_get_freqlist, + .close = mtk_close, +}; diff --git a/package/utils/iwinfo/src/iwinfo_mtk_ccode.c b/package/utils/iwinfo/src/iwinfo_mtk_ccode.c new file mode 100644 index 0000000000..3e875e8375 --- /dev/null +++ b/package/utils/iwinfo/src/iwinfo_mtk_ccode.c @@ -0,0 +1,103 @@ +static const char *mtk_country_codes[] = { +// "DB", + "AE", + "AL", + "AR", + "AT", + "AM", + "AU", + "AZ", + "BE", + "BH", + "BY", + "BO", + "BR", + "BN", + "BG", + "BZ", + "CA", + "CH", + "CL", + "CN", + "CO", + "CR", + "CY", + "CZ", + "DE", + "DK", + "DO", + "DZ", + "EC", + "EG", + "EE", + "ES", + "FI", + "FR", + "GE", + "GB", + "GR", + "GT", + "HN", + "HK", + "HU", + "HR", + "IS", + "IN", + "ID", + "IR", + "IE", + "IL", + "IT", + "JP", + "JO", + "KP", + "KR", + "KW", + "KZ", + "LB", + "LI", + "LT", + "LU", + "LV", + "MA", + "MC", + "MO", + "MK", + "MX", + "MY", + "NL", + "NO", + "NZ", + "OM", + "PA", + "PE", + "PH", + "PL", + "PK", + "PT", + "PR", + "QA", + "RO", + "RU", + "SA", + "SG", + "SK", + "SI", + "SV", + "SE", + "SY", + "TH", + "TN", + "TR", + "TT", + "TW", + "UA", + "US", + "UY", + "UZ", + "VE", + "VN", + "YE", + "ZA", + "ZW", +}; diff --git a/package/utils/iwinfo/src/iwinfo_mtk_rate.c b/package/utils/iwinfo/src/iwinfo_mtk_rate.c new file mode 100644 index 0000000000..b6f42acc19 --- /dev/null +++ b/package/utils/iwinfo/src/iwinfo_mtk_rate.c @@ -0,0 +1,479 @@ +#include "mtwifi.h" + +#define MAX_NUM_HE_BANDWIDTHS 4 +#define MAX_NUM_HE_SPATIAL_STREAMS 4 +#define MAX_NUM_HE_MCS_ENTRIES 12 + +UINT32 cck_to_mcs(UINT32 mcs) { + UINT32 ret = 0; + if (mcs == TMI_TX_RATE_CCK_1M_LP) + ret = 0; + else if (mcs == TMI_TX_RATE_CCK_2M_LP) + ret = 1; + else if (mcs == TMI_TX_RATE_CCK_5M_LP) + ret = 2; + else if (mcs == TMI_TX_RATE_CCK_11M_LP) + ret = 3; + else if (mcs == TMI_TX_RATE_CCK_2M_SP) + ret = 1; + else if (mcs == TMI_TX_RATE_CCK_5M_SP) + ret = 2; + else if (mcs == TMI_TX_RATE_CCK_11M_SP) + ret = 3; + + return ret; +} + +static UINT16 he_mcs_phyrate_mapping_table[MAX_NUM_HE_BANDWIDTHS][MAX_NUM_HE_SPATIAL_STREAMS][MAX_NUM_HE_MCS_ENTRIES] = { + { /*20 Mhz*/ + /* 1 SS */ + { + /* DCM 0*/ + 8, + 17, + 25, + 34, + 51, + 68, + 77, + 86, + 103, + 114, + 129, + 143 + }, + /* 2 SS */ + { + /* DCM 0 */ + 17, + 34, + 51, + 68, + 103, + 137, + 154, + 172, + 206, + 229, + 258, + 286 + }, + /* 3 SS */ + { + /* DCM 0 */ + 25, + 51, + 77, + 103, + 154, + 206, + 232, + 258, + 309, + 344, + 387, + 430 + }, + /* 4 SS */ + { + /* DCM 0 */ + 34, + 68, + 103, + 137, + 206, + 275, + 309, + 344, + 412, + 458, + 516, + 573 + } + }, + { /*40 Mhz*/ + /* 1 SS */ + { + /* DCM 0*/ + 17, + 34, + 51, + 68, + 103, + 137, + 154, + 172, + 206, + 229, + 258, + 286 + }, + /* 2 SS */ + { + /* DCM 0 */ + 34, + 68, + 103, + 137, + 206, + 275, + 309, + 344, + 412, + 458, + 516, + 573 + + }, + /* 3 SS */ + { + /* DCM 0 */ + 51, + 103, + 154, + 206, + 309, + 412, + 464, + 516, + 619, + 688, + 774, + 860 + + }, + /* 4 SS */ + { + /* DCM 0 */ + 68, + 137, + 206, + 275, + 412, + 550, + 619, + 688, + 825, + 917, + 1032, + 1147 + } + }, + { /*80 Mhz*/ + /* 1 SS */ + { + /* DCM 0*/ + 36, + 72, + 108, + 144, + 216, + 288, + 324, + 360, + 432, + 480, + 540, + 600 + }, + /* 2 SS */ + { + /* DCM 0 */ + 72, + 144, + 216, + 288, + 432, + 576, + 648, + 720, + 864, + 960, + 1080, + 1201 + }, + /* 3 SS */ + { + /* DCM 0 */ + 108, + 216, + 324, + 432, + 648, + 864, + 972, + 1080, + 1297, + 1441, + 1621, + 1801 + }, + /* 4 SS */ + { + /* DCM 0 */ + 144, + 288, + 432, + 576, + 864, + 1152, + 1297, + 1141, + 1729, + 1921, + 2161, + 2401 + } + }, + { /*160 Mhz*/ + /* 1 SS */ + { + /* DCM 0*/ + 72, + 144, + 216, + 288, + 432, + 576, + 648, + 720, + 864, + 960, + 1080, + 1201 + }, + /* 2 SS */ + { + /* DCM 0 */ + 144, + 288, + 432, + 576, + 864, + 1152, + 1297, + 1441, + 1729, + 1921, + 2161, + 2401 + }, + /* 3 SS */ + { + /* DCM 0 */ + 216, + 432, + 648, + 864, + 1297, + 1729, + 1945, + 2161, + 2594, + 2882, + 3242, + 3602 + }, + /* 4 SS */ + { + /* DCM 0 */ + 288, + 576, + 864, + 1152, + 1729, + 2305, + 2594, + 2882, + 3458, + 3843, + 4323, + 4803 + }, + } + +}; + +void get_rate_he(UINT8 mcs, UINT8 bw, UINT8 nss, UINT8 dcm, ULONG *last_tx_rate) +{ + ULONG value = 0; + + if (nss == 0) + nss = 1; + + if (mcs >= MAX_NUM_HE_MCS_ENTRIES) + mcs = MAX_NUM_HE_MCS_ENTRIES - 1; + + if (nss > MAX_NUM_HE_SPATIAL_STREAMS) + nss = MAX_NUM_HE_SPATIAL_STREAMS; + + if (bw >= MAX_NUM_HE_BANDWIDTHS) + bw = MAX_NUM_HE_BANDWIDTHS - 1; + + nss--; + + value = he_mcs_phyrate_mapping_table[bw][nss][mcs]; + /*In spec data rate when DCM =1 is half of the data rate when DCM = 0*/ + if (dcm && value) + value = value / 2 ; + + *last_tx_rate = (ULONG)value; + + return; +} + +static INT32 getLegacyOFDMMCSIndex(UINT8 MCS) +{ + INT32 mcs_index = MCS; + + if (MCS == 0xb) + mcs_index = 0; + else if (MCS == 0xf) + mcs_index = 1; + else if (MCS == 0xa) + mcs_index = 2; + else if (MCS == 0xe) + mcs_index = 3; + else if (MCS == 0x9) + mcs_index = 4; + else if (MCS == 0xd) + mcs_index = 5; + else if (MCS == 0x8) + mcs_index = 6; + else if (MCS == 0xc) + mcs_index = 7; + + return mcs_index; +} + +static INT MCSMappingRateTable[] = { + 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112,/* CCK and OFDM */ + 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, + 39, 78, 117, 156, 234, 312, 351, 390, /* BW 20, 800ns GI, MCS 0~23 */ + 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, + 81, 162, 243, 324, 486, 648, 729, 810, /* BW 40, 800ns GI, MCS 0~23 */ + 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, + 43, 87, 130, 173, 260, 317, 390, 433, /* BW 20, 400ns GI, MCS 0~23 */ + 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, + 90, 180, 270, 360, 540, 720, 810, 900, /* BW 40, 400ns GI, MCS 0~23 */ + + /*for 11ac:20 Mhz 800ns GI*/ + 6, 13, 19, 26, 39, 52, 58, 65, 78, 90, /*1ss mcs 0~8*/ + 13, 26, 39, 52, 78, 104, 117, 130, 156, 180, /*2ss mcs 0~8*/ + 19, 39, 58, 78, 117, 156, 175, 195, 234, 260, /*3ss mcs 0~9*/ + 26, 52, 78, 104, 156, 208, 234, 260, 312, 360, /*4ss mcs 0~8*/ + + /*for 11ac:40 Mhz 800ns GI*/ + 13, 27, 40, 54, 81, 108, 121, 135, 162, 180, /*1ss mcs 0~9*/ + 27, 54, 81, 108, 162, 216, 243, 270, 324, 360, /*2ss mcs 0~9*/ + 40, 81, 121, 162, 243, 324, 364, 405, 486, 540, /*3ss mcs 0~9*/ + 54, 108, 162, 216, 324, 432, 486, 540, 648, 720, /*4ss mcs 0~9*/ + + /*for 11ac:80 Mhz 800ns GI*/ + 29, 58, 87, 117, 175, 234, 263, 292, 351, 390, /*1ss mcs 0~9*/ + 58, 117, 175, 243, 351, 468, 526, 585, 702, 780, /*2ss mcs 0~9*/ + 87, 175, 263, 351, 526, 702, 0, 877, 1053, 1170, /*3ss mcs 0~9*/ + 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, /*4ss mcs 0~9*/ + + /*for 11ac:160 Mhz 800ns GI*/ + 58, 117, 175, 234, 351, 468, 526, 585, 702, 780, /*1ss mcs 0~9*/ + 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, /*2ss mcs 0~9*/ + 175, 351, 526, 702, 1053, 1404, 1579, 1755, 2160, 0, /*3ss mcs 0~8*/ + 234, 468, 702, 936, 1404, 1872, 2106, 2340, 2808, 3120, /*4ss mcs 0~9*/ + + /*for 11ac:20 Mhz 400ns GI*/ + 7, 14, 21, 28, 43, 57, 65, 72, 86, 100, /*1ss mcs 0~8*/ + 14, 28, 43, 57, 86, 115, 130, 144, 173, 200, /*2ss mcs 0~8*/ + 21, 43, 65, 86, 130, 173, 195, 216, 260, 288, /*3ss mcs 0~9*/ + 28, 57, 86, 115, 173, 231, 260, 288, 346, 400, /*4ss mcs 0~8*/ + + /*for 11ac:40 Mhz 400ns GI*/ + 15, 30, 45, 60, 90, 120, 135, 150, 180, 200, /*1ss mcs 0~9*/ + 30, 60, 90, 120, 180, 240, 270, 300, 360, 400, /*2ss mcs 0~9*/ + 45, 90, 135, 180, 270, 360, 405, 450, 540, 600, /*3ss mcs 0~9*/ + 60, 120, 180, 240, 360, 480, 540, 600, 720, 800, /*4ss mcs 0~9*/ + + /*for 11ac:80 Mhz 400ns GI*/ + 32, 65, 97, 130, 195, 260, 292, 325, 390, 433, /*1ss mcs 0~9*/ + 65, 130, 195, 260, 390, 520, 585, 650, 780, 866, /*2ss mcs 0~9*/ + 97, 195, 292, 390, 585, 780, 0, 975, 1170, 1300, /*3ss mcs 0~9*/ + 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1733, /*4ss mcs 0~9*/ + + /*for 11ac:160 Mhz 400ns GI*/ + 65, 130, 195, 260, 390, 520, 585, 650, 780, 866, /*1ss mcs 0~9*/ + 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1733, /*2ss mcs 0~9*/ + 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 0, /*3ss mcs 0~8*/ + 260, 520, 780, 1040, 1560, 2080, 2340, 2600, 3120, 3466, /*4ss mcs 0~9*/ + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 +}; /* 3*3 */ + + +void getRate(HTTRANSMIT_SETTING HTSetting, ULONG *fLastTxRxRate) +{ + UINT8 Antenna = 0; + UINT8 MCS = HTSetting.field.MCS; + int rate_count = sizeof(MCSMappingRateTable) / sizeof(int); + int rate_index = 0; + int value = 0; + + if (HTSetting.field.MODE >= MODE_VHT) { + MCS = HTSetting.field.MCS & 0xf; + Antenna = (HTSetting.field.MCS >> 4) + 1; + + if (HTSetting.field.BW == BW_20) { + rate_index = 112 + ((Antenna - 1) * 10) + + ((UCHAR)HTSetting.field.ShortGI * 160) + + ((UCHAR)MCS); + } else if (HTSetting.field.BW == BW_40) { + rate_index = 152 + ((Antenna - 1) * 10) + + ((UCHAR)HTSetting.field.ShortGI * 160) + + ((UCHAR)MCS); + } else if (HTSetting.field.BW == BW_80) { + rate_index = 192 + ((Antenna - 1) * 10) + + ((UCHAR)HTSetting.field.ShortGI * 160) + + ((UCHAR)MCS); + } else if (HTSetting.field.BW == BW_160) { + rate_index = 232 + ((Antenna - 1) * 10) + + ((UCHAR)HTSetting.field.ShortGI * 160) + + ((UCHAR)MCS); + } + } else { + if (HTSetting.field.MODE >= MODE_HTMIX) { + MCS = HTSetting.field.MCS; + + if ((HTSetting.field.MODE == MODE_HTMIX) + || (HTSetting.field.MODE == MODE_HTGREENFIELD)) + Antenna = (MCS >> 3) + 1; + + /* map back to 1SS MCS , multiply by antenna numbers later */ + if (MCS > 7) + MCS %= 8; + + rate_index = 16 + ((UCHAR)HTSetting.field.BW * 24) + ((UCHAR)HTSetting.field.ShortGI * 48) + ((UCHAR)MCS); + } else { + if (HTSetting.field.MODE == MODE_OFDM) + rate_index = getLegacyOFDMMCSIndex(HTSetting.field.MCS) + 4; + else if (HTSetting.field.MODE == MODE_CCK) + rate_index = (UCHAR)(HTSetting.field.MCS); + } + } + + if (rate_index < 0) + rate_index = 0; + + if (rate_index >= rate_count) + rate_index = rate_count - 1; + + if (HTSetting.field.MODE < MODE_VHT) + value = (MCSMappingRateTable[rate_index] * 5) / 10; + else + value = MCSMappingRateTable[rate_index]; + + if (HTSetting.field.MODE >= MODE_HTMIX && HTSetting.field.MODE < MODE_VHT) + value *= Antenna; + + *fLastTxRxRate = (ULONG)value; + return; +} diff --git a/package/utils/iwinfo/src/mtwifi.h b/package/utils/iwinfo/src/mtwifi.h new file mode 100644 index 0000000000..cb8ff4cff4 --- /dev/null +++ b/package/utils/iwinfo/src/mtwifi.h @@ -0,0 +1,268 @@ +#ifndef __MTWIFI_H +#define __MTWIFI_H + +#define USHORT unsigned short +#define UCHAR unsigned char +#define ULONG unsigned long +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned int +#define INT32 int +#define INT int + +typedef union _HTTRANSMIT_SETTING_FIX { + struct { + unsigned short MCS:6; + unsigned short ldpc:1; + unsigned short BW:2; + unsigned short ShortGI:2; + unsigned short STBC:1; + unsigned short eTxBF:1; + unsigned short iTxBF:1; + unsigned short MODE:4; + } field; + unsigned int word; +} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING; + +typedef struct _RT_802_11_MAC_ENTRY_FIX { + unsigned char ApIdx; + unsigned char Addr[6]; + unsigned short Aid; + unsigned char Psm; + unsigned char MimoPs; + signed char AvgRssi0; + signed char AvgRssi1; + signed char AvgRssi2; + signed char AvgRssi3; + unsigned int ConnectedTime; + HTTRANSMIT_SETTING TxRate; + HTTRANSMIT_SETTING LastRxRate; + short StreamSnr[3]; + short SoundingRespSnr[3]; + unsigned int EncryMode; + unsigned int AuthMode; +} RT_802_11_MAC_ENTRY; + +#define MAX_NUMBER_OF_MAC 544 + +typedef struct _RT_802_11_MAC_TABLE_FIX { + unsigned long Num; + RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC]; +} RT_802_11_MAC_TABLE; + +#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x01) +#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02) +#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07) +#define RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT (SIOCIWFIRSTPRIV + 0x1F) +#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11) +#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) +#define RTPRIV_IOCTL_PHY_STATE (SIOCIWFIRSTPRIV + 0x21) +#define RTPRIV_IOCTL_GET_DRIVER_INFO (SIOCIWFIRSTPRIV + 0x1D) +#define OID_802_11_COUNTRYCODE 0x1907 +#define OID_802_11_BW 0x1903 +#define OID_GET_CHAN_LIST 0x0998 +#define OID_GET_WIRELESS_BAND 0x09B4 +#define OID_802_11_SECURITY_TYPE 0x093e +#define RT_OID_802_11_PHY_MODE 0x050C +#define GET_MAC_TABLE_STRUCT_FLAG_RAW_SSID 0x1 + +#define MODE_CCK 0 +#define MODE_OFDM 1 +#define MODE_HTMIX 2 +#define MODE_HTGREENFIELD 3 +#define MODE_VHT 4 +#define MODE_HE 5 +#define MODE_HE_5G 6 +#define MODE_HE_24G 7 +#define MODE_HE_SU 8 +#define MODE_HE_EXT_SU 9 +#define MODE_HE_TRIG 10 +#define MODE_HE_MU 11 + +#define TMI_TX_RATE_OFDM_6M 11 +#define TMI_TX_RATE_OFDM_9M 15 +#define TMI_TX_RATE_OFDM_12M 10 +#define TMI_TX_RATE_OFDM_18M 14 +#define TMI_TX_RATE_OFDM_24M 9 +#define TMI_TX_RATE_OFDM_36M 13 +#define TMI_TX_RATE_OFDM_48M 8 +#define TMI_TX_RATE_OFDM_54M 12 + +#define TMI_TX_RATE_CCK_1M_LP 0 +#define TMI_TX_RATE_CCK_2M_LP 1 +#define TMI_TX_RATE_CCK_5M_LP 2 +#define TMI_TX_RATE_CCK_11M_LP 3 + +#define TMI_TX_RATE_CCK_2M_SP 5 +#define TMI_TX_RATE_CCK_5M_SP 6 +#define TMI_TX_RATE_CCK_11M_SP 7 + +enum oid_bw { + BAND_WIDTH_20, + BAND_WIDTH_40, + BAND_WIDTH_80, + BAND_WIDTH_160, + BAND_WIDTH_10, + BAND_WIDTH_5, + BAND_WIDTH_8080, + BAND_WIDTH_BOTH, + BAND_WIDTH_25, + BAND_WIDTH_20_242TONE, + BAND_WIDTH_NUM +}; + +#define BW_20 BAND_WIDTH_20 +#define BW_40 BAND_WIDTH_40 +#define BW_80 BAND_WIDTH_80 +#define BW_160 BAND_WIDTH_160 +#define BW_10 BAND_WIDTH_10 +#define BW_5 BAND_WIDTH_5 +#define BW_8080 BAND_WIDTH_8080 +#define BW_25 BAND_WIDTH_25 +#define BW_20_242TONE BAND_WIDTH_20_242TONE +#define BW_NUM BAND_WIDTH_NUM + +enum WIFI_MODE { + WMODE_INVALID = 0, + WMODE_A = 1 << 0, + WMODE_B = 1 << 1, + WMODE_G = 1 << 2, + WMODE_GN = 1 << 3, + WMODE_AN = 1 << 4, + WMODE_AC = 1 << 5, + WMODE_AX_24G = 1 << 6, + WMODE_AX_5G = 1 << 7, + WMODE_AX_6G = 1 << 8, + WMODE_COMP = 9, +}; + +#define WMODE_CAP_N(_x) (((_x) & (WMODE_GN | WMODE_AN)) != 0) +#define WMODE_CAP_AC(_x) (((_x) & (WMODE_AC)) != 0) +#define WMODE_CAP_AX(_x) ((_x) & (WMODE_AX_24G | WMODE_AX_5G | WMODE_AX_6G)) + +enum MTK_CH_BAND { + MTK_CH_BAND_24G = 0, + MTK_CH_BAND_5G = 1, + MTK_CH_BAND_6G = 2, +}; + +#define MAX_NUM_OF_CHANNELS 59 + +struct __attribute__ ((packed)) chnList { + unsigned char channel; + unsigned char pref; + unsigned short cac_timer; +}; + +typedef struct __attribute__ ((packed)) _wdev_chn_info { + unsigned char op_ch; + unsigned char op_class; + unsigned short band; + unsigned char ch_list_num; + unsigned char non_op_chn_num; + unsigned short dl_mcs; + struct chnList ch_list[32]; + unsigned char non_op_ch_list[32]; + unsigned char AutoChannelSkipListNum; + unsigned char AutoChannelSkipList[MAX_NUM_OF_CHANNELS + 1]; +} wdev_chn_info; + +struct security_info { + unsigned int ifindex; + unsigned int auth_mode; + unsigned int encryp_type; +}; + +typedef enum _SEC_CIPHER_MODE { + SEC_CIPHER_NONE, + SEC_CIPHER_WEP40, + SEC_CIPHER_WEP104, + SEC_CIPHER_WEP128, + SEC_CIPHER_TKIP, + SEC_CIPHER_CCMP128, + SEC_CIPHER_CCMP256, + SEC_CIPHER_GCMP128, + SEC_CIPHER_GCMP256, + SEC_CIPHER_BIP_CMAC128, + SEC_CIPHER_BIP_CMAC256, + SEC_CIPHER_BIP_GMAC128, + SEC_CIPHER_BIP_GMAC256, + SEC_CIPHER_WPI_SMS4, /* WPI SMS4 support */ + SEC_CIPHER_MAX /* Not a real mode, defined as upper bound */ +} SEC_CIPHER_MODE; + +#define IS_CIPHER_NONE(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_NONE)) > 0) +#define IS_CIPHER_WEP40(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_WEP40)) > 0) +#define IS_CIPHER_WEP104(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_WEP104)) > 0) +#define IS_CIPHER_WEP128(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_WEP128)) > 0) +#define IS_CIPHER_WEP(_Cipher) (((_Cipher) & ((1 << SEC_CIPHER_WEP40) | (1 << SEC_CIPHER_WEP104) | (1 << SEC_CIPHER_WEP128))) > 0) +#define IS_CIPHER_TKIP(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_TKIP)) > 0) +#define IS_CIPHER_WEP_TKIP_ONLY(_Cipher) ((IS_CIPHER_WEP(_Cipher) || IS_CIPHER_TKIP(_Cipher)) && (_Cipher < (1 << SEC_CIPHER_CCMP128))) +#define IS_CIPHER_CCMP128(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_CCMP128)) > 0) +#define IS_CIPHER_CCMP256(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_CCMP256)) > 0) +#define IS_CIPHER_GCMP128(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_GCMP128)) > 0) +#define IS_CIPHER_GCMP256(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_GCMP256)) > 0) +#define IS_CIPHER_BIP_CMAC128(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_BIP_CMAC128)) > 0) +#define IS_CIPHER_BIP_CMAC256(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_BIP_CMAC256)) > 0) +#define IS_CIPHER_BIP_GMAC128(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_BIP_GMAC128)) > 0) +#define IS_CIPHER_BIP_GMAC256(_Cipher) (((_Cipher) & (1 << SEC_CIPHER_BIP_GMAC256)) > 0) + +/* 802.11 authentication and key management */ +typedef enum _SEC_AKM_MODE { + SEC_AKM_OPEN, + SEC_AKM_SHARED, + SEC_AKM_AUTOSWITCH, + SEC_AKM_WPA1, /* Enterprise security over 802.1x */ + SEC_AKM_WPA1PSK, + SEC_AKM_WPANone, /* For Win IBSS, directly PTK, no handshark */ + SEC_AKM_WPA2, /* Enterprise security over 802.1x */ + SEC_AKM_WPA2PSK, + SEC_AKM_FT_WPA2, + SEC_AKM_FT_WPA2PSK, + SEC_AKM_WPA2_SHA256, + SEC_AKM_WPA2PSK_SHA256, + SEC_AKM_TDLS, + SEC_AKM_SAE_SHA256, + SEC_AKM_FT_SAE_SHA256, + SEC_AKM_SUITEB_SHA256, + SEC_AKM_SUITEB_SHA384, + SEC_AKM_FT_WPA2_SHA384, + SEC_AKM_WAICERT, /* WAI certificate authentication */ + SEC_AKM_WAIPSK, /* WAI pre-shared key */ + SEC_AKM_OWE, + SEC_AKM_FILS_SHA256, + SEC_AKM_FILS_SHA384, + SEC_AKM_WPA3, /* WPA3(ent) = WPA2(ent) + PMF MFPR=1 => WPA3 code flow is same as WPA2, the usage of SEC_AKM_WPA3 is to force pmf on */ + SEC_AKM_MAX /* Not a real mode, defined as upper bound */ +} SEC_AKM_MODE; + +#define IS_AKM_OPEN(_AKMMap) ((_AKMMap & (1 << SEC_AKM_OPEN)) > 0) +#define IS_AKM_SHARED(_AKMMap) ((_AKMMap & (1 << SEC_AKM_SHARED)) > 0) +#define IS_AKM_AUTOSWITCH(_AKMMap) ((_AKMMap & (1 << SEC_AKM_AUTOSWITCH)) > 0) +#define IS_AKM_WPA1(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA1)) > 0) +#define IS_AKM_WPA1PSK(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA1PSK)) > 0) +#define IS_AKM_WPANONE(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPANone)) > 0) +#define IS_AKM_WPA2(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA2)) > 0) +#define IS_AKM_WPA2PSK(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA2PSK)) > 0) +#define IS_AKM_FT_WPA2(_AKMMap) ((_AKMMap & (1 << SEC_AKM_FT_WPA2)) > 0) +#define IS_AKM_FT_WPA2PSK(_AKMMap) ((_AKMMap & (1 << SEC_AKM_FT_WPA2PSK)) > 0) +#define IS_AKM_WPA2_SHA256(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA2_SHA256)) > 0) +#define IS_AKM_WPA2PSK_SHA256(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA2PSK_SHA256)) > 0) +#define IS_AKM_TDLS(_AKMMap) ((_AKMMap & (1 << SEC_AKM_TDLS)) > 0) +#define IS_AKM_SAE_SHA256(_AKMMap) ((_AKMMap & (1 << SEC_AKM_SAE_SHA256)) > 0) +#define IS_AKM_FT_SAE_SHA256(_AKMMap) ((_AKMMap & (1 << SEC_AKM_FT_SAE_SHA256)) > 0) +#define IS_AKM_SUITEB_SHA256(_AKMMap) ((_AKMMap & (1 << SEC_AKM_SUITEB_SHA256)) > 0) +#define IS_AKM_SUITEB_SHA384(_AKMMap) ((_AKMMap & (1 << SEC_AKM_SUITEB_SHA384)) > 0) +#define IS_AKM_FT_WPA2_SHA384(_AKMMap) ((_AKMMap & (1 << SEC_AKM_FT_WPA2_SHA384)) > 0) +#define IS_AKM_WPA3(_AKMMap) ((_AKMMap & (1 << SEC_AKM_WPA3)) > 0) +#define IS_AKM_WPA3PSK(_AKMMap) (IS_AKM_SAE_SHA256(_AKMMap)) +#define IS_AKM_WPA3_192BIT(_AKMMap) (IS_AKM_SUITEB_SHA384(_AKMMap)) +#define IS_AKM_OWE(_AKMMap) ((_AKMMap & (1 << SEC_AKM_OWE)) > 0) + +#define MTK_L1_PROFILE_PATH "/etc/wireless/l1profile.dat" + +void getRate(HTTRANSMIT_SETTING HTSetting, ULONG *fLastTxRxRate); +void get_rate_he(UINT8 mcs, UINT8 bw, UINT8 nss, UINT8 dcm, ULONG *last_tx_rate); +UINT32 cck_to_mcs(UINT32 mcs); + +#endif