From 59ab5b73fae85371eeb32f6431caccd9f9139838 Mon Sep 17 00:00:00 2001 From: hanwckf Date: Fri, 13 Sep 2024 21:15:40 +0800 Subject: [PATCH] iwinfo: add support for mtk l1util lua script --- package/network/utils/iwinfo/Makefile | 2 +- .../iwinfo/patches/0002-support-mt798x.patch | 6 +- .../patches/0003-support-lua-link.patch | 11 ++ .../0004-return-err-for-dev2-eeprom.patch | 30 +++ package/network/utils/iwinfo/src/iwinfo_mtk.c | 61 +----- .../utils/iwinfo/src/iwinfo_mtk_l1util.c | 176 ++++++++++++++++++ package/network/utils/iwinfo/src/mtwifi.h | 6 + 7 files changed, 233 insertions(+), 59 deletions(-) create mode 100644 package/network/utils/iwinfo/patches/0003-support-lua-link.patch create mode 100644 package/network/utils/iwinfo/patches/0004-return-err-for-dev2-eeprom.patch create mode 100644 package/network/utils/iwinfo/src/iwinfo_mtk_l1util.c diff --git a/package/network/utils/iwinfo/Makefile b/package/network/utils/iwinfo/Makefile index e6a433e508..ed03123aa5 100644 --- a/package/network/utils/iwinfo/Makefile +++ b/package/network/utils/iwinfo/Makefile @@ -26,7 +26,7 @@ define Package/libiwinfo SECTION:=libs CATEGORY:=Libraries TITLE:=Generalized Wireless Information Library (iwinfo) - DEPENDS:=+libnl-tiny +libuci +libubus +libiwinfo-data + DEPENDS:=+libnl-tiny +libuci +libubus +libiwinfo-data +liblua ABI_VERSION:=$(IWINFO_ABI_VERSION) endef diff --git a/package/network/utils/iwinfo/patches/0002-support-mt798x.patch b/package/network/utils/iwinfo/patches/0002-support-mt798x.patch index e1dc163393..a9633e3767 100644 --- a/package/network/utils/iwinfo/patches/0002-support-mt798x.patch +++ b/package/network/utils/iwinfo/patches/0002-support-mt798x.patch @@ -6,7 +6,7 @@ +ifneq ($(filter mtk,$(IWINFO_BACKENDS)),) + IWINFO_CFLAGS += -DUSE_MTK -+ IWINFO_LIB_OBJ += iwinfo_mtk.o iwinfo_mtk_rate.o ++ IWINFO_LIB_OBJ += iwinfo_mtk.o iwinfo_mtk_rate.o iwinfo_mtk_l1util.o +endif + ifneq ($(filter nl80211,$(IWINFO_BACKENDS)),) @@ -141,9 +141,11 @@ luaL_register(L, NULL, R_common); --- a/devices.txt +++ b/devices.txt -@@ -197,6 +197,7 @@ +@@ -196,7 +196,9 @@ + 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 0x7916 0x14c3 0x7916 0 0 "MediaTek" "MT7916" 0x14c3 0x7986 0x14c3 0x7986 0 0 "MediaTek" "MT7986" +0x14c3 0x7981 0x14c3 0x7981 0 0 "MediaTek" "MT7981" 0x14e4 0xaa52 0x14e4 0xaa52 0 0 "Broadcom" "BCM43602" diff --git a/package/network/utils/iwinfo/patches/0003-support-lua-link.patch b/package/network/utils/iwinfo/patches/0003-support-lua-link.patch new file mode 100644 index 0000000000..388bb434ad --- /dev/null +++ b/package/network/utils/iwinfo/patches/0003-support-lua-link.patch @@ -0,0 +1,11 @@ +--- a/Makefile ++++ b/Makefile +@@ -5,7 +5,7 @@ IWINFO_CFLAGS = $(CFLAGS) -std=gnu9 + IWINFO_LDFLAGS = -luci -lubox -lubus + + IWINFO_LIB = libiwinfo.so +-IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared -Wl,-soname -Wl,$(IWINFO_LIB).$(IWINFO_SOVERSION) ++IWINFO_LIB_LDFLAGS = $(LDFLAGS) -shared -llua -Wl,-soname -Wl,$(IWINFO_LIB).$(IWINFO_SOVERSION) + IWINFO_LIB_OBJ = iwinfo_utils.o iwinfo_lib.o + + IWINFO_LUA = iwinfo.so diff --git a/package/network/utils/iwinfo/patches/0004-return-err-for-dev2-eeprom.patch b/package/network/utils/iwinfo/patches/0004-return-err-for-dev2-eeprom.patch new file mode 100644 index 0000000000..9d80b023b7 --- /dev/null +++ b/package/network/utils/iwinfo/patches/0004-return-err-for-dev2-eeprom.patch @@ -0,0 +1,30 @@ +--- a/iwinfo_utils.c ++++ b/iwinfo_utils.c +@@ -213,6 +213,16 @@ int iwinfo_hardware_id_from_mtd(struct i + if (ident == 0x7981 || ident == 0x7986 + || ident == 0x8179 || ident == 0x8679) + { ++ uint16_t ident_zone2 = 0; ++ if (len > 0xa0002 && ++ lseek(fd, 0xa0000, SEEK_SET) != -1 && ++ read(fd, &ident_zone2, sizeof(ident_zone2)) != -1) ++ { ++ if (ident_zone2 != 0xFFFF && ident_zone2 != 0x0) { ++ close(fd); ++ return -1; ++ } ++ } + if ((ident & 0xff) == 0x79) + id->device_id = (ident >> 8) | (ident & 0x00ff) << 8; + else +@@ -222,6 +232,10 @@ int iwinfo_hardware_id_from_mtd(struct i + id->subsystem_device_id = id->device_id; + close(fd); + return 0; ++ } else if (ident == 0xffff || ident == 0x0) { ++ /* eeprom invalid */ ++ close(fd); ++ return -1; + } + } + lseek(fd, 0, SEEK_SET); diff --git a/package/network/utils/iwinfo/src/iwinfo_mtk.c b/package/network/utils/iwinfo/src/iwinfo_mtk.c index 39358dfd6d..c47338e3c1 100644 --- a/package/network/utils/iwinfo/src/iwinfo_mtk.c +++ b/package/network/utils/iwinfo/src/iwinfo_mtk.c @@ -962,61 +962,6 @@ static int mtk_get_mbssid_support(const char *dev, int *buf) 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; @@ -1025,8 +970,12 @@ static int mtk_get_hardware_id(const char *dev, char *buf) memset(id, 0, sizeof(*id)); ret = iwinfo_hardware_id_from_mtd(id); + if (ret != 0) - ret = mtk_get_hardware_id_from_l1profile(id); + ret = mtk_get_id_by_l1util(dev, id); + + if (ret != 0) + ret = mtk_get_id_from_l1profile(id); return ret; } diff --git a/package/network/utils/iwinfo/src/iwinfo_mtk_l1util.c b/package/network/utils/iwinfo/src/iwinfo_mtk_l1util.c new file mode 100644 index 0000000000..5db4838ce0 --- /dev/null +++ b/package/network/utils/iwinfo/src/iwinfo_mtk_l1util.c @@ -0,0 +1,176 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include "iwinfo.h" +#include "mtwifi.h" + +static char luacmd[500]; + +static const char dev2chip[] = + "local l1parser = require 'l1util'\n" + "local l1dat = l1parser.load_l1_profile(l1parser.L1_DAT_PATH)\n" + "return l1dat.devname_ridx.%s.INDEX\n"; + +static const char ifname2chip[] = + "local l1parser = require 'l1util'\n" + "local l1dat = l1parser.load_l1_profile(l1parser.L1_DAT_PATH)\n" + "return l1dat.ifname_ridx.%s.INDEX\n"; + +#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 +static int lua_absindex (lua_State *L, int i) { + if (i < 0 && i > LUA_REGISTRYINDEX) + i += lua_gettop(L) + 1; + return i; +} +#endif + +#if defined( LUA_VERSION_NUM ) && LUA_VERSION_NUM <= 502 +#define lua_getfield(L, i, k) \ + (lua_getfield((L), (i), (k)), lua_type((L), -1)) + +static int luaL_getsubtable (lua_State *L, int i, const char *name) { + int abs_i = lua_absindex(L, i); + luaL_checkstack(L, 3, "not enough stack slots"); + lua_pushstring(L, name); + lua_gettable(L, abs_i); + if (lua_istable(L, -1)) + return 1; + lua_pop(L, 1); + lua_newtable(L); + lua_pushstring(L, name); + lua_pushvalue(L, -2); + lua_settable(L, abs_i); + return 0; +} + +static void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + luaL_checkstack(L, 3, "not enough stack slots available"); + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + if (lua_getfield(L, -1, modname) == LUA_TNIL) { + lua_pop(L, 1); + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); + lua_call(L, 1, 1); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); + } + + if (glb) { + lua_pushvalue(L, -1); + lua_setglobal(L, modname); + } + lua_replace(L, -2); +} +#endif + +static int openf(lua_State* L) { + int ret; + ret = luaL_dofile(L, MTK_L1UTIL_PATH); + return 1; +} + +static int mtk_dev_match_id(const char* chip, struct iwinfo_hardware_id *id) +{ + if (!strcmp(chip, "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(chip, "MT7986")) { + id->vendor_id = 0x14c3; + id->device_id = 0x7986; + id->subsystem_vendor_id = id->vendor_id; + id->subsystem_device_id = id->device_id; + } else if (!strcmp(chip, "MT7916")) { + id->vendor_id = 0x14c3; + id->device_id = 0x7916; + id->subsystem_vendor_id = id->vendor_id; + id->subsystem_device_id = id->device_id; + } else { + return -1; + } + + return 0; +} + +int mtk_get_id_by_l1util(const char *dev, struct iwinfo_hardware_id *id) +{ + int ret; + int is_ifname = 0; + + if (access(MTK_L1UTIL_PATH, F_OK) != 0) + return -1; + + if (strstr(dev,"ra") || strstr(dev,"apcli") || strstr(dev,"wds") || strstr(dev,"mesh")) + is_ifname = 1; + + lua_State* L = luaL_newstate(); + + luaL_openlibs(L); + luaL_requiref(L, "l1util", openf, 0); + + if (is_ifname) + snprintf(luacmd, sizeof(luacmd), ifname2chip, dev); + else + snprintf(luacmd, sizeof(luacmd), dev2chip, dev); + + ret = luaL_dostring(L, luacmd); + + if (ret == 0) + ret = mtk_dev_match_id(lua_tostring(L, -1), id); + + lua_close(L); + + return ret; +} + +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; +} + +int mtk_get_id_from_l1profile(struct iwinfo_hardware_id *id) +{ + char buf[16] = {0}; + + /* if l1profile has INDEX1, return error*/ + if (mtk_get_l1profile_attr("INDEX1", buf, sizeof(buf)) == 0) + return -1; + + if (mtk_get_l1profile_attr("INDEX0", buf, sizeof(buf)) != 0) + return -1; + + return (mtk_dev_match_id(buf, id)); +} diff --git a/package/network/utils/iwinfo/src/mtwifi.h b/package/network/utils/iwinfo/src/mtwifi.h index cb8ff4cff4..ec90d22270 100644 --- a/package/network/utils/iwinfo/src/mtwifi.h +++ b/package/network/utils/iwinfo/src/mtwifi.h @@ -1,6 +1,8 @@ #ifndef __MTWIFI_H #define __MTWIFI_H +#include "iwinfo.h" + #define USHORT unsigned short #define UCHAR unsigned char #define ULONG unsigned long @@ -260,9 +262,13 @@ typedef enum _SEC_AKM_MODE { #define IS_AKM_OWE(_AKMMap) ((_AKMMap & (1 << SEC_AKM_OWE)) > 0) #define MTK_L1_PROFILE_PATH "/etc/wireless/l1profile.dat" +#define MTK_L1UTIL_PATH "/usr/lib/lua/l1dat_parser.lua" 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); +int mtk_get_id_by_l1util(const char *dev, struct iwinfo_hardware_id *id); +int mtk_get_id_from_l1profile(struct iwinfo_hardware_id *id); + #endif