iwinfo: add support for mtk l1util lua script

This commit is contained in:
hanwckf 2024-09-13 21:15:40 +08:00
parent 59930ea1b2
commit 59ab5b73fa
7 changed files with 233 additions and 59 deletions

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -0,0 +1,176 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <lauxlib.h>
#include <lua.h>
#include <luaconf.h>
#include <lualib.h>
#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));
}

View File

@ -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