diff --git a/.gitignore b/.gitignore index 9647daa5a4..1f572936a5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ .DS_Store .*.swp /env -/dl +/dl/* /.config /.config.old /bin @@ -30,3 +30,7 @@ git-src .cproject .ccache .vscode + +!/dl/datconf* +!/dl/mt798* +!/dl/warp* diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 8a1ddf96f5..b9181cae3f 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -205,6 +205,9 @@ define Package/base-files/install $(if $(CONFIG_TARGET_PREINIT_DISABLE_FAILSAFE), \ rm -f $(1)/etc/banner.failsafe,) + + $(if $(CONFIG_PACKAGE_wifi-profile), \ + rm -f $(1)/sbin/wifi) endef ifneq ($(DUMP),1) diff --git a/package/mtk/applications/datconf/Makefile b/package/mtk/applications/datconf/Makefile new file mode 100644 index 0000000000..94edc47cd2 --- /dev/null +++ b/package/mtk/applications/datconf/Makefile @@ -0,0 +1,92 @@ +# +# Copyright (C) 2019 +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=datconf +PKG_REVISION:=6bb733f7 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_REVISION).tar.bz2 +PKG_RELEASE:=1 +PKG_USE_NINJA:=0 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +PKG_MAINTAINER:=Weijie Gao + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/libkvcutil + SECTION:=libs + CATEGORY:=Libraries + TITLE:=C library for Key-value based config files +endef + +define Package/kvcedit + SECTION:=util + CATEGORY:=Utilities + DEPENDS:=+libkvcutil + TITLE:=Utility for editing key-value based config files +endef + +define Package/datconf + SECTION:=MTK Properties + CATEGORY:=MTK Properties + SUBMENU:=Applications + DEPENDS:=+kvcedit + TITLE:=Utility for editing dat files used by MediaTek Wi-Fi drivers +endef + +define Package/datconf-lua + SECTION:=MTK Properties + CATEGORY:=MTK Properties + SUBMENU:=Applications + DEPENDS:=+datconf +liblua + TITLE:=Lua plugin for datconf +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +CMAKE_OPTIONS = \ + -DLUAPATH=/usr/lib/lua + + +define Package/libkvcutil/install + $(INSTALL_DIR) $(1)/lib + $(CP) $(PKG_BUILD_DIR)/kvcutil/libkvcutil.so* $(1)/lib/ +endef + +define Package/kvcedit/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/kvcutil/kvcedit $(1)/usr/bin/ +endef + +define Package/datconf/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/datconf/datconf $(1)/usr/bin/ +endef + +define Package/datconf-lua/install + $(INSTALL_DIR) $(1)/usr/lib/lua + $(CP) $(PKG_BUILD_DIR)/datconf/lua/datconf.so $(1)/usr/lib/lua/ +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/kvcutil/libkvcutil.h $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/datconf/libdatconf.h $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/kvcutil/libkvcutil.so* $(1)/usr/lib + -$(CP) $(PKG_BUILD_DIR)/datconf/libdatconf.a $(1)/usr/lib +endef + +$(eval $(call BuildPackage,libkvcutil)) +$(eval $(call BuildPackage,kvcedit)) +$(eval $(call BuildPackage,datconf)) +$(eval $(call BuildPackage,datconf-lua)) diff --git a/package/mtk/applications/luci-app-mtk/Makefile b/package/mtk/applications/luci-app-mtk/Makefile new file mode 100644 index 0000000000..bcf3511879 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/Makefile @@ -0,0 +1,21 @@ +# +# Copyright (C) Hua Shao +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=MediaTek Proprietary Configuration. +LUCI_DEPENDS:=+datconf-lua +LUCI_MK_PATH_OLD:=$(shell test -e ../luci.mk && echo "old") +LUCI_MK_PATH_FEEDS:=$(shell test -e $(TOPDIR)/feeds/luci/luci.mk && echo "feeds") +ifeq ($(LUCI_MK_PATH_OLD),old) +include ../luci.mk +else ifeq ($(LUCI_MK_PATH_FEEDS),feeds) +include $(TOPDIR)/feeds/luci/luci.mk +else +include $(TOPDIR)/package/luci/luci.mk +endif + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/mtk/applications/luci-app-mtk/NOTICE b/package/mtk/applications/luci-app-mtk/NOTICE new file mode 100644 index 0000000000..486c549461 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/NOTICE @@ -0,0 +1,198 @@ +Copyright (C) 2016 Gion Kunz + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Copyright 2008 Steven Barth +Copyright 2008 Jo-Philipp Wich + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/package/mtk/applications/luci-app-mtk/luasrc/controller/mtkwifi.lua b/package/mtk/applications/luci-app-mtk/luasrc/controller/mtkwifi.lua new file mode 100644 index 0000000000..3d589028a9 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/controller/mtkwifi.lua @@ -0,0 +1,1795 @@ +-- This module is a demo to configure MTK' proprietary WiFi driver. +-- Basic idea is to bypass uci and edit wireless profile (mt76xx.dat) directly. +-- LuCI's WiFi configuration is more logical and elegent, but it's quite tricky to +-- translate uci into MTK's WiFi profile (like we did in "uci2dat"). +-- And you will get your hands dirty. +-- +-- Hua Shao + +package.path = '/lib/wifi/?.lua;'..package.path +module("luci.controller.mtkwifi", package.seeall) + +local ioctl_help = require "ioctl_helper" +local http = require("luci.http") +local mtkwifi = require("mtkwifi") + +local logDisable = 0 +function debug_write(...) + -- luci.http.write(...) + if logDisable == 1 then + return + end + local syslog_msg = ""; + local ff = io.open("/tmp/dbgmsg", "a") + local nargs = select('#',...) + + for n=1, nargs do + local v = select(n,...) + if (type(v) == "string" or type(v) == "number") then + ff:write(v.." ") + syslog_msg = syslog_msg..v.." "; + elseif (type(v) == "boolean") then + if v then + ff:write("true ") + syslog_msg = syslog_msg.."true "; + else + ff:write("false ") + syslog_msg = syslog_msg.."false "; + end + elseif (type(v) == "nil") then + ff:write("nil ") + syslog_msg = syslog_msg.."nil "; + else + ff:write(" ") + syslog_msg = syslog_msg.." "; + end + end + ff:write("\n") + ff:close() + nixio.syslog("debug", syslog_msg) +end + +function index() + -- if not nixio.fs.access("/etc/wireless") then + -- return + -- end + + entry({"admin", "mtk"}, firstchild(), _("MTK"), 80) + entry({"admin", "mtk", "test"}, call("test")) + entry({"admin", "mtk", "wifi"}, template("admin_mtk/mtk_wifi_overview"), _("WiFi configuration"), 1) + entry({"admin", "mtk", "wifi", "chip_cfg_view"}, template("admin_mtk/mtk_wifi_chip_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "chip_cfg"}, call("chip_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "dev_cfg_view"}, template("admin_mtk/mtk_wifi_dev_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "dev_cfg"}, call("dev_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "dev_cfg_raw"}, call("dev_cfg_raw")).leaf = true + entry({"admin", "mtk", "wifi", "vif_cfg_view"}, template("admin_mtk/mtk_wifi_vif_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "vif_cfg"}, call("vif_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "vif_add_view"}, template("admin_mtk/mtk_wifi_vif_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "vif_add"}, call("vif_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "vif_del"}, call("vif_del")).leaf = true + entry({"admin", "mtk", "wifi", "vif_disable"}, call("vif_disable")).leaf = true + entry({"admin", "mtk", "wifi", "vif_enable"}, call("vif_enable")).leaf = true + entry({"admin", "mtk", "wifi", "get_station_list"}, call("get_station_list")) + entry({"admin", "mtk", "wifi", "get_country_region_list"}, call("get_country_region_list")).leaf = true + entry({"admin", "mtk", "wifi", "get_channel_list"}, call("get_channel_list")) + entry({"admin", "mtk", "wifi", "get_HT_ext_channel_list"}, call("get_HT_ext_channel_list")) + entry({"admin", "mtk", "wifi", "get_5G_2nd_80Mhz_channel_list"}, call("get_5G_2nd_80Mhz_channel_list")) + entry({"admin", "mtk", "wifi", "reset"}, call("reset_wifi")).leaf = true + entry({"admin", "mtk", "wifi", "reload"}, call("reload_wifi")).leaf = true + entry({"admin", "mtk", "wifi", "get_raw_profile"}, call("get_raw_profile")) + entry({"admin", "mtk", "wifi", "apcli_cfg_view"}, template("admin_mtk/mtk_wifi_apcli")).leaf = true + entry({"admin", "mtk", "wifi", "apcli_cfg"}, call("apcli_cfg")).leaf = true + entry({"admin", "mtk", "wifi", "apcli_disconnect"}, call("apcli_disconnect")).leaf = true + entry({"admin", "mtk", "wifi", "apcli_connect"}, call("apcli_connect")).leaf = true + entry({"admin", "mtk", "netmode", "net_cfg"}, call("net_cfg")) + entry({"admin", "mtk", "wifi", "get_wps_info"}, call("get_WPS_Info")).leaf = true + entry({"admin", "mtk", "wifi", "get_wifi_pin"}, call("get_wifi_pin")).leaf = true + entry({"admin", "mtk", "wifi", "set_wifi_gen_pin"}, call("set_wifi_gen_pin")).leaf = true + entry({"admin", "mtk", "wifi", "set_wifi_wps_oob"}, call("set_wifi_wps_oob")).leaf = true + entry({"admin", "mtk", "wifi", "set_wifi_do_wps"}, call("set_wifi_do_wps")).leaf = true + entry({"admin", "mtk", "wifi", "get_wps_security"}, call("get_wps_security")).leaf = true + entry({"admin", "mtk", "wifi", "apcli_get_wps_status"}, call("apcli_get_wps_status")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_do_enr_pin_wps"}, call("apcli_do_enr_pin_wps")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_do_enr_pbc_wps"}, call("apcli_do_enr_pbc_wps")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_cancel_wps"}, call("apcli_cancel_wps")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_wps_gen_pincode"}, call("apcli_wps_gen_pincode")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_wps_get_pincode"}, call("apcli_wps_get_pincode")).leaf = true; + entry({"admin", "mtk", "wifi", "apcli_scan"}, call("apcli_scan")).leaf = true; + entry({"admin", "mtk", "wifi", "sta_info"}, call("sta_info")).leaf = true; + entry({"admin", "mtk", "wifi", "get_apcli_conn_info"}, call("get_apcli_conn_info")).leaf = true; + entry({"admin", "mtk", "wifi", "apply_power_boost_settings"}, call("apply_power_boost_settings")).leaf = true; + entry({"admin", "mtk", "wifi", "apply_reboot"}, template("admin_mtk/mtk_wifi_apply_reboot")).leaf = true; + entry({"admin", "mtk", "wifi", "reboot"}, call("exec_reboot")).leaf = true; + entry({"admin", "mtk", "wifi", "get_bssid_num"}, call("get_bssid_num")).leaf = true; + entry({"admin", "mtk", "wifi", "loading"}, template("admin_mtk/mtk_wifi_loading")).leaf = true; + entry({"admin", "mtk", "wifi", "get_apply_status"}, call("get_apply_status")).leaf = true; + entry({"admin", "mtk", "wifi", "reset_to_defaults"}, call("reset_to_defaults")).leaf = true; + local mtkwifi = require("mtkwifi") + -- local profiles = mtkwifi.search_dev_and_profile() + -- for devname,profile in pairs(profiles) do + -- local cfgs = mtkwifi.load_profile(profile) + -- if cfgs["VOW_Airtime_Fairness_En"] then + -- entry({"admin", "mtk", "vow"}, template("admin_mtk/mtk_vow"), _("VoW / ATF / ATC"), 4) + -- break + -- end + -- end +end + +function test() + http.write_json(http.formvalue()) +end + +function exec_reboot() + os.execute("rm -f /tmp/mtk/wifi/reboot_required >/dev/null 2>&1") + os.execute("sync >/dev/null 2>&1") + os.execute("reboot >/dev/null 2>&1") +end + +function get_apply_status() + local ret = {} + + if mtkwifi.is_child_active() then + ret["status"] = "ON_PROGRESS" + elseif mtkwifi.exists("/tmp/mtk/wifi/reboot_required") then + -- If the "wifi restart" command can not re-install the driver; then, it will create + -- "/tmp/mtk/wifi/reboot_required" file to indicate LuCI that the settings will be applied + -- only after reboot of the device. + -- Redirect "Reboot Device" web-page to get consent from the user to reboot the device. + ret["status"] = "REBOOT" + else + ret["status"] = "DONE" + end + http.write_json(ret) +end + +function __mtkwifi_save_profile(cfgs, path, isProfileSettingsAppliedToDriver) + -- Create the applied settings backup file before saving the new profile settings only if it does not exist. + if not mtkwifi.exists(mtkwifi.__profile_applied_settings_path(path)) then + os.execute("cp -f "..path.." "..mtkwifi.__profile_applied_settings_path(path)) + end + if isProfileSettingsAppliedToDriver then + -- It means the some context based profile settings to be saved in DAT file is already applied to the driver. + -- Find the profile settings which are not applied to the driver before saving the new profile settings + local diff = mtkwifi.diff_profile(path) + mtkwifi.save_profile(cfgs, path) + -- If there are any settings which are not applied to the driver, then do NOT copy and WebUI will display the "need reload to apply changes" message + -- Otherwise, copy the new profile settings and WebUI will NOT display the "need reload to apply changes" message + if next(diff) == nil then + os.execute("cp -f "..path.." "..mtkwifi.__profile_applied_settings_path(path)) + end + else + mtkwifi.save_profile(cfgs, path) + end +end + +local __mtkwifi_reload = function (devname) + local wifi_restart = false + local wifi_reload = false + local profiles = mtkwifi.search_dev_and_profile() + + for dev,profile in pairs(profiles) do + if not devname or devname == dev then + local diff = mtkwifi.diff_profile(profile) + __process_settings_before_apply(dev, profile, diff) + + if diff.BssidNum or diff.WHNAT or diff.E2pAccessMode or diff.HT_RxStream or diff.HT_TxStream or diff.HE_LDPC or diff.WdsEnable then + -- Addition or deletion of a vif requires re-installation of the driver. + -- Change in WHNAT setting also requires re-installation of the driver. + -- Driver will be re-installed by "wifi restart" command. + wifi_restart = true + else + wifi_reload = true + end + + end + end + + if wifi_restart then + os.execute("wifi restart "..(devname or "")) + debug_write("wifi restart "..(devname or "")) + elseif wifi_reload then + os.execute("wifi reload "..(devname or "")) + debug_write("wifi reload "..(devname or "")) + end + + for dev,profile in pairs(profiles) do + if not devname or devname == dev then + -- keep a backup for this commit + -- it will be used in mtkwifi.diff_profile() + os.execute("cp -f "..profile.." "..mtkwifi.__profile_applied_settings_path(profile)) + debug_write("cp -f "..profile.." "..mtkwifi.__profile_applied_settings_path(profile)) + end + end + +end + +function __process_settings_before_apply(devname, profile, diff) + local devs = mtkwifi.get_all_devs() + local cfgs = mtkwifi.load_profile(profile) + __apply_wifi_wpsconf(devs, devname, cfgs, diff) +end + +function chip_cfg(devname) + local profiles = mtkwifi.search_dev_and_profile() + assert(profiles[devname]) + local cfgs = mtkwifi.load_profile(profiles[devname]) + local devs = mtkwifi.get_all_devs() + local dbdc_cfgs = {} + local dev = {} + dev = devs and devs[devname] + + for k,v in pairs(http.formvalue()) do + if type(v) ~= type("") and type(v) ~= type(0) then + nixio.syslog("err", "chip_cfg, invalid value type for "..k..","..type(v)) + elseif string.byte(k) == string.byte("_") then + nixio.syslog("err", "chip_cfg, special: "..k.."="..v) + else + if dev.dbdc == true then + dbdc_cfgs[k] = v or "" + else + cfgs[k] = v or "" + end + end + end + + -- VOW + -- ATC should actually be scattered into each SSID, but I'm just lazy. + if cfgs.VOW_Airtime_Fairness_En then + for i = 1,tonumber(cfgs.BssidNum) do + __atc_tp = http.formvalue("__atc_vif"..i.."_tp") or "0" + __atc_min_tp = http.formvalue("__atc_vif"..i.."_min_tp") or "0" + __atc_max_tp = http.formvalue("__atc_vif"..i.."_max_tp") or "0" + __atc_at = http.formvalue("__atc_vif"..i.."_at") or "0" + __atc_min_at = http.formvalue("__atc_vif"..i.."_min_at") or "0" + __atc_max_at = http.formvalue("__atc_vif"..i.."_max_at") or "0" + + nixio.syslog("info", "ATC.__atc_tp ="..i..__atc_tp ); + nixio.syslog("info", "ATC.__atc_min_tp ="..i..__atc_min_tp ); + nixio.syslog("info", "ATC.__atc_max_tp ="..i..__atc_max_tp ); + nixio.syslog("info", "ATC.__atc_at ="..i..__atc_at ); + nixio.syslog("info", "ATC.__atc_min_at ="..i..__atc_min_at ); + nixio.syslog("info", "ATC.__atc_max_at ="..i..__atc_max_at ); + + dbdc_cfgs.VOW_Rate_Ctrl_En = mtkwifi.token_set(cfgs.VOW_Rate_Ctrl_En, i, __atc_tp) + dbdc_cfgs.VOW_Group_Min_Rate = mtkwifi.token_set(cfgs.VOW_Group_Min_Rate, i, __atc_min_tp) + dbdc_cfgs.VOW_Group_Max_Rate = mtkwifi.token_set(cfgs.VOW_Group_Max_Rate, i, __atc_max_tp) + + dbdc_cfgs.VOW_Airtime_Ctrl_En = mtkwifi.token_set(cfgs.VOW_Airtime_Ctrl_En, i, __atc_at) + dbdc_cfgs.VOW_Group_Min_Ratio = mtkwifi.token_set(cfgs.VOW_Group_Min_Ratio, i, __atc_min_at) + dbdc_cfgs.VOW_Group_Max_Ratiio = mtkwifi.token_set(cfgs.VOW_Group_Max_Ratio, i, __atc_max_at) + + cfgs.VOW_Rate_Ctrl_En = mtkwifi.token_set(cfgs.VOW_Rate_Ctrl_En, i, __atc_tp) + cfgs.VOW_Group_Min_Rate = mtkwifi.token_set(cfgs.VOW_Group_Min_Rate, i, __atc_min_tp) + cfgs.VOW_Group_Max_Rate = mtkwifi.token_set(cfgs.VOW_Group_Max_Rate, i, __atc_max_tp) + + cfgs.VOW_Airtime_Ctrl_En = mtkwifi.token_set(cfgs.VOW_Airtime_Ctrl_En, i, __atc_at) + cfgs.VOW_Group_Min_Ratio = mtkwifi.token_set(cfgs.VOW_Group_Min_Ratio, i, __atc_min_at) + cfgs.VOW_Group_Max_Ratio = mtkwifi.token_set(cfgs.VOW_Group_Max_Ratio, i, __atc_max_at) + + end + + dbdc_cfgs.VOW_RX_En = http.formvalue("VOW_RX_En") or "0" + cfgs.VOW_RX_En = http.formvalue("VOW_RX_En") or "0" + end + + if dev.dbdc == true then + for devname, profile in pairs(profiles) do + __mtkwifi_save_profile(dbdc_cfgs, profile, false) + end + else + __mtkwifi_save_profile(cfgs, profiles[devname], false) + end + + if http.formvalue("__apply") then + mtkwifi.__run_in_child_env(__mtkwifi_reload, devname) + local url_to_visit_after_reload = luci.dispatcher.build_url("admin", "mtk", "wifi", "chip_cfg_view",devname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",url_to_visit_after_reload)) + else + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "chip_cfg_view",devname)) + end + +end + +function dev_cfg(devname) + local profiles = mtkwifi.search_dev_and_profile() + assert(profiles[devname]) + local cfgs = mtkwifi.load_profile(profiles[devname]) + + for k,v in pairs(http.formvalue()) do + if type(v) ~= type("") and type(v) ~= type(0) then + nixio.syslog("err", "dev_cfg, invalid value type for "..k..","..type(v)) + elseif string.byte(k) == string.byte("_") then + nixio.syslog("err", "dev_cfg, special: "..k.."="..v) + else + cfgs[k] = v or "" + end + end + + if cfgs.Channel == "0" then -- Auto Channel Select + cfgs.AutoChannelSelect = "3" + else + cfgs.AutoChannelSelect = "0" + end + + if http.formvalue("__bw") == "20" then + cfgs.HT_BW = 0 + cfgs.VHT_BW = 0 + elseif http.formvalue("__bw") == "40" then + cfgs.HT_BW = 1 + cfgs.VHT_BW = 0 + cfgs.HT_BSSCoexistence = 0 + elseif http.formvalue("__bw") == "60" then + cfgs.HT_BW = 1 + cfgs.VHT_BW = 0 + cfgs.HT_BSSCoexistence = 1 + elseif http.formvalue("__bw") == "80" then + cfgs.HT_BW = 1 + cfgs.VHT_BW = 1 + elseif http.formvalue("__bw") == "160" then + cfgs.HT_BW = 1 + cfgs.VHT_BW = 2 + elseif http.formvalue("__bw") == "161" then + cfgs.HT_BW = 1 + cfgs.VHT_BW = 3 + cfgs.VHT_Sec80_Channel = http.formvalue("VHT_Sec80_Channel") or "" + end + + if mtkwifi.band(string.split(cfgs.WirelessMode,";")[1]) == "5G" or mtkwifi.band(cfgs.WirelessMode) == "6G" then + cfgs.CountryRegionABand = http.formvalue("__cr"); + else + cfgs.CountryRegion = http.formvalue("__cr"); + end + + if http.formvalue("TxPower") then + local txpower = tonumber(http.formvalue("TxPower")) + if txpower < 100 then + cfgs.PERCENTAGEenable=1 + else + cfgs.PERCENTAGEenable=0 + end + end + + local IndividualTWTSupport = tonumber(http.formvalue("IndividualTWTSupport")) + if IndividualTWTSupport == 0 then + cfgs.TWTResponder=0 + cfgs.TWTRequired=0 + elseif IndividualTWTSupport == 1 then + cfgs.TWTResponder=1 + cfgs.TWTRequired=0 + else + cfgs.TWTResponder=1 + cfgs.TWTRequired=1 + end + + local mimo = http.formvalue("__mimo") + if mimo == "0" then + cfgs.ETxBfEnCond=1 + cfgs.MUTxRxEnable=0 + cfgs.ITxBfEn=0 + elseif mimo == "1" then + cfgs.ETxBfEnCond=0 + cfgs.MUTxRxEnable=0 + cfgs.ITxBfEn=1 + elseif mimo == "2" then + cfgs.ETxBfEnCond=1 + cfgs.MUTxRxEnable=0 + cfgs.ITxBfEn=1 + elseif mimo == "3" then + cfgs.ETxBfEnCond=1 + if tonumber(cfgs.ApCliEnable) == 1 then + cfgs.MUTxRxEnable=3 + else + cfgs.MUTxRxEnable=1 + end + cfgs.ITxBfEn=0 + elseif mimo == "4" then + cfgs.ETxBfEnCond=1 + if tonumber(cfgs.ApCliEnable) == 1 then + cfgs.MUTxRxEnable=3 + else + cfgs.MUTxRxEnable=1 + end + cfgs.ITxBfEn=1 + else + cfgs.ETxBfEnCond=0 + cfgs.MUTxRxEnable=0 + cfgs.ITxBfEn=0 + end + +-- if cfgs.ApCliEnable == "1" then +-- cfgs.Channel = http.formvalue("__apcli_channel") +-- end + + -- WDS + -- http.write_json(http.formvalue()) + __mtkwifi_save_profile(cfgs, profiles[devname], false) + + if http.formvalue("__apply") then + mtkwifi.__run_in_child_env(__mtkwifi_reload, devname) + local url_to_visit_after_reload = luci.dispatcher.build_url("admin", "mtk", "wifi", "dev_cfg_view",devname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",url_to_visit_after_reload)) + else + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "dev_cfg_view",devname)) + end +end + +function dev_cfg_raw(devname) + -- http.write_json(http.formvalue()) + local profiles = mtkwifi.search_dev_and_profile() + assert(profiles[devname]) + + local raw = http.formvalue("raw") + raw = string.gsub(raw, "\r\n", "\n") + local cfgs = mtkwifi.load_profile(nil, raw) + __mtkwifi_save_profile(cfgs, profiles[devname], false) + + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "dev_cfg_view", devname)) +end + +function __delete_mbss_para(cfgs, vif_idx) + debug_write(vif_idx) + cfgs["WPAPSK"..vif_idx]="" + cfgs["Key1Type"]=mtkwifi.token_set(cfgs["Key1Type"],vif_idx,"") + cfgs["Key2Type"]=mtkwifi.token_set(cfgs["Key2Type"],vif_idx,"") + cfgs["Key3Type"]=mtkwifi.token_set(cfgs["Key3Type"],vif_idx,"") + cfgs["Key4Type"]=mtkwifi.token_set(cfgs["Key4Type"],vif_idx,"") + cfgs["RADIUS_Server"]=mtkwifi.token_set(cfgs["RADIUS_Server"],vif_idx,"") + cfgs["RADIUS_Port"]=mtkwifi.token_set(cfgs["RADIUS_Port"],vif_idx,"") + cfgs["RADIUS_Key"..vif_idx]="" + cfgs["DefaultKeyID"]=mtkwifi.token_set(cfgs["DefaultKeyID"],vif_idx,"") + cfgs["IEEE8021X"]=mtkwifi.token_set(cfgs["IEEE8021X"],vif_idx,"") + cfgs["WscConfMode"]=mtkwifi.token_set(cfgs["WscConfMode"],vif_idx,"") + cfgs["PreAuth"]=mtkwifi.token_set(cfgs["PreAuth"],vif_idx,"") + cfgs["HT_STBC"] = mtkwifi.token_set(cfgs["HT_STBC"],vif_idx,"") + cfgs["HT_LDPC"] = mtkwifi.token_set(cfgs["HT_LDPC"],vif_idx,"") + cfgs["VHT_STBC"] = mtkwifi.token_set(cfgs["VHT_STBC"],vif_idx,"") + cfgs["VHT_LDPC"] = mtkwifi.token_set(cfgs["VHT_LDPC"],vif_idx,"") + cfgs["HideSSID"]=mtkwifi.token_set(cfgs["HideSSID"],vif_idx,"") + cfgs["NoForwarding"]=mtkwifi.token_set(cfgs["NoForwarding"],vif_idx,"") + cfgs["WmmCapable"]=mtkwifi.token_set(cfgs["WmmCapable"],vif_idx,"") + cfgs["TxRate"]=mtkwifi.token_set(cfgs["TxRate"],vif_idx,"") + cfgs["RekeyInterval"]=mtkwifi.token_set(cfgs["RekeyInterval"],vif_idx,"") + cfgs["AuthMode"]=mtkwifi.token_set(cfgs["AuthMode"],vif_idx,"") + cfgs["EncrypType"]=mtkwifi.token_set(cfgs["EncrypType"],vif_idx,"") + cfgs["session_timeout_interval"]=mtkwifi.token_set(cfgs["session_timeout_interval"],vif_idx,"") + cfgs["WscModeOption"]=mtkwifi.token_set(cfgs["WscModeOption"],vif_idx,"") + cfgs["RekeyMethod"]=mtkwifi.token_set(cfgs["RekeyMethod"],vif_idx,"") + cfgs["PMFMFPC"] = mtkwifi.token_set(cfgs["PMFMFPC"],vif_idx,"") + cfgs["PMFMFPR"] = mtkwifi.token_set(cfgs["PMFMFPR"],vif_idx,"") + cfgs["PMFSHA256"] = mtkwifi.token_set(cfgs["PMFSHA256"],vif_idx,"") + cfgs["PMKCachePeriod"] = mtkwifi.token_set(cfgs["PMKCachePeriod"],vif_idx,"") + cfgs["Wapiifname"] = mtkwifi.token_set(cfgs["Wapiifname"],vif_idx,"") + cfgs["RRMEnable"] = mtkwifi.token_set(cfgs["RRMEnable"],vif_idx,"") + cfgs["DLSCapable"] = mtkwifi.token_set(cfgs["DLSCapable"],vif_idx,"") + cfgs["APSDCapable"] = mtkwifi.token_set(cfgs["APSDCapable"],vif_idx,"") + cfgs["FragThreshold"] = mtkwifi.token_set(cfgs["FragThreshold"],vif_idx,"") + cfgs["RTSThreshold"] = mtkwifi.token_set(cfgs["RTSThreshold"],vif_idx,"") + cfgs["VHT_SGI"] = mtkwifi.token_set(cfgs["VHT_SGI"],vif_idx,"") + cfgs["VHT_BW_SIGNAL"] = mtkwifi.token_set(cfgs["VHT_BW_SIGNAL"],vif_idx,"") + cfgs["HT_PROTECT"] = mtkwifi.token_set(cfgs["HT_PROTECT"],vif_idx,"") + cfgs["HT_GI"] = mtkwifi.token_set(cfgs["HT_GI"],vif_idx,"") + cfgs["HT_OpMode"] = mtkwifi.token_set(cfgs["HT_OpMode"],vif_idx,"") + cfgs["HT_TxStream"] = mtkwifi.token_set(cfgs["HT_TxStream"],vif_idx,"") + cfgs["HT_RxStream"] = mtkwifi.token_set(cfgs["HT_RxStream"],vif_idx,"") + cfgs["HT_AMSDU"] = mtkwifi.token_set(cfgs["HT_AMSDU"],vif_idx,"") + cfgs["HT_AutoBA"] = mtkwifi.token_set(cfgs["HT_AutoBA"],vif_idx,"") + cfgs["IgmpSnEnable"] = mtkwifi.token_set(cfgs["IgmpSnEnable"],vif_idx,"") + cfgs["WirelessMode"] = mtkwifi.token_set(cfgs["WirelessMode"],vif_idx,"") + cfgs["WdsEnable"] = mtkwifi.token_set(cfgs["WdsEnable"],vif_idx,"") + cfgs["MuOfdmaDlEnable"] = mtkwifi.token_set(cfgs["MuOfdmaDlEnable"],vif_idx,"") + cfgs["MuOfdmaUlEnable"] = mtkwifi.token_set(cfgs["MuOfdmaUlEnable"],vif_idx,"") + cfgs["MuMimoDlEnable"] = mtkwifi.token_set(cfgs["MuMimoDlEnable"],vif_idx,"") + cfgs["MuMimoUlEnable"] = mtkwifi.token_set(cfgs["MuMimoUlEnable"],vif_idx,"") + +end + +function vif_del(dev, vif) + debug_write("vif_del("..dev..vif..")") + local devname,vifname = dev, vif + debug_write("devname="..devname) + debug_write("vifname="..vifname) + local devs = mtkwifi.get_all_devs() + local idx = devs[devname]["vifs"][vifname].vifidx -- or tonumber(string.match(vifname, "%d+")) + 1 + debug_write("idx="..idx, devname, vifname) + local profile = devs[devname].profile + assert(profile) + if idx and tonumber(idx) >= 0 then + local cfgs = mtkwifi.load_profile(profile) + __delete_mbss_para(cfgs, idx) + if cfgs then + debug_write("ssid"..idx.."="..cfgs["SSID"..idx].."
") + cfgs["SSID"..idx] = "" + debug_write("ssid"..idx.."="..cfgs["SSID"..idx].."
") + debug_write("wpapsk"..idx.."="..cfgs["WPAPSK"..idx].."
") + cfgs["WPAPSK"..idx] = "" + local ssidlist = {} + local j = 1 + for i = 1,16 do + if cfgs["SSID"..i] ~= "" then + ssidlist[j] = cfgs["SSID"..i] + j = j + 1 + end + end + for i,v in ipairs(ssidlist) do + debug_write("ssidlist"..i.."="..v) + end + debug_write("cfgs.BssidNum="..cfgs.BssidNum.." #ssidlist="..#ssidlist) + assert(tonumber(cfgs.BssidNum) == #ssidlist + 1, "BssidNum="..cfgs.BssidNum.." SSIDlist="..#ssidlist..", BssidNum count does not match with SSIDlist count.") + cfgs.BssidNum = #ssidlist + for i = 1,16 do + if i <= cfgs.BssidNum then + cfgs["SSID"..i] = ssidlist[i] + elseif cfgs["SSID"..i] then + cfgs["SSID"..i] = "" + end + end + + __mtkwifi_save_profile(cfgs, profile, false) + else + debug_write(profile.." cannot be found!") + end + end + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + +function vif_disable(iface) + os.execute("ifconfig "..iface.." down") + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + +function vif_enable(iface) + os.execute("ifconfig "..iface.." up") + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + + +--[[ +-- security config in mtk wifi is quite complicated! +-- cfgs listed below are attached with vif and combined like "0;0;0;0". They need specicial treatment. + TxRate, WmmCapable, NoForwarding, + HideSSID, IEEE8021X, PreAuth, + AuthMode, EncrypType, RekeyMethod, + RekeyInterval, PMKCachePeriod, + DefaultKeyId, Key{n}Type, HT_EXTCHA, + RADIUS_Server, RADIUS_Port, +]] + +local function conf_wep_keys(cfgs,vifidx) + cfgs.DefaultKeyID = mtkwifi.token_set(cfgs.DefaultKeyID, vifidx, http.formvalue("__DefaultKeyID") or 1) + cfgs["Key1Str"..vifidx] = http.formvalue("Key1Str"..vifidx) + cfgs["Key2Str"..vifidx] = http.formvalue("Key2Str"..vifidx) + cfgs["Key3Str"..vifidx] = http.formvalue("Key3Str"..vifidx) + cfgs["Key4Str"..vifidx] = http.formvalue("Key4Str"..vifidx) + + cfgs["Key1Type"]=mtkwifi.token_set(cfgs["Key1Type"],vifidx, http.formvalue("WEP1Type"..vifidx)) + cfgs["Key2Type"]=mtkwifi.token_set(cfgs["Key2Type"],vifidx, http.formvalue("WEP2Type"..vifidx)) + cfgs["Key3Type"]=mtkwifi.token_set(cfgs["Key3Type"],vifidx, http.formvalue("WEP3Type"..vifidx)) + cfgs["Key4Type"]=mtkwifi.token_set(cfgs["Key4Type"],vifidx, http.formvalue("WEP4Type"..vifidx)) + + return cfgs +end + +local function __security_cfg(cfgs, vif_idx) + debug_write("__security_cfg, before, HideSSID="..tostring(cfgs.HideSSID)) + debug_write("__security_cfg, before, NoForwarding="..tostring(cfgs.NoForwarding)) + debug_write("__security_cfg, before, WmmCapable="..tostring(cfgs.WmmCapable)) + debug_write("__security_cfg, before, TxRate="..tostring(cfgs.TxRate)) + debug_write("__security_cfg, before, RekeyInterval="..tostring(cfgs.RekeyInterval)) + debug_write("__security_cfg, before, AuthMode="..tostring(cfgs.AuthMode)) + debug_write("__security_cfg, before, EncrypType="..tostring(cfgs.EncrypType)) + debug_write("__security_cfg, before, WscModeOption="..tostring(cfgs.WscModeOption)) + debug_write("__security_cfg, before, RekeyMethod="..tostring(cfgs.RekeyMethod)) + debug_write("__security_cfg, before, IEEE8021X="..tostring(cfgs.IEEE8021X)) + debug_write("__security_cfg, before, DefaultKeyID="..tostring(cfgs.DefaultKeyID)) + debug_write("__security_cfg, before, PMFMFPC="..tostring(cfgs.PMFMFPC)) + debug_write("__security_cfg, before, PMFMFPR="..tostring(cfgs.PMFMFPR)) + debug_write("__security_cfg, before, PMFSHA256="..tostring(cfgs.PMFSHA256)) + debug_write("__security_cfg, before, RADIUS_Server="..tostring(cfgs.RADIUS_Server)) + debug_write("__security_cfg, before, RADIUS_Port="..tostring(cfgs.RADIUS_Port)) + debug_write("__security_cfg, before, session_timeout_interval="..tostring(cfgs.session_timeout_interval)) + debug_write("__security_cfg, before, PMKCachePeriod="..tostring(cfgs.PMKCachePeriod)) + debug_write("__security_cfg, before, PreAuth="..tostring(cfgs.PreAuth)) + debug_write("__security_cfg, before, Wapiifname="..tostring(cfgs.Wapiifname)) + + -- Reset/Clear all necessary settings here. Later, these settings will be set as per AuthMode. + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "DISABLE") + cfgs.IEEE8021X = mtkwifi.token_set(cfgs.IEEE8021X, vif_idx, "0") + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "0") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "0") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + -- Update the settings which are not dependent on AuthMode + cfgs.HideSSID = mtkwifi.token_set(cfgs.HideSSID, vif_idx, http.formvalue("__hidessid") or "0") + cfgs.NoForwarding = mtkwifi.token_set(cfgs.NoForwarding, vif_idx, http.formvalue("__noforwarding") or "0") + cfgs.WmmCapable = mtkwifi.token_set(cfgs.WmmCapable, vif_idx, http.formvalue("__wmmcapable") or "0") + cfgs.TxRate = mtkwifi.token_set(cfgs.TxRate, vif_idx, http.formvalue("__txrate") or "0"); + cfgs.RekeyInterval = mtkwifi.token_set(cfgs.RekeyInterval, vif_idx, http.formvalue("__rekeyinterval") or "0"); + + local __authmode = http.formvalue("__authmode") or "Disable" + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, vif_idx, __authmode) + + if __authmode == "Disable" then + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, vif_idx, "OPEN") + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "NONE") + + elseif __authmode == "OPEN" or __authmode == "SHARED" or __authmode == "WEPAUTO" then + cfgs.WscModeOption = "0" + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "WEP") + cfgs = conf_wep_keys(cfgs,vif_idx) + + elseif __authmode == "Enhanced Open" then + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, vif_idx, "OWE") + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "AES") + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "1") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "1") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + elseif __authmode == "WPAPSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__encrypttype") or "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + + elseif __authmode == "WPAPSKWPA2PSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__encrypttype") or "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + cfgs.WpaMixPairCipher = "WPA_TKIP_WPA2_AES" + + elseif __authmode == "WPA2PSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__encrypttype") or "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, http.formvalue("__pmfmfpc") or "0") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, http.formvalue("__pmfmfpr") or "0") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, http.formvalue("__pmfsha256") or "0") + + elseif __authmode == "WPA3PSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "1") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "1") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + elseif __authmode == "WPA2PSKWPA3PSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "1") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "0") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + elseif __authmode == "WPA2" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__encrypttype") or "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + cfgs.RADIUS_Server = mtkwifi.token_set(cfgs.RADIUS_Server, vif_idx, http.formvalue("__radius_server") or "0") + cfgs.RADIUS_Port = mtkwifi.token_set(cfgs.RADIUS_Port, vif_idx, http.formvalue("__radius_port") or "0") + cfgs.session_timeout_interval = mtkwifi.token_set(cfgs.session_timeout_interval, vif_idx, http.formvalue("__session_timeout_interval") or "0") + cfgs.PMKCachePeriod = mtkwifi.token_set(cfgs.PMKCachePeriod, vif_idx, http.formvalue("__pmkcacheperiod") or "0") + cfgs.PreAuth = mtkwifi.token_set(cfgs.PreAuth, vif_idx, http.formvalue("__preauth") or "0") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, http.formvalue("__pmfmfpc") or "0") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, http.formvalue("__pmfmfpr") or "0") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, http.formvalue("__pmfsha256") or "0") + + elseif __authmode == "WPA3" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + cfgs.RADIUS_Server = mtkwifi.token_set(cfgs.RADIUS_Server, vif_idx, http.formvalue("__radius_server") or "0") + cfgs.RADIUS_Port = mtkwifi.token_set(cfgs.RADIUS_Port, vif_idx, http.formvalue("__radius_port") or "0") + cfgs.session_timeout_interval = mtkwifi.token_set(cfgs.session_timeout_interval, vif_idx, http.formvalue("__session_timeout_interval") or "0") + cfgs.PMKCachePeriod = mtkwifi.token_set(cfgs.PMKCachePeriod, vif_idx, http.formvalue("__pmkcacheperiod") or "0") + cfgs.PreAuth = mtkwifi.token_set(cfgs.PreAuth, vif_idx, http.formvalue("__preauth") or "0") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "1") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "1") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + elseif __authmode == "WPA3-192-bit" then + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, vif_idx, "WPA3-192") + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "GCMP256") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + cfgs.RADIUS_Server = mtkwifi.token_set(cfgs.RADIUS_Server, vif_idx, http.formvalue("__radius_server") or "0") + cfgs.RADIUS_Port = mtkwifi.token_set(cfgs.RADIUS_Port, vif_idx, http.formvalue("__radius_port") or "0") + cfgs.session_timeout_interval = mtkwifi.token_set(cfgs.session_timeout_interval, vif_idx, http.formvalue("__session_timeout_interval") or "0") + cfgs.PMKCachePeriod = mtkwifi.token_set(cfgs.PMKCachePeriod, vif_idx, http.formvalue("__pmkcacheperiod") or "0") + cfgs.PreAuth = mtkwifi.token_set(cfgs.PreAuth, vif_idx, http.formvalue("__preauth") or "0") + -- for DOT11W_PMF_SUPPORT + cfgs.PMFMFPC = mtkwifi.token_set(cfgs.PMFMFPC, vif_idx, "1") + cfgs.PMFMFPR = mtkwifi.token_set(cfgs.PMFMFPR, vif_idx, "1") + cfgs.PMFSHA256 = mtkwifi.token_set(cfgs.PMFSHA256, vif_idx, "0") + + elseif __authmode == "WPA1WPA2" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__encrypttype") or "AES") + cfgs.RekeyMethod = mtkwifi.token_set(cfgs.RekeyMethod, vif_idx, "TIME") + cfgs.RADIUS_Server = mtkwifi.token_set(cfgs.RADIUS_Server, vif_idx, http.formvalue("__radius_server") or "0") + cfgs.RADIUS_Port = mtkwifi.token_set(cfgs.RADIUS_Port, vif_idx, http.formvalue("__radius_port") or "1812") + cfgs.session_timeout_interval = mtkwifi.token_set(cfgs.session_timeout_interval, vif_idx, http.formvalue("__session_timeout_interval") or "0") + cfgs.PMKCachePeriod = mtkwifi.token_set(cfgs.PMKCachePeriod, vif_idx, http.formvalue("__pmkcacheperiod") or "0") + cfgs.PreAuth = mtkwifi.token_set(cfgs.PreAuth, vif_idx, http.formvalue("__preauth") or "0") + + elseif __authmode == "IEEE8021X" then + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, vif_idx, "OPEN") + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, http.formvalue("__8021x_wep") and "WEP" or "NONE") + cfgs.IEEE8021X = mtkwifi.token_set(cfgs.IEEE8021X, vif_idx, "1") + cfgs.RADIUS_Server = mtkwifi.token_set(cfgs.RADIUS_Server, vif_idx, http.formvalue("__radius_server") or "0") + cfgs.RADIUS_Port = mtkwifi.token_set(cfgs.RADIUS_Port, vif_idx, http.formvalue("__radius_port") or "0") + cfgs.session_timeout_interval = mtkwifi.token_set(cfgs.session_timeout_interval, vif_idx, http.formvalue("__session_timeout_interval") or "0") + + elseif __authmode == "WAICERT" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "SMS4") + cfgs.Wapiifname = mtkwifi.token_set(cfgs.Wapiifname, vif_idx, "br-lan") + -- cfgs.wapicert_asipaddr + -- cfgs.WapiAsPort + -- cfgs.wapicert_ascert + -- cfgs.wapicert_usercert + + elseif __authmode == "WAIPSK" then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, vif_idx, "SMS4") + -- cfgs.wapipsk_keytype + -- cfgs.wapipsk_prekey + end + + debug_write("__security_cfg, after, HideSSID="..tostring(cfgs.HideSSID)) + debug_write("__security_cfg, after, NoForwarding="..tostring(cfgs.NoForwarding)) + debug_write("__security_cfg, after, WmmCapable="..tostring(cfgs.WmmCapable)) + debug_write("__security_cfg, after, TxRate="..tostring(cfgs.TxRate)) + debug_write("__security_cfg, after, RekeyInterval="..tostring(cfgs.RekeyInterval)) + debug_write("__security_cfg, after, AuthMode="..tostring(cfgs.AuthMode)) + debug_write("__security_cfg, after, EncrypType="..tostring(cfgs.EncrypType)) + debug_write("__security_cfg, after, WscModeOption="..tostring(cfgs.WscModeOption)) + debug_write("__security_cfg, after, RekeyMethod="..tostring(cfgs.RekeyMethod)) + debug_write("__security_cfg, after, IEEE8021X="..tostring(cfgs.IEEE8021X)) + debug_write("__security_cfg, after, DefaultKeyID="..tostring(cfgs.DefaultKeyID)) + debug_write("__security_cfg, after, PMFMFPC="..tostring(cfgs.PMFMFPC)) + debug_write("__security_cfg, after, PMFMFPR="..tostring(cfgs.PMFMFPR)) + debug_write("__security_cfg, after, PMFSHA256="..tostring(cfgs.PMFSHA256)) + debug_write("__security_cfg, after, RADIUS_Server="..tostring(cfgs.RADIUS_Server)) + debug_write("__security_cfg, after, RADIUS_Port="..tostring(cfgs.RADIUS_Port)) + debug_write("__security_cfg, after, session_timeout_interval="..tostring(cfgs.session_timeout_interval)) + debug_write("__security_cfg, after, PMKCachePeriod="..tostring(cfgs.PMKCachePeriod)) + debug_write("__security_cfg, after, PreAuth="..tostring(cfgs.PreAuth)) + debug_write("__security_cfg, after, Wapiifname="..tostring(cfgs.Wapiifname)) +end + +function initialize_multiBssParameters(cfgs,vif_idx) + cfgs["WPAPSK"..vif_idx]="12345678" + cfgs["Key1Type"]=mtkwifi.token_set(cfgs["Key1Type"],vif_idx,"0") + cfgs["Key2Type"]=mtkwifi.token_set(cfgs["Key2Type"],vif_idx,"0") + cfgs["Key3Type"]=mtkwifi.token_set(cfgs["Key3Type"],vif_idx,"0") + cfgs["Key4Type"]=mtkwifi.token_set(cfgs["Key4Type"],vif_idx,"0") + cfgs["RADIUS_Server"]=mtkwifi.token_set(cfgs["RADIUS_Server"],vif_idx,"0") + cfgs["RADIUS_Port"]=mtkwifi.token_set(cfgs["RADIUS_Port"],vif_idx,"1812") + cfgs["RADIUS_Key"..vif_idx]="ralink" + cfgs["DefaultKeyID"]=mtkwifi.token_set(cfgs["DefaultKeyID"],vif_idx,"1") + cfgs["IEEE8021X"]=mtkwifi.token_set(cfgs["IEEE8021X"],vif_idx,"0") + cfgs["WscConfMode"]=mtkwifi.token_set(cfgs["WscConfMode"],vif_idx,"0") + cfgs["PreAuth"]=mtkwifi.token_set(cfgs["PreAuth"],vif_idx,"0") + return cfgs +end + +function __wps_ap_pbc_start_all(ifname) + os.execute("iwpriv "..ifname.." set WscMode=2"); + os.execute("iwpriv "..ifname.." set WscGetConf=1"); +end + +function __wps_ap_pin_start_all(ifname, pincode) + os.execute("iwpriv "..ifname.." set WscMode=1") + os.execute("iwpriv "..ifname.." set WscPinCode="..pincode) + os.execute("iwpriv "..ifname.." set WscGetConf=1") +end + +function __apply_wifi_wpsconf(devs, devname, cfgs, diff) + local saved = cfgs.WscConfMode and cfgs.WscConfMode:gsub(";-(%d);-","%1") or "" + local applied = diff.WscConfMode and diff["WscConfMode"][2]:gsub(";-(%d);-","%1") or "" + local num_ifs = tonumber(cfgs.BssidNum) or 0 + + for idx=1, num_ifs do + local ifname = devs[devname]["vifs"][idx]["vifname"] + if mtkwifi.__any_wsc_enabled(saved:sub(idx,idx)) == 1 then + cfgs.WscConfStatus = mtkwifi.token_set(cfgs.WscConfStatus, idx, "2") + else + cfgs.WscConfStatus = mtkwifi.token_set(cfgs.WscConfStatus, idx, "1") + end + if (diff.WscConfMode) and saved:sub(idx,idx) ~= applied:sub(idx,idx) then + cfgs = mtkwifi.__restart_if_wps(devname, ifname, cfgs) + end + end + + -- __mtkwifi_save_profile() is called outside the loop because it is a high time consuming function. + __mtkwifi_save_profile(cfgs, devs[devname]["profile"], false) + +end + +function __set_wifi_wpsconf(cfgs, wsc_enable, vif_idx) + debug_write("__set_wifi_wpsconf : wsc_enable = ",wsc_enable) + if(wsc_enable == "1") then + cfgs["WscConfMode"] = mtkwifi.token_set(cfgs["WscConfMode"], vif_idx, "7") + else + cfgs["WscConfMode"] = mtkwifi.token_set(cfgs["WscConfMode"], vif_idx, "0") + end + if(((http.formvalue("__authmode")=="OPEN") and + (http.formvalue("__encrypttype") == "WEP")) or + (http.formvalue("__hidessid") == "1")) then + cfgs.WscConfMode = mtkwifi.token_set(cfgs.WscConfMode, vif_idx, "0") + end + debug_write("__set_wifi_wpsconf : WscConfMode = ",cfgs["WscConfMode"]) +end + +function __update_mbss_para(cfgs, vif_idx) + debug_write(vif_idx) + cfgs.HT_STBC = mtkwifi.token_set(cfgs.HT_STBC, vif_idx, http.formvalue("__ht_stbc") or "0") + cfgs.HT_LDPC = mtkwifi.token_set(cfgs.HT_LDPC, vif_idx, http.formvalue("__ht_ldpc") or "0") + cfgs.VHT_STBC = mtkwifi.token_set(cfgs.VHT_STBC, vif_idx, http.formvalue("__vht_stbc") or "0") + cfgs.VHT_LDPC = mtkwifi.token_set(cfgs.VHT_LDPC, vif_idx, http.formvalue("__vht_ldpc") or "0") + cfgs.DLSCapable = mtkwifi.token_set(cfgs.DLSCapable, vif_idx, http.formvalue("__dls_capable") or "0") + cfgs.APSDCapable = mtkwifi.token_set(cfgs.APSDCapable, vif_idx, http.formvalue("__apsd_capable") or "0") + cfgs.FragThreshold = mtkwifi.token_set(cfgs.FragThreshold, vif_idx, http.formvalue("__frag_threshold") or "0") + cfgs.RTSThreshold = mtkwifi.token_set(cfgs.RTSThreshold, vif_idx, http.formvalue("__rts_threshold") or "0") + cfgs.VHT_SGI = mtkwifi.token_set(cfgs.VHT_SGI, vif_idx, http.formvalue("__vht_sgi") or "0") + cfgs.VHT_BW_SIGNAL = mtkwifi.token_set(cfgs.VHT_BW_SIGNAL, vif_idx, http.formvalue("__vht_bw_signal") or "0") + cfgs.HT_PROTECT = mtkwifi.token_set(cfgs.HT_PROTECT, vif_idx, http.formvalue("__ht_protect") or "0") + cfgs.HT_GI = mtkwifi.token_set(cfgs.HT_GI, vif_idx, http.formvalue("__ht_gi") or "0") + cfgs.HT_OpMode = mtkwifi.token_set(cfgs.HT_OpMode, vif_idx, http.formvalue("__ht_opmode") or "0") + cfgs.HT_AMSDU = mtkwifi.token_set(cfgs.HT_AMSDU, vif_idx, http.formvalue("__ht_amsdu") or "0") + cfgs.HT_AutoBA = mtkwifi.token_set(cfgs.HT_AutoBA, vif_idx, http.formvalue("__ht_autoba") or "0") + cfgs.IgmpSnEnable = mtkwifi.token_set(cfgs.IgmpSnEnable, vif_idx, http.formvalue("__igmp_snenable") or "0") + cfgs.WirelessMode = mtkwifi.token_set(cfgs.WirelessMode, vif_idx, http.formvalue("__wirelessmode") or "0") + cfgs.WdsEnable = mtkwifi.token_set(cfgs.WdsEnable, vif_idx, http.formvalue("__wdsenable") or "0") + cfgs.MuOfdmaDlEnable = mtkwifi.token_set(cfgs.MuOfdmaDlEnable, vif_idx, http.formvalue("__muofdma_dlenable") or "0") + cfgs.MuOfdmaUlEnable = mtkwifi.token_set(cfgs.MuOfdmaUlEnable, vif_idx, http.formvalue("__muofdma_ulenable") or "0") + cfgs.MuMimoDlEnable = mtkwifi.token_set(cfgs.MuMimoDlEnable, vif_idx, http.formvalue("__mumimo_dlenable") or "0") + cfgs.MuMimoUlEnable = mtkwifi.token_set(cfgs.MuMimoUlEnable, vif_idx, http.formvalue("__mumimo_ulenable") or "0") + +end + +function vif_cfg(dev, vif) + local devname, vifname = dev, vif + if not devname then devname = vif end + debug_write("devname="..devname) + debug_write("vifname="..(vifname or "")) + local devs = mtkwifi.get_all_devs() + local profile = devs[devname].profile + assert(profile) + + --local ssid_index; + --ssid_index = devs[devname]["vifs"][vifname].vifidx + + local cfgs = mtkwifi.load_profile(profile) + + for k,v in pairs(http.formvalue()) do + if type(v) == type("") or type(v) == type(0) then + nixio.syslog("debug", "post."..k.."="..tostring(v)) + else + nixio.syslog("debug", "post."..k.." invalid, type="..type(v)) + end + end + + -- sometimes vif_idx start from 0, like AccessPolicy0 + -- sometimes it starts from 1, like WPAPSK1. nice! + local vif_idx + local to_url + if http.formvalue("__action") == "vif_cfg_view" then + vif_idx = devs[devname]["vifs"][vifname].vifidx + debug_write("vif_idx=", vif_idx, devname, vifname) + to_url = luci.dispatcher.build_url("admin", "mtk", "wifi", "vif_cfg_view", devname, vifname) + elseif http.formvalue("__action") == "vif_add_view" then + cfgs.BssidNum = tonumber(cfgs.BssidNum) + 1 + vif_idx = tonumber(cfgs.BssidNum) + to_url = luci.dispatcher.build_url("admin", "mtk", "wifi") + -- initializing ; separated parameters for the new interface + cfgs = initialize_multiBssParameters(cfgs, vif_idx) + end + assert(vif_idx) + assert(to_url) + -- "__" should not be the prefix of a name if user wants to copy form value data directly to the dat file variable + for k,v in pairs(http.formvalue()) do + if type(v) ~= type("") and type(v) ~= type(0) then + nixio.syslog("err", "vif_cfg, invalid value type for "..k..","..type(v)) + elseif string.byte(k) ~= string.byte("_") then + debug_write("vif_cfg: Copying",k,v) + cfgs[k] = v or "" + end + end + + -- WDS + -- Update WdsXKey if respective WdsEncrypType is NONE + for i=0,3 do + if (cfgs["Wds"..i.."Key"] and cfgs["Wds"..i.."Key"] ~= "") and + ((not mtkwifi.token_get(cfgs["WdsEncrypType"],i+1,nil)) or + ("NONE" == mtkwifi.token_get(cfgs["WdsEncrypType"],i+1,nil))) then + cfgs["Wds"..i.."Key"] = "" + end + end + + cfgs["AccessPolicy"..vif_idx-1] = http.formvalue("__accesspolicy") + local t = mtkwifi.parse_mac(http.formvalue("__maclist")) + cfgs["AccessControlList"..vif_idx-1] = table.concat(t, ";") + + __security_cfg(cfgs, vif_idx) + __update_mbss_para(cfgs, vif_idx) + __set_wifi_wpsconf(cfgs, http.formvalue("WPSRadio"), vif_idx) + + __mtkwifi_save_profile(cfgs, profile, false) + if http.formvalue("__apply") then + mtkwifi.__run_in_child_env(__mtkwifi_reload, devname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",to_url)) + else + luci.http.redirect(to_url) + end +end + +function get_WPS_Info(devname, ifname) + local devs = mtkwifi.get_all_devs() + local ssid_index = devs[devname]["vifs"][ifname].vifidx + local profile = devs[devname].profile + assert(profile) + + local cfgs = mtkwifi.load_profile(profile) + + -- Create the applied settings backup file if it does not exist. + if not mtkwifi.exists(mtkwifi.__profile_applied_settings_path(profile)) then + os.execute("cp -f "..profile.." "..mtkwifi.__profile_applied_settings_path(profile)) + end + local applied_cfgs = mtkwifi.load_profile(mtkwifi.__profile_applied_settings_path(profile)) + + local WPS_details = {} + WPS_details = c_getCurrentWscProfile(ifname) + + if type(WPS_details) ~= "table" then + WPS_details["DRIVER_RSP"] = "NO" + else + WPS_details["DRIVER_RSP"] = "YES" + local isCfgsChanged = false -- To indicate that the settings have been changed by External Registrar. + local isBasicTabUpdateRequired = false + + if type(WPS_details["SSID"]) == "string" then + if applied_cfgs["SSID"..ssid_index] ~= WPS_details["SSID"] then + cfgs["SSID"..ssid_index] = WPS_details["SSID"] + isCfgsChanged = true + isBasicTabUpdateRequired = true + end + else + WPS_details["SSID"] = cfgs["SSID"..ssid_index] + end + + if type(WPS_details["AuthMode"]) == "string" then + local auth_mode_ioctl = WPS_details["AuthMode"]:gsub("%W",""):upper() + local auth_mode_applied = mtkwifi.token_get(applied_cfgs.AuthMode, ssid_index, "") + if auth_mode_applied ~= auth_mode_ioctl then + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, ssid_index, auth_mode_ioctl) + isCfgsChanged = true + isBasicTabUpdateRequired = true + end + else + WPS_details["AuthMode"] = mtkwifi.token_get(cfgs.AuthMode, ssid_index, "") + end + + if type(WPS_details["EncType"]) == "string" then + local enc_type_ioctl = WPS_details["EncType"]:upper() + local enc_type_applied = mtkwifi.token_get(applied_cfgs.EncrypType, ssid_index, "") + if enc_type_applied ~= enc_type_ioctl then + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, ssid_index, enc_type_ioctl) + isCfgsChanged = true + isBasicTabUpdateRequired = true + end + else + WPS_details["EncType"] = mtkwifi.token_get(cfgs.EncrypType, ssid_index, "") + end + + if type(WPS_details["WscWPAKey"]) == "string" then + if applied_cfgs["WPAPSK"..ssid_index] ~= WPS_details["WscWPAKey"] then + cfgs["WPAPSK"..ssid_index] = WPS_details["WscWPAKey"] + isCfgsChanged = true + isBasicTabUpdateRequired = true + end + else + WPS_details["WscWPAKey"] = cfgs["WPAPSK"..ssid_index] + end + + if type(WPS_details["DefKey"]) == "number" then + local def_key_applied = tonumber(mtkwifi.token_get(applied_cfgs.DefaultKeyID, ssid_index, "")) + if def_key_applied ~= WPS_details["DefKey"] then + cfgs.DefaultKeyID = mtkwifi.token_set(cfgs.DefaultKeyID, ssid_index, WPS_details["DefKey"]) + isCfgsChanged = true + end + else + WPS_details["DefKey"] = tonumber(mtkwifi.token_get(cfgs.DefaultKeyID, ssid_index, 0)) or "" + end + + if type(WPS_details["Conf"]) == "number" then + local wsc_conf_status_applied = tonumber(mtkwifi.token_get(applied_cfgs.WscConfStatus, ssid_index, "")) + if wsc_conf_status_applied ~= WPS_details["Conf"] then + cfgs.WscConfStatus = mtkwifi.token_set(cfgs.WscConfStatus, ssid_index, WPS_details["Conf"]) + isCfgsChanged = true + end + else + WPS_details["Conf"] = mtkwifi.token_get(cfgs.WscConfStatus, ssid_index, "") + end + + WPS_details["IS_BASIC_TAB_UPDATE_REQUIRED"] = isBasicTabUpdateRequired + + if isCfgsChanged then + -- Driver updates the *.dat file for following scenarios, + -- 1. When WPS Conf Status is not configured i.e. WscConfStatus is not set as 2, + -- and connection with a station is established i.e. where station acts as an External Registrar. + -- 2. When below settings are changed through External Registrar irrespective of WPS Conf Status + -- Update mtkwifi.__profile_applied_settings_path(profile) file with the + -- new settings to avoid display of "reload to apply changes" message. + applied_cfgs["WPAPSK"] = cfgs["WPAPSK"] + applied_cfgs["SSID"] = cfgs["SSID"] + applied_cfgs["SSID"..ssid_index] = cfgs["SSID"..ssid_index] + applied_cfgs["AuthMode"] = cfgs["AuthMode"] + applied_cfgs["EncrypType"] = cfgs["EncrypType"] + applied_cfgs["WPAPSK"..ssid_index] = cfgs["WPAPSK"..ssid_index] + applied_cfgs["DefaultKeyID"] = cfgs["DefaultKeyID"] + applied_cfgs["WscConfStatus"] = cfgs["WscConfStatus"] + mtkwifi.save_profile(applied_cfgs, mtkwifi.__profile_applied_settings_path(profile)) + end + end + http.write_json(WPS_details) +end + +function get_wifi_pin(ifname) + local pin = "" + pin = c_getApPin(ifname) + http.write_json(pin) +end + +function set_wifi_gen_pin(ifname,devname) + local devs = mtkwifi.get_all_devs() + local ssid_index = devs[devname]["vifs"][ifname].vifidx + local profile = devs[devname].profile + assert(profile) + + local cfgs = mtkwifi.load_profile(profile) + + os.execute("iwpriv "..ifname.." set WscGenPinCode") + + pin = c_getApPin(ifname) + cfgs["WscVendorPinCode"]=pin["genpincode"] + + --existing c code... done nothing for this segment as it read flash data and write to related .dat file. + -- no concept of nvram zones here + --if (nvram == RT2860_NVRAM) + -- do_system("ralink_init make_wireless_config rt2860"); + --else + -- do_system("ralink_init make_wireless_config rtdev"); + __mtkwifi_save_profile(cfgs, profile, true) + http.write_json(pin) +end + +function set_wifi_wps_oob(devname, ifname) + local SSID, mac = "" + local ssid_index = 0 + local devs = mtkwifi.get_all_devs() + local profile = devs[devname].profile + assert(profile) + + local cfgs = mtkwifi.load_profile(profile) + + ssid_index = devs[devname]["vifs"][ifname].vifidx + mac = c_get_macaddr(ifname) + + if (mac["macaddr"] ~= "") then + SSID = "RalinkInitAP"..(ssid_index-1).."_"..mac["macaddr"] + else + SSID = "RalinkInitAP"..(ssid_index-1).."_unknown" + end + + cfgs["SSID"..ssid_index]=SSID + cfgs.WscConfStatus = mtkwifi.token_set(cfgs.WscConfStatus, ssid_index, "1") + cfgs.AuthMode = mtkwifi.token_set(cfgs.AuthMode, ssid_index, "WPA2PSK") + cfgs.EncrypType = mtkwifi.token_set(cfgs.EncrypType, ssid_index, "AES") + cfgs.DefaultKeyID = mtkwifi.token_set(cfgs.DefaultKeyID, ssid_index, "2") + + cfgs["WPAPSK"..ssid_index]="12345678" + cfgs["WPAPSK"]="" + cfgs.IEEE8021X = mtkwifi.token_set(cfgs.IEEE8021X, ssid_index, "0") + + os.execute("iwpriv "..ifname.." set SSID="..SSID ) + debug_write("iwpriv "..ifname.." set SSID="..SSID ) + os.execute("iwpriv "..ifname.." set AuthMode=WPA2PSK") + debug_write("iwpriv "..ifname.." set AuthMode=WPA2PSK") + os.execute("iwpriv "..ifname.." set EncrypType=AES") + debug_write("iwpriv "..ifname.." set EncrypType=AES") + os.execute("iwpriv "..ifname.." set WPAPSK=12345678") + debug_write("iwpriv "..ifname.." set WPAPSK=12345678") + os.execute("iwpriv "..ifname.." set SSID="..SSID) + debug_write("iwpriv "..ifname.." set SSID="..SSID) + + cfgs = mtkwifi.__restart_if_wps(devname, ifname, cfgs) + __mtkwifi_save_profile(cfgs, profile, true) + + --mtkwifi.__run_in_child_env(__restart_all_daemons, devname, ifname) + + os.execute("iwpriv "..ifname.." set WscConfStatus=1") + debug_write("iwpriv "..ifname.." set WscConfStatus=1") + + local url_to_visit_after_reload = luci.dispatcher.build_url("admin", "mtk", "wifi", "vif_cfg_view", devname, ifname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",url_to_visit_after_reload)) +end + +function set_wifi_do_wps(ifname, devname, wsc_pin_code_w) + local devs = mtkwifi.get_all_devs() + local ssid_index = devs[devname]["vifs"][ifname].vifidx + local profile = devs[devname].profile + local wsc_mode = 0 + local wsc_conf_mode + assert(profile) + + local cfgs = mtkwifi.load_profile(profile) + + if(wsc_pin_code_w == "nopin") then + wsc_mode=2 + else + wsc_mode=1 + end + + wsc_conf_mode = mtkwifi.token_get(cfgs["WscConfMode"], ssid_index, nil) + + if (wsc_conf_mode == 0) then + print("{\"wps_start\":\"WPS_NOT_ENABLED\"}") + DBG_MSG("WPS is not enabled before do PBC/PIN.\n") + return + end + + if (wsc_mode == 1) then + __wps_ap_pin_start_all(ifname, wsc_pin_code_w) + + elseif (wsc_mode == 2) then + __wps_ap_pbc_start_all(ifname) + else + http.write_json("{\"wps_start\":\"NG\"}") + return + end + cfgs["WscStartIF"] = ifname + + http.write_json("{\"wps_start\":\"OK\"}") +end + +function get_wps_security(ifname, devname) + local devs = mtkwifi.get_all_devs() + local ssid_index = devs[devname]["vifs"][ifname].vifidx + local profile = devs[devname].profile + assert(profile) + local output = {} + local cfgs = mtkwifi.load_profile(profile) + + output["AuthMode"] = mtkwifi.token_get(cfgs.AuthMode,ssid_index) + output["IEEE8021X"] = mtkwifi.token_get(cfgs.IEEE8021X,ssid_index) + + http.write_json(output) +end + +function apcli_get_wps_status(ifname, devname) + local output = {} + local ssid_index = 0 + local devs = mtkwifi.get_all_devs() + local profile = devs[devname].profile + assert(profile) + + -- apcli interface has a different structure as compared to other vifs + ssid_index = devs[devname][ifname].vifidx + output = c_apcli_get_wps_status(ifname) + if (output.wps_port_secured == "YES") then + local cfgs = mtkwifi.load_profile(profile) + cfgs.ApCliSsid = mtkwifi.token_set(cfgs.ApCliSsid, ssid_index, output.enr_SSID) + cfgs.ApCliEnable = mtkwifi.token_set(cfgs.ApCliEnable, ssid_index, "1") + cfgs.ApCliAuthMode = mtkwifi.token_set(cfgs.ApCliAuthMode, ssid_index, output.enr_AuthMode) + cfgs.ApCliEncrypType = mtkwifi.token_set(cfgs.ApCliEncrypType, ssid_index, output.enr_EncrypType) + cfgs.ApCliDefaultKeyID = mtkwifi.token_set(cfgs.ApCliDefaultKeyID, ssid_index, output.enr_DefaultKeyID) + cfgs.Channel = mtkwifi.read_pipe("iwconfig "..ifname.." | grep Channel | cut -d = -f 2 | cut -d \" \" -f 1") + debug_write("iwconfig "..ifname.." | grep Channel | cut -d = -f 2 | cut -d \" \" -f 1") + + if(output.enr_EncrypType == "WEP") then + for i = 1, 4 do + cfgs["ApCliKey"..i.."Type"] = mtkwifi.token_set(cfgs["ApCliKey"..i.."Type"], ssid_index, output["Key"..i.."Type"]) + end + if(ssid_index == "0") then + cfgs["ApCliKey"..output.enr_DefaultKeyID.."Str"] = output.enr_KeyStr + else + cfgs["ApCliKey"..output.enr_DefaultKeyID.."Str"..ssid_index] = output.enr_KeyStr + end + elseif(output.enr_EncrypType == "TKIP") or (output.enr_EncrypType == "AES") or (output.enr_EncrypType == "TKIPAES") then + if(output.enr_AuthMode ~= "WPAPSKWPA2PSK") then + cfgs["ApCliWPAPSK"] = output.enr_WPAPSK + end + end + __mtkwifi_save_profile(cfgs, profile, true) + end + http.write_json(output); +end + +function string.tohex(str) + return (str:gsub('.', function (c) + return string.format('%02X', string.byte(c)) + end)) +end + +function unencode_ssid(raw_ssid) + local c + local output = "" + local convertNext = 0 + for c in raw_ssid:gmatch"." do + if(convertNext == 0) then + if(c == '+') then + output = output..' ' + elseif(c == '%') then + convertNext = 1 + else + output = output..c + end + else + output = output..string.tohex(c) + convertNext = 0 + end + end + return output +end + +function decode_ssid(raw_ssid) + local output = raw_ssid + output = output:gsub("&", "&") + output = output:gsub("<", "<") + output = output:gsub(">", ">") + output = output:gsub(""", "\"") + output = output:gsub("'", "'") + output = output:gsub(" ", " ") + for codenum in raw_ssid:gmatch("&#(%d+);") do + output = output:gsub("&#"..codenum..";", string.char(tonumber(codenum))) + end + return output +end + +function apcli_do_enr_pin_wps(ifname, devname, raw_ssid) + local target_ap_ssid = "" + local ret_value = {} + if(raw_ssid == "") then + ret_value["apcli_do_enr_pin_wps"] = "GET_SSID_NG" + end + ret_value["raw_ssid"] = raw_ssid + target_ap_ssid = decode_ssid(raw_ssid) + target_ap_ssid = ''..mtkwifi.__handleSpecialChars(target_ap_ssid) + ret_value["target_ap_ssid"] = target_ap_ssid + if(target_ap_ssid == "") then + ret_value["apcli_do_enr_pin_wps"] = "GET_SSID_NG" + else + ret_value["apcli_do_enr_pin_wps"] = "OK" + end + os.execute("ifconfig "..ifname.." up") + debug_write("ifconfig "..ifname.." up") + os.execute("brctl addif br0 "..ifname) + debug_write("brctl addif br0 "..ifname) + os.execute("brctl addif br-lan "..ifname) + debug_write("brctl addif br-lan "..ifname) + os.execute("iwpriv "..ifname.." set ApCliAutoConnect=1") + os.execute("iwpriv "..ifname.." set ApCliEnable=1") + debug_write("iwpriv "..ifname.." set ApCliEnable=1") + --os.execute("iwpriv "..ifname.." set WscConfMode=0") + os.execute("iwpriv "..ifname.." set WscConfMode=1") + debug_write("iwpriv "..ifname.." set WscConfMode=1") + os.execute("iwpriv "..ifname.." set WscMode=1") + debug_write("iwpriv "..ifname.." set WscMode=1") + os.execute("iwpriv "..ifname.." set ApCliWscSsid=\""..target_ap_ssid.."\"") + debug_write("iwpriv "..ifname.." set ApCliWscSsid=\""..target_ap_ssid.."\"") + os.execute("iwpriv "..ifname.." set WscGetConf=1") + debug_write("iwpriv "..ifname.." set WscGetConf=1") + -- check interface value to correlate with nvram as values will be like apclixxx + http.write_json(ret_value) +end + +function apcli_do_enr_pbc_wps(ifname, devname) + local ret_value = {} + + --os.execute("iwpriv "..ifname.." set ApCliAutoConnect=1") + --os.execute("iwpriv "..ifname.." set ApCliEnable=1") + --os.execute("ifconfig "..ifname.." up") + --os.execute("brctl addif br0 "..ifname) + --os.execute("iwpriv "..ifname.." set WscConfMode=0") + os.execute("iwpriv "..ifname.." set WscConfMode=1") + os.execute("iwpriv "..ifname.." set WscMode=2") + os.execute("iwpriv "..ifname.." set WscGetConf=1") + -- check interface value to correlate with nvram as values will be like apclixxx + + --debug_write("iwpriv "..ifname.." set ApCliEnable=1") + --debug_write("brctl addif br0 "..ifname) + --debug_write("ifconfig "..ifname.." up") + debug_write("iwpriv "..ifname.." set WscConfMode=1") + debug_write("iwpriv "..ifname.." set WscMode=2") + debug_write("iwpriv "..ifname.." set WscGetConf=1") + ret_value["apcli_do_enr_pbc_wps"] = "OK" + http.write_json(ret_value) +end + +function apcli_cancel_wps(ifname) + local ret_value = {} + os.execute("iwpriv "..ifname.." set WscStop=1") + -- os.execute("miniupnpd.sh init") + -- check interface value to correlate with nvram as values will be like apclixxx + ret_value["apcli_cancel_wps"] = "OK" + http.write_json(ret_value) +end + +function apcli_wps_gen_pincode(ifname) + local ret_value = {} + os.execute("iwpriv "..ifname.." set WscGenPinCode") + ret_value["apcli_wps_gen_pincode"] = "OK" + http.write_json(ret_value) +end + +function apcli_wps_get_pincode(ifname) + local output = c_apcli_wps_get_pincode(ifname) + http.write_json(output) +end + +function get_apcli_conn_info(ifname) + local rsp = {} + if not ifname then + rsp["conn_state"]="Disconnected" + else + local flags = tonumber(mtkwifi.read_pipe("cat /sys/class/net/"..ifname.."/flags 2>/dev/null")) or 0 + rsp["infc_state"] = flags%2 == 1 and "up" or "down" + local iwapcli = mtkwifi.read_pipe("iwconfig "..ifname.." | grep ESSID 2>/dev/null") + local ssid = string.match(iwapcli, "ESSID:\"(.*)\"") + iwapcli = mtkwifi.read_pipe("iwconfig "..ifname.." | grep 'Access Point' 2>/dev/null") + local bssid = string.match(iwapcli, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") + if not ssid or ssid == "" then + rsp["conn_state"]= "Disconnected" + else + rsp["conn_state"] = "Connected" + rsp["ssid"] = ssid + rsp["bssid"] = bssid or "N/A" + end + end + http.write_json(rsp) +end + +function sta_info(ifname) + local output = {} + local stalist = c_StaInfo(ifname) + + local count = 0 + for _ in pairs(stalist) do count = count + 1 end + + for i=0, count - 1 do + table.insert(output, stalist[i]) + end + http.write_json(output) +end + +function apcli_scan(ifname) + local aplist = mtkwifi.scan_ap(ifname) + local convert=""; + for i=1, #aplist do + convert = c_convert_string_display(aplist[i]["ssid"]) + aplist[i]["original_ssid"] = aplist[i]["ssid"] + aplist[i]["ssid"] = convert["output"] + end + http.write_json(aplist) +end + +function get_station_list() + http.write("get_station_list") +end + +function reset_wifi(devname) + if devname then + os.execute("cp -f /rom/etc/wireless/"..devname.."/ /etc/wireless/") + else + os.execute("cp -rf /rom/etc/wireless /etc/") + end + return luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + +function reload_wifi(devname) + profiles = mtkwifi.search_dev_and_profile() + path = profiles[devname] + if mtkwifi.exists("/tmp/mtk/wifi/"..string.match(path, "([^/]+)\.dat")..".last") then + os.execute("rm -rf /tmp/mtk/wifi/"..string.match(path, "([^/]+)\.dat")..".last") + end + mtkwifi.__run_in_child_env(__mtkwifi_reload, devname) + local url_to_visit_after_reload = luci.dispatcher.build_url("admin", "mtk", "wifi") + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",url_to_visit_after_reload)) +end + +function get_raw_profile() + local sid = http.formvalue("sid") + http.write_json("get_raw_profile") +end + +function get_country_region_list() + local mode = http.formvalue("mode") + local cr_list; + + if mtkwifi.band(mode) == "5G" then + cr_list = mtkwifi.CountryRegionList_5G_All + elseif mtkwifi.band(mode) == "6G" then + cr_list = mtkwifi.CountryRegionList_6G_All + else + cr_list = mtkwifi.CountryRegionList_2G_All + end + + http.write_json(cr_list) +end + +function remove_ch_by_region(ch_list, region) + for i = #ch_list,2,-1 do + if not ch_list[i].region[region] then + table.remove(ch_list, i) + end + end +end + +function get_channel_list() + local mode = http.formvalue("mode") + local region = tonumber(http.formvalue("country_region")) or 1 + local ch_list + + if mtkwifi.band(mode) == "5G" then + ch_list = mtkwifi.ChannelList_5G_All + elseif mtkwifi.band(mode) == "6G" then + ch_list = mtkwifi.ChannelList_6G_All + else + ch_list = mtkwifi.ChannelList_2G_All + end + + remove_ch_by_region(ch_list, region) + http.write_json(ch_list) +end + +function get_HT_ext_channel_list() + local mode = http.formvalue("mode") + local ch_cur = tonumber(http.formvalue("ch_cur")) + local region = tonumber(http.formvalue("country_region")) or 1 + local ext_ch_list = {} + + if mtkwifi.band(mode) == "6G" then -- 6G Channel + local ch_list = mtkwifi.ChannelList_6G_All + local ext_ch_idx = -1 + local len = 0 + + for k, v in ipairs(ch_list) do + len = len + 1 + if v.channel == ch_cur then + ext_ch_idx = (k % 2 == 0) and k + 1 or k - 1 + end + end + + if ext_ch_idx > 0 and ext_ch_idx < len and ch_list[ext_ch_idx].region[region] then + ext_ch_list[1] = {} + ext_ch_list[1].val = ext_ch_idx % 2 + ext_ch_list[1].text = ch_list[ext_ch_idx].text + end + + elseif mtkwifi.band(mode) == "2.4G" then -- 2.4G Channel + local ch_list = mtkwifi.ChannelList_2G_All + local below_ch = ch_cur - 4 + local above_ch = ch_cur + 4 + local i = 1 + + if below_ch > 0 and ch_list[below_ch + 1].region[region] then + ext_ch_list[i] = {} + ext_ch_list[i].val = 0 + ext_ch_list[i].text = ch_list[below_ch + 1].text + i = i + 1 + end + + if above_ch <= 14 and ch_list[above_ch + 1].region[region] then + ext_ch_list[i] = {} + ext_ch_list[i].val = 1 + ext_ch_list[i].text = ch_list[above_ch + 1].text + end + else -- 5G Channel + local ch_list = mtkwifi.ChannelList_5G_All + local ext_ch_idx = -1 + local len = 0 + + for k, v in ipairs(ch_list) do + len = len + 1 + if v.channel == ch_cur then + ext_ch_idx = (k % 2 == 0) and k + 1 or k - 1 + end + end + + if ext_ch_idx > 0 and ext_ch_idx < len and ch_list[ext_ch_idx].region[region] then + ext_ch_list[1] = {} + ext_ch_list[1].val = ext_ch_idx % 2 + ext_ch_list[1].text = ch_list[ext_ch_idx].text + end + end + + http.write_json(ext_ch_list) +end + +function get_5G_2nd_80Mhz_channel_list() + local ch_cur = tonumber(http.formvalue("ch_cur")) + local region = tonumber(http.formvalue("country_region")) + local ch_list = mtkwifi.ChannelList_5G_2nd_80MHZ_ALL + local ch_list_5g = mtkwifi.ChannelList_5G_All + local i, j, test_ch, test_idx + local bw80_1st_idx = -1 + + -- remove adjacent freqencies starting from list tail. + for i = #ch_list,1,-1 do + for j = 0,3 do + if ch_list[i].channel == -1 then + break + end + + test_ch = ch_list[i].channel + j * 4 + test_idx = ch_list[i].chidx + j + + if test_ch == ch_cur then + if i + 1 <= #ch_list and ch_list[i + 1] then + table.remove(ch_list, i + 1) + end + table.remove(ch_list, i) + bw80_1st_idx = i + break + end + + if i == (bw80_1st_idx - 1) or (not ch_list_5g[test_idx].region[region]) then + table.remove(ch_list, i) + break + end + end + end + + -- remove unused channel. + for i = #ch_list,1,-1 do + if ch_list[i].channel == -1 then + table.remove(ch_list, i) + end + end + http.write_json(ch_list) +end + +function net_cfg() + http.write_json(http.formvalue()) +end + +function apcli_cfg(dev, vif) + local devname = dev + debug_write(devname) + local profiles = mtkwifi.search_dev_and_profile() + debug_write(profiles[devname]) + assert(profiles[devname]) + + local cfgs = mtkwifi.load_profile(profiles[devname]) + + for k,v in pairs(http.formvalue()) do + if type(v) ~= type("") and type(v) ~= type(0) then + nixio.syslog("err", "apcli_cfg, invalid value type for "..k..","..type(v)) + elseif string.byte(k) ~= string.byte("_") then + cfgs[k] = v or "" + end + end + + -- http.write_json(http.formvalue()) + + -- Mediatek Adaptive Network + --[=[ moved to a separated page + if cfgs.ApCliEzEnable then + cfgs.EzEnable = cfgs.ApCliEzEnable + cfgs.ApMWDS = cfgs.ApCliMWDS + cfgs.EzConfStatus = cfgs.ApCliEzConfStatus + cfgs.EzOpenGroupID = cfgs.ApCliEzOpenGroupID + if http.formvalue("__group_id_mode") == "0" then + cfgs.EzGroupID = cfgs.ApCliEzGroupID + cfgs.EzGenGroupID = "" + cfgs.ApCliEzGenGroupID = "" + else + cfgs.EzGroupID = "" + cfgs.ApCliEzGroupID = "" + cfgs.EzGenGroupID = cfgs.ApCliEzGenGroupID + end + -- if dbdc + -- os.execute("app_ez &") + -- os.execute("ManDaemon ") + end + ]=] + __mtkwifi_save_profile(cfgs, profiles[devname], false) + + -- M.A.N Push parameters + -- They are not part of wifi profile, we save it into /etc/man.conf. + + --[=[ moved to a separated page + local man_ssid = http.formvalue("__man_ssid_"..vifname) + local man_pass = http.formvalue("__man_pass_"..vifname) + local man_auth = http.formvalue("__man_auth_"..vifname) or "" + + if man_ssid and man_pass then + local fp = io.open("/etc/man."..vifname..".conf", "w+") + fp:write("__man_ssid_"..vifname.."="..man_ssid.."\n") + fp:write("__man_pass_"..vifname.."="..man_pass.."\n") + fp:write("__man_auth_"..vifname.."="..man_auth.."\n") + fp:close() + end + ]=] + + -- commented, do not connect by default + --[=[ + os.execute("iwpriv apcli0 set ApCliEnable=0") + os.execute("iwpriv apcli0 set Channel="..cfgs.Channel) + os.execute("iwpriv apcli0 set ApCliAuthMode="..cfgs.ApCliAuthMode) + os.execute("iwpriv apcli0 set ApCliEncrypType="..cfgs.ApCliEncrypType) + if cfgs.ApCliAuthMode == "WEP" then + os.execute("#iwpriv apcli0 set ApCliDefaultKeyID="..cfgs.ApCliDefaultKeyID) + os.execute("#iwpriv apcli0 set ApCliKey1="..cfgs.ApCliKey1Str) + elseif cfgs.ApCliAuthMode == "WPAPSK" + or cfgs.ApCliAuthMode == "WPA2PSK" + or cfgs.ApCliAuthMode == "WPAPSKWPA2PSK" then + os.execute("iwpriv apcli0 set ApCliWPAPSK="..cfgs.ApCliWPAPSK) + end + -- os.execute("iwpriv apcli0 set ApCliWirelessMode=") + os.execute("iwpriv apcli0 set ApCliSsid="..cfgs.ApCliSsid) + os.execute("iwpriv apcli0 set ApCliEnable=1") + ]=] + if http.formvalue("__apply") then + mtkwifi.__run_in_child_env(__mtkwifi_reload, devname) + local url_to_visit_after_reload = luci.dispatcher.build_url("admin", "mtk", "wifi", "apcli_cfg_view", dev, vif) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",url_to_visit_after_reload)) + else + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "apcli_cfg_view", dev, vif)) + end +end + +function apcli_connect(dev, vif) + -- dev_vif can be + -- 1. mt7620.apcli0 # simple case + -- 2. mt7615e.1.apclix0 # multi-card + -- 3. mt7615e.1.2G.apclix0 # multi-card & multi-profile + local devname,vifname = dev, vif + debug_write("devname=", dev, "vifname=", vif) + local profiles = mtkwifi.search_dev_and_profile() + debug_write(profiles[devname]) + assert(profiles[devname]) + local cfgs = mtkwifi.load_profile(profiles[devname]) + cfgs.ApCliEnable = "1" + __mtkwifi_save_profile(cfgs, profiles[devname], true) + os.execute("ifconfig "..vifname.." up") + os.execute("brctl addif br-lan "..vifname) + os.execute("iwpriv "..vifname.." set MACRepeaterEn="..cfgs.MACRepeaterEn) + os.execute("iwpriv "..vifname.." set ApCliEnable=0") + os.execute("iwpriv "..vifname.." set Channel="..cfgs.Channel) + os.execute("iwpriv "..vifname.." set ApCliAuthMode="..cfgs.ApCliAuthMode) + os.execute("iwpriv "..vifname.." set ApCliEncrypType="..cfgs.ApCliEncrypType) + if cfgs.ApCliEncrypType == "WEP" then + os.execute("iwpriv "..vifname.." set ApCliDefaultKeyID="..cfgs.ApCliDefaultKeyID) + if (cfgs.ApCliDefaultKeyID == "1") then + os.execute("iwpriv "..vifname.." set ApCliKey1=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliKey1Str).."\"") + elseif (cfgs.ApCliDefaultKeyID == "2") then + os.execute("iwpriv "..vifname.." set ApCliKey2=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliKey2Str).."\"") + elseif (cfgs.ApCliDefaultKeyID == "3") then + os.execute("iwpriv "..vifname.." set ApCliKey3=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliKey3Str).."\"") + elseif (cfgs.ApCliDefaultKeyID == "4") then + os.execute("iwpriv "..vifname.." set ApCliKey4=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliKey4Str).."\"") + end + elseif cfgs.ApCliAuthMode == "WPAPSK" + or cfgs.ApCliAuthMode == "WPA2PSK" + or cfgs.ApCliAuthMode == "WPAPSKWPA2PSK" then + os.execute("iwpriv "..vifname.." set ApCliWPAPSK=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliWPAPSK).."\"") + end + os.execute("iwpriv "..vifname.." set ApCliSsid=\""..mtkwifi.__handleSpecialChars(cfgs.ApCliSsid).."\"") + os.execute("iwpriv "..vifname.." set ApCliEnable=1") + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + +function apcli_disconnect(dev, vif) + -- dev_vif can be + -- 1. mt7620.apcli0 # simple case + -- 2. mt7615e.1.apclix0 # multi-card + -- 3. mt7615e.1.2G.apclix0 # multi-card & multi-profile + local devname,vifname = dev, vif + debug_write("devname=", dev, "vifname", vif) + debug_write(devname) + debug_write(vifname) + local profiles = mtkwifi.search_dev_and_profile() + debug_write(profiles[devname]) + assert(profiles[devname]) + local cfgs = mtkwifi.load_profile(profiles[devname]) + cfgs.ApCliEnable = "1" + __mtkwifi_save_profile(cfgs, profiles[devname], true) + os.execute("iwpriv "..vifname.." set ApCliEnable=0") + os.execute("ifconfig "..vifname.." down") + os.execute("brctl delif br-lan "..vifname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi")) +end + +function apply_power_boost_settings() + local devname = http.formvalue("__devname") + local ret_status = {} + local devs = mtkwifi.get_all_devs() + local dev = {} + for _,v in ipairs(devs) do + if v.devname == devname then + dev = v + break + end + end + if next(dev) == nil then + ret_status["status"]= "Device "..(devname or "").." not found!" + elseif not dev.isPowerBoostSupported then + ret_status["status"]= "Power Boost feature is not supported by "..(devname or "").." Device!" + else + local cfgs = mtkwifi.load_profile(dev.profile) + if type(cfgs) ~= "table" or next(cfgs) == nil then + ret_status["status"]= "Profile settings file not found!" + else + for k,v in pairs(http.formvalue()) do + if type(v) ~= type("") and type(v) ~= type(0) then + debug_write("ERROR: [apply_power_boost_settings] String expected; Got"..type(v).."for"..k.."key") + ret_status["status"]= "Power Boost settings are of incorrect type!" + break + elseif string.byte(k) ~= string.byte("_") then + cfgs[k] = v or "" + end + end + if next(ret_status) == nil then + if type(dev.vifs) ~= "table" or next(dev.vifs) == nil or not cfgs.BssidNum or cfgs.BssidNum == "0" then + ret_status["status"]= "No Wireless Interfaces has been added yet!" + elseif cfgs.PowerUpenable ~= "1" then + ret_status["status"]= "Power Boost feature is not enabled!" + else + local up_vif_name_list = {} + for idx,vif in ipairs(dev.vifs) do + if vif.state == "up" and vif.vifname ~= nil and vif.vifname ~= "" and type(vif.vifname) == "string" then + up_vif_name_list[idx] = vif.vifname + end + end + if next(up_vif_name_list) == nil then + ret_status["status"]= "No Wireless Interfaces is up!" + else + for _,vifname in ipairs(up_vif_name_list) do + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=0:"..cfgs.PowerUpCckOfdm) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=1:"..cfgs.PowerUpHT20) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=2:"..cfgs.PowerUpHT40) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=3:"..cfgs.PowerUpVHT20) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=4:"..cfgs.PowerUpVHT40) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=5:"..cfgs.PowerUpVHT80) + os.execute("iwpriv "..vifname.." set TxPowerBoostCtrl=6:"..cfgs.PowerUpVHT160) + os.execute("sleep 1") -- Wait for 1 second to let driver process the above data + end + __mtkwifi_save_profile(cfgs, dev.profile, true) + ret_status["status"]= "SUCCESS" + end + end + end + end + end + http.write_json(ret_status) +end + +function get_bssid_num(devName) + local ret_status = {} + local profiles = mtkwifi.search_dev_and_profile() + for dev,profile in pairs(profiles) do + if devName == dev then + local cfgs = mtkwifi.load_profile(profile) + if type(cfgs) ~= "table" or next(cfgs) == nil then + ret_status["status"]= "Profile settings file not found!" + else + ret_status["status"] = "SUCCESS" + ret_status["bssidNum"] = cfgs.BssidNum + end + break + end + end + if next(ret_status) == nil then + ret_status["status"]= "Device "..(devName or "").." not found!" + end + http.write_json(ret_status) +end + +local exec_reset_to_defaults_cmd = function (devname) + if devname then + os.execute("wifi reset "..devname) + else + os.execute("wifi reset") + end +end + +function reset_to_defaults(devname) + mtkwifi.__run_in_child_env(exec_reset_to_defaults_cmd, devname) + luci.http.redirect(luci.dispatcher.build_url("admin", "mtk", "wifi", "loading",mtkwifi.get_referer_url())) +end + diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apcli.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apcli.htm new file mode 100644 index 0000000000..3503b99456 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apcli.htm @@ -0,0 +1,1659 @@ + +<%+header%> + +<% +local disp = require "luci.dispatcher" +-- local request = disp.context.path +local request = disp.context.request +local mtkwifi = require("mtkwifi") +--local devname = string.match(request[5], "(mt.+)%.") +local devname = request[5] +local devs = mtkwifi.get_all_devs() +local dev = {} +local vif = {} +local vifidx +for _,v in ipairs(devs) do + if v.devname == devname then + dev = v + end +end + +local vifname = request[6] or dev.apcli.vifname +assert(vifname) +vif = dev and dev.vifs[vifname] or nil +vifidx = vif and vif.vifidx or nil +--print(devs, dev, dev.apcli, devname, vifname) + +local cfgs = mtkwifi.load_profile(dev.profile) +local map_cfgs +local first_card_cfgs +local appliedMapModeDiff + +%> + + + + + + + + +
+
" enctype="multipart/form-data" onreset="return cbi_validate_reset(this);" onsubmit="return validate_all() && cbi_validate_form(this, 'Some fields are invalid, cannot save values!')" autocomplete="off"> +
+ ApCli Configurations - <%=vifname and devname.."@"..vifname or devname%> + <%local diff = mtkwifi.diff_profile(dev.profile)%> + <%if next(diff) ~= nil then%> + ( '">Click here to apply changes) + <%end%> + + + + + + + + + + + +
+ + + Available Wireless Networks + + +

+ +

+
+ +
+
+
+ Connection Configurations + + + + + + + style="display:none;" <% end %> > + + + + + + + + + + + + + + + + + + + + + + style="display:none;"<% end %>> + + + + + + style="display:none;"<% end %>> + + + + + + style="display:none;" <% end %>> + + + + + + + + + + + style="display:none" <% end %> > + + + + + + style="display: none;"<% end %>> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ApClient Mode + checked="checked"<% end %> onclick="toggle_apcli(true)"/> Enable + checked="checked"<% end %> onclick="toggle_apcli(false)"/> Disable +
MAC Repeater Mode + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Root AP SSID + "/> +
Root AP Channel + + This will overwrite channel of AP!
Root AP Authentication Mode + +
Root AP Encryption + +
Root AP WPA Key + "/> +
ApCli MFPC + + checked="checked" + <% end %> + <% if cfgs.ApCliAuthMode == "WPA3PSK" then %> + disabled="disabled" + <% end %> + type="checkbox"> +
ApCli MFPR + + checked="checked" + <% end %> + <% if cfgs.ApCliAuthMode == "WPA3PSK" then %> + disabled="disabled" + <% end %> + type="checkbox"> +
ApCli MFPSHA256 + + checked="checked" + <% end %> + <% if cfgs.ApCliAuthMode == "WPA3PSK" then %> + disabled="disabled" + <% end %> + type="checkbox"> +
Root AP Encryption + +
WEP Default Key + +
Root AP WEP Key 1 + " maxlength="26"/> +
WEP Key 1 Type + +
Root AP WEP Key 2 + " maxlength="26"/> +
WEP Key 2 Type + +
Root AP WEP Key 3 + " maxlength="26"/> +
WEP Key 3 Type + +
Root AP WEP Key 4 + " maxlength="26"/> +
WEP Key 4 Type + +
+
+ + +
+ + + +
+
+
+
+ + + + + +<%+footer%> diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apply_reboot.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apply_reboot.htm new file mode 100644 index 0000000000..bf50265f38 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_apply_reboot.htm @@ -0,0 +1,67 @@ +<%# + File name : mtk_wifi_apply_reboot.htm + This file is used in WebUI based on LuCI to handle the reboot event. +%> +<%+header%> +

Reboot Device

+
+

+ As the driver does not support addition or deletion of interfaces on the fly, + the settings which were changed during addition or deletion of interfaces have not been applied yet! +

+ + The changed settings will be applied only after reboot of the device. + Please click on the Reboot button. + +

+ Tip:
+ Add or delete as many interfaces as required before reboot so that you do not have to reboot the device again.
+ Please follow below instructions to add or delete an interface;
+ 1. Go to Wireless Overview web-page.
+ 2. Click on Add button to add a new interface or click on Remove button to delete an existing interface.
+ 3. If you are are adding a new interface, then, click on Save button after filling out all the required fields such as SSID etc.
+ 4. Once you are done with addition/deletion of interfaces, then please click on Reload button or + Save and Apply button on any web-page which will redirect to this web-page to perform the reboot of the device.
+

+ +
+

+ + +<%+footer%> \ No newline at end of file diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_chip_cfg.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_chip_cfg.htm new file mode 100644 index 0000000000..b88f8fc56c --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_chip_cfg.htm @@ -0,0 +1,546 @@ +<%+header%> + + +<% +local disp = require "luci.dispatcher" +-- local request = disp.context.path +local request = disp.context.request +local mtkwifi = require("mtkwifi") +local devname = request[5] +local devs = mtkwifi.get_all_devs() +local dev = {} +for _,v in ipairs(devs) do + if v.devname == devname then + dev = v + end +end +local cfgs = mtkwifi.load_profile(dev.profile) +local map_cfgs +local first_card_cfgs +local appliedMapModeDiff +%> + + + + + +
" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, 'Some fields are invalid, cannot save values!') && ValidateAllSettings()" autocomplete="false"> +
+ Chip Configurations - <%=string.split(devname,".")[1]%> + <%local diff = mtkwifi.diff_profile(dev.profile)%> + <%if next(diff) ~= nil then%> + ( '">Click here to apply changes) + <%end%> + +
    +
  • + Basic +
  • + <% if cfgs["VOW_Airtime_Fairness_En"] then %> +
  • + VoW +
  • + <% end %> +
+ + + + + + + + + + + + + + + + + + + + + + <% if cfgs.WHNAT then %> + + + + + + <% end %> + <% if cfgs.E2pAccessMode then %> + + + + + + <% end %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Decline BA Request + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Reverse Direction Grant (RDG) + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
BA Win size + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> (range 1-256) <% else %> (range 1-64) <% end %> +
HT Disallow TKIP + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Wi-Fi HW NAT + + Supported by MT7615
E2pAccessMode + +
Beacon Interval + tu(range 20-999, default 100) +
Data Beacon Rate (DTIM) + Beacon interval(range 1-255, default 1) +
BG Protection Mode + +
Short Preamble + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
TX Burst + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Packet Aggregate + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Short Slot + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
+ + <% if cfgs["VOW_Airtime_Fairness_En"] then %> + + <% end %> + +
+ + + + + +
+ + + + +<%+footer%> diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_dev_cfg.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_dev_cfg.htm new file mode 100644 index 0000000000..e74fa9976d --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_dev_cfg.htm @@ -0,0 +1,1329 @@ + +<%+header%> + + +<% +local disp = require "luci.dispatcher" +-- local request = disp.context.path +local request = disp.context.request +local mtkwifi = require("mtkwifi") +local devname = request[5] +local devs = mtkwifi.get_all_devs() +local dev = {} +for _,v in ipairs(devs) do + if v.devname == devname then + dev = v + end +end +local cfgs = mtkwifi.load_profile(dev.profile) +local bands = mtkwifi.detect_triband() +local map_cfgs +local first_card_cfgs +local appliedMapModeDiff +%> + + + + + +
" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, 'Some fields are invalid, cannot save values!') && ValidateAllSettings()" autocomplete="false"> +
+ Device Configuration - <%=devname%> + <%local diff = mtkwifi.diff_profile(dev.profile)%> + <%if next(diff) ~= nil then%> + ( '">Click here to apply changes) + <%end%> + + + + + + + + + + + + + + + + + + + + + + + + + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> + + + + + + + + + + + + + + + + <% end %> + +
Channel + + <% if cfgs.ApCliEnable == "1" then %> APClient/Repeater Mode. <% end %>
BSS color + +
Co-located BSSID set max index + +
TWT Support + +
+ + + + + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> + + + + + + + + + + + + + + + + <% end %> + "> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% if mtkwifi.band(string.split(cfgs.WirelessMode,";")[1]) == "5G" then %> + + + + + + + + + + + <% end %> + + + + + + + + + + + <% if cfgs.MUTxRxEnable then %> + + + + + + <% end %> + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> + + + + + + <% end %> + + + <% if dev.isPowerBoostSupported then%> + + + + + + + style="display:none" <% end %>> + + + + + + + + + + + + + + <% end %> +
+
+ + + + + +
+
+ + +
" enctype="multipart/form-data" onreset="return cbi_validate_reset(this)" onsubmit="return cbi_validate_form(this, 'Some fields are invalid, cannot save values!')" autocomplete="off"> +
+ Raw Configurations ( Edit WiFi profile directly ) +

WARNING : DO NOT MESS WITH IT IF YOU DON'T UNDERSTAND IT!

+ +
+
+ '" type="button"> + + '"> +
+
+ + + + +<%+footer%> diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_loading.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_loading.htm new file mode 100644 index 0000000000..9a459f2e10 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_loading.htm @@ -0,0 +1,90 @@ +<%# + File name : mtk_wifi_loading.htm + This file is used in WebUI based on LuCI to handle the loading event. +%> +<%+header%> +<% +local disp = require "luci.dispatcher" +local request = disp.context.request +local url = "/"..table.concat(request,'/',5) +%> +

Applying Settings

+
+ + Please wait while the settings are being applied. +
+ + + +<%+footer%> \ No newline at end of file diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_overview.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_overview.htm new file mode 100644 index 0000000000..08acca6d11 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_overview.htm @@ -0,0 +1,510 @@ +<%+header%> + + + + +<% +local mtkwifi = require("mtkwifi") +local devs = mtkwifi.get_all_devs() +local l1dat, l1 = mtkwifi.__get_l1dat() +local dridx = l1.DEV_RINDEX +local main_ifname +local map_cfgs +local first_card_cfgs +local appliedMapModeDiff +local chipname +%> + + + +

Wireless Overview

+ + <% if #devs == 0 then %> +
+ No wireless device found! +
+ <% end %> + + <% for _,dev in ipairs(devs) do %> + <% main_ifname = l1dat and l1dat[dridx][dev.devname].main_ifname or dbdc_prefix[mainidx][subidx].."0" %> + <% if mtkwifi.exists("/sys/class/net/"..main_ifname) then %> +
+ + + + <% if chipname ~= string.split(dev.devname,".")[1].."."..(dev.mainidx) then %> + <% chipname = string.split(dev.devname,".")[1].."."..(dev.mainidx) %> + + + + + + <% end %> + + + + + + + <% if dev.vifs then%> + + <% for _,vif in ipairs(dev.vifs) do %> + + + + + + + <% end %> + + + <% if dev.apcli then %> + + + + + + + <% end %> + + <% end %> + +
+ + + <%=string.split(dev.devname,".")[1]%> + <%if not dev.vifs then%> + * FATAL ERROR: Incorrect Profile Settings + <%end%> +
+ Driver version: <%=dev.version%> +
+
"> + ','<%=luci.dispatcher.build_url("admin", "mtk", "wifi", "chip_cfg_view", dev.devname)%>')"> +
+
" style="display:none"> + Processing request. +
+
+ <%=dev.devname%> + <%local diff = mtkwifi.diff_profile(dev.profile)%> + <%if next(diff) ~= nil then%> + * need reload to apply changes + <%end%> +
+ Work mode: <% if dev.ApCliEnable == "1" then %> APCli <% else %> AP <% end %> +
+
+ <%if not dev.vifs then%> + ')"> + <%else%> + ')"> + ')"> + + <%end%> +
+ +
+ <% if vif.state == "up" then %> + + <% else %> + + <% end %> + + Interface: <%=vif.vifname%> | + Type: AP | + SSID: + + <% if vif.__ssid == "" then %> + Error: value not present in dat file + <% else %> + <%=vif.__ssid and vif.__ssid:gsub(" "," ") or nil%> <% end %> + | + Channel: + <%=vif.__channel or dev.Channel%> +
+ <% if vif.state == "up" then %> + BSSID: <%=vif.__bssid%> | Mode: <%=dev.WirelessModeList[tonumber(vif.__wirelessmode)]%> + <% else %> + Wireless is disabled or not associated + <% end %> +
+
+ <% if not vif.state then %> + + <% elseif vif.state == "up" then %> + ')"> + <% else %> + ')"> + <% end %> + ')"> + ')"> +
+ +
+ <% if dev.apcli.state == "up" then %> + + <% else %> + + <% end %> + Interface: <%=dev.apcli.devname%> | Type: STA | Status: <% if dev.ApCliEnable ~= "1" then %> Disconnected <% end %> +
+
style="display:none" <% end %>> + <%:Loading%>  Loading connection information of <%=dev.apcli.devname%> +
+ + style="display:none" <% end %>>Wireless is disabled or not associated +
+
+ <% if dev.ApCliEnable ~= "1" then %> + <% if dev.apcli.state == "up" then %> + ')"> + <% else %> + ')"> + <% end %> + ')"> + ')"> + <% else %> + ')"> + ')"> + ')"> + ')"> + ')"> + <% end %> +
+ +
+
+ <% end %> + <% end %> + + + + <%+footer%> diff --git a/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_vif_cfg.htm b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_vif_cfg.htm new file mode 100644 index 0000000000..5f66cae90a --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/luasrc/view/admin_mtk/mtk_wifi_vif_cfg.htm @@ -0,0 +1,2740 @@ + +<%+header%> + +<% +local disp = require "luci.dispatcher" +local path = disp.context.path +local request = disp.context.request +local mtkwifi = require("mtkwifi") +local devs = mtkwifi.get_all_devs() +local devname +local vifname, vifidx +local dev = {} +local vif = {} +if request[4] == "vif_add_view" then + devname, vifname = request[5], request[6] + dev = devs and devs[devname] + vifname = vifname..#dev.vifs + vifidx = #dev.vifs + 1 + +elseif request[4] == "vif_cfg_view" then + devname, vifname = request[5], request[6] + dev = devs and devs[devname] or nil + vif = dev and dev.vifs[vifname] or nil + vifidx = vif and vif.vifidx or nil +end + +local cfgs = mtkwifi.load_profile(dev.profile) +local diff = mtkwifi.diff_profile(dev.profile) +local WscValue = mtkwifi.token_get(cfgs["WscConfMode"], vifidx, "0") or "0" +local appliedWscValue = diff["WscConfMode"] and mtkwifi.token_get(diff["WscConfMode"][2], vifidx) or nil + +local map_cfgs +local first_card_cfgs = mtkwifi.load_profile(mtkwifi.detect_first_card()) +local appliedMapModeDiff + +local AuthModes = {} +local EncryptionTypeLists = {} +if string.split(cfgs.WirelessMode,";")[1] == "18" then + AuthModes = (WscValue == "0") and dev.AuthModeList_6G or dev.WpsEnableAuthModeList_6G + EncryptionTypeLists = dev.EncryptionTypeList_6G +else + AuthModes = (WscValue == "0") and dev.AuthModeList or dev.WpsEnableAuthModeList + EncryptionTypeLists = dev.EncryptionTypeList +end +%> + + + + + +
" enctype="multipart/form-data" onsubmit="return validate_all('<%=vifidx%>','<%=cfgs["HT_DisallowTKIP"]%>') && chk_WPS_ACL('<%=tostring(mtkwifi.__any_wsc_enabled(WscValue)) %>')" autocomplete="off"> +<% if not dev or not vif then%> +
+ Interface Not Exist - <%=vifname and devname.."@"..vifname or devname%> + +
+<% else %> + + <% if mtkwifi.band(vif.__wirelessmode or string.split(cfgs.WirelessMode,";")[1]) == "5G" or mtkwifi.band(vif.__wirelessmode or string.split(cfgs.WirelessMode,";")[1]) == "6G" then %> + + <% else %> + + <% end %> + +
+ Interface Configurations - <%=vifname and devname.."@"..vifname or devname%> + <%if next(diff) ~= nil then%> + ( '">Click here to apply changes) + <%end%> + + +
    +
  • + );this.blur(); ">Basic +
  • + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> +
  • + );this.blur(); ">HE_MU +
  • + <% end %> +
  • + );this.blur(); ">WPS +
  • + <% if map_cfgs then %> + <% if (not dev.wdsBand or dev.wdsBand == dev.dbdcBandName) and first_card_cfgs.MapMode ~= "1" then %> +
  • + WDS +
  • + <% end %> + <% else %> + <% if (not dev.wdsBand or dev.wdsBand == dev.dbdcBandName) then %> +
  • + WDS +
  • + <% end %> + <% end %> + <% if map_cfgs then %> + <% if request[4] == "vif_cfg_view" and cfgs.MapMode == "0" then%> +
  • + );this.blur(); ">Stations +
  • + <% end %> + <% else %> + <% if request[4] == "vif_cfg_view" then%> +
  • + );this.blur(); ">Stations +
  • + <% end %> + <% end %> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% if dev.DBDC_MODE == "0" then %> + + + + + + <% end %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
SSID + " name="<%="SSID"..vifidx%>"> +
Channel + +
Auth Mode + +
Hidden + + checked="checked" + <% end %> type="checkbox"> +
AP Isolation + + checked="checked" + <% end %> type="checkbox"> +
WMM Capable + + checked="checked" + <% end %> type="checkbox"> +
TX Rate + +
STBC + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
HT LDPC + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
VHT STBC + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
VHT LDPC + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Mode + +
DLS Capable + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
APSD Capable + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Fragment Threshold + (range 256-2346, default 2346) +
RTS Threshold + (range 1-2347, default 2347) +
VHT Short GI + +
VHT BW Signaling + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable + checked="checked"<% end %>/> Dynamic +
HT Protection + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
HT Guard Interval + +
Operating Mode + +
A-MSDU + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
Auto Block ACK + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
IGMP Snooping + checked="checked"<% end %>/> Enable + checked="checked"<% end %>/> Disable +
+ + <% if string.split(cfgs.WirelessMode,";")[1] == "16" or string.split(cfgs.WirelessMode,";")[1] == "17" or string.split(cfgs.WirelessMode,";")[1] == "18" then %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% end %> + + + + + + + + + + + + <%if tostring(mtkwifi.__any_wsc_enabled(WscValue)) == "1" then%> + <% if not appliedWscValue or (WscValue == appliedWscValue) then%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% if map_cfgs then %> + <% if cfgs.MapMode == "0" then %> + + + + + + + + + + + + + + + <% end %> + <% else %> + + + + + + + + + + + + + + + <% end %> + + + + + + + + + + + + + + + + + + + + + + + + + + <% else %> + + + + <% end %> + <% end %> + + + + <% if not dev.wdsBand or dev.wdsBand == dev.dbdcBandName then %> + + + + + + + + style="display:none" <% end %>> + + + + + style="display:none" <% end %>> + + + + + style="display:none" <% end %>> + + + + + style="display:none" <% end %>> + + + + style="display:none" <% end %>> + + + + + style="display:none" <% end %>> + + + + style="display:none" <% end %>> + + + + + style="display:none" <% end %>> + + + + style="display:none" <% end %>> + + + + + + style="display:none" <% end %>> + + <% _wdsMac=cfgs.WdsList and cfgs.WdsList:match("^([%x:]+)") %> + + + + style="display:none" <% end %>> + + <% _wdsMac=cfgs.WdsList and cfgs.WdsList:match("^[%x:]+;([%x:]+)") %> + + + + style="display:none" <% end %>> + + <% _wdsMac=cfgs.WdsList and cfgs.WdsList:match("^[%x:]+;[%x:]+;([%x:]+)") %> + + + + style="display:none" <% end %>> + + <% _wdsMac=cfgs.WdsList and cfgs.WdsList:match("^[%x:]+;[%x:]+;[%x:]+;([%x:]+)") %> + + + + + + <% end %> + + <% if request[4] == "vif_cfg_view" then%> + + + + + + + + + + + + + + + + <% end %> + + <% if map_cfgs then %> +
+ Access Control - <%=vifname and devname.."@"..vifname or devname%> + + + + + +
Access Policy + disabled="disabled" <% end %> <% if cfgs["AccessPolicy"..(vifidx-1)] == "0" then %> checked="checked"<% end %>/> Disable +
+ disabled="disabled" <% end %> <% if cfgs["AccessPolicy"..(vifidx-1)] == "1" then %> checked="checked"<% end %>/> White List +
+ disabled="disabled" <% end %> <% if cfgs["AccessPolicy"..(vifidx-1)] == "2" then %> checked="checked"<% end %>/> Black List +
+ <% if first_card_cfgs.MapMode == "1" then %> + To set Black List see MAP application note when EasyMesh is enabled. + <% end %> +
+
+# 1. one MAC one line.
+# 2. empty lines will be ignored.
+# 3. lines start with "#" will be ignored.
+# 4. invalid MAC will be ignored.
+
+11:22:33:44:55:66
+AA:BB:CC:DD:EE:FF
+11:22:33:aa:bb:cc
+            
+ +
+ <% else %> +
+ Access Control - <%=vifname and devname.."@"..vifname or devname%> + + + + + +
Access Policy + checked="checked"<% end %>/> Disable +
+ checked="checked"<% end %>/> White List +
+ checked="checked"<% end %>/> Black List +
+
+# 1. one MAC one line.
+# 2. empty lines will be ignored.
+# 3. lines start with "#" will be ignored.
+# 4. invalid MAC will be ignored.
+
+11:22:33:44:55:66
+AA:BB:CC:DD:EE:FF
+11:22:33:aa:bb:cc
+            
+ +
+ <% end %> + +
+ + + +
+<% end %> + + + +<%+footer%> diff --git a/package/mtk/applications/luci-app-mtk/root/sbin/l1dat b/package/mtk/applications/luci-app-mtk/root/sbin/l1dat new file mode 100755 index 0000000000..8f36466b12 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/sbin/l1dat @@ -0,0 +1,177 @@ +#!/usr/bin/lua + +-- Constant Definition +local FW_PATH = "/lib/firmware/" +local MTD_PATH = "/dev/" +local MTD_TABLE = "/proc/mtd" +local E2P_PART_NAME = "Factory" +local E2P_FILE_NAME = "e2p" + + +function show_usage() + print("Usage: l1dat genconfig | dbg | idx2if idx | if2zone ifname | if2dat ifname | zone2if zone | if2dbdcidx ifname") +end + +function print_err(msg) + io.stderr:write("[ERR][l1dat] "..msg) +end + +if not pcall(require, "l1dat_parser") then + if arg[1] == "dbg" then + print_err("Load l1dat_parser module failed\n") + end + return +end + +local l1parser = require("l1dat_parser") +local l1dat = l1parser.load_l1_profile(l1parser.L1_DAT_PATH) + +if not l1dat then + if arg[1] == "dbg" then + print_err("l1profile.dat is ivalid\n") + end + return +end + +function read_pipe(pipe) + local fp = io.popen(pipe) + local txt = fp:read("*a") + fp:close() + return txt +end + +function eeprom_extract(part, offset, size, bin_name) + local part_name = part or E2P_PART_NAME + local dump_name = bin_name or E2P_FILE_NAME + + if not offset or not size or tonumber(offset) < 0 or tonumber(size) < 0 then + print_err("Invalid offset or size value") + return + end + local offset_decimal = string.format("%d", offset) + local size_decimal = string.format("%d", size) + + local cmd = "cat "..MTD_TABLE.." | grep "..part_name + local mtd = read_pipe(cmd) + if not mtd or mtd == "" then + print_err("mtd partition "..part_name.." not found") + return + end + + cmd = "[ -e "..FW_PATH.." ] || mkdir "..FW_PATH + os.execute(cmd) + + local mtd_node = "/dev/"..string.match(mtd, "(mtd[%d]+)") + cmd = "dd if="..mtd_node.." of="..FW_PATH..dump_name.." bs=1 skip="..offset_decimal.." count="..size_decimal.." seek="..offset_decimal.." conv=notrunc 2>/dev/null" + os.execute(cmd) +end + +local action0 = { + ["dbg"] = function() + show_usage() + end, + + ["genconfig"] = function() + local seen = {} + local dridx = l1parser.DEV_RINDEX + local cmd = "" + local dir = "" + for name, dev in pairs(l1dat[dridx]) do + if not seen[dev] then + seen[dev] = true + dir = string.match(dev["profile_path"], "^(.+)/") + --print("mkdir -p "..dir) + os.execute("mkdir -p "..dir) + cmd = "ralink_init gen "..dev["nvram_zone"].." "..dev["profile_path"] + --print(cmd) + os.execute(cmd) + + eeprom_extract(E2P_PART_NAME, dev.EEPROM_offset, dev.EEPROM_size, dev.EEPROM_name) + end + end + end, + + ["if2zone"] = function(ifname) + if not ifname then return end + + local zone = l1parser.l1_ifname_to_zone(ifname) or "" + print(zone); + end, + + ["if2dat"] = function(ifname) + if not ifname then return end + + local dat_path = l1parser.l1_ifname_to_datpath(ifname) or "" + print(dat_path) + end, + + ["zone2if"] = function(zone) + if not zone then return end + + local main_if, ext_if, apcli, wds, mesh = l1parser.l1_zone_to_ifname(zone) + + if main_if then + print(main_if.." "..ext_if.." "..apcli.." "..wds.." "..mesh) + end + end, + + ["idx2if"] = function(idx) + if not idx then return end + + idx = tonumber(idx) + + local band_num = l1parser.MAX_NUM_DBDC_BAND + local dbdc_if + local count = 0 + for k, v in pairs(l1dat) do + -- check if last dbdc exists + dbdc_if = l1parser.token_get(v.main_ifname, band_num, nil) + if dbdc_if then + count = count + band_num; + else + count = count + 1 + end + + if not dbdc_if and count == idx then + print(v.main_ifname) + + break + end + + if count >= idx then -- dbdc case + local token_num = band_num - ( count - idx ) + print(l1parser.token_get(v.main_ifname, token_num, nil)) + + break + end + end + end, + + ["if2dbdcidx"] = function(ifname) + if not ifname then return end + + local ridx = l1parser.IF_RINDEX + + if not l1dat[ridx][ifname] then return end + + print(l1dat[ridx][ifname]["subidx"] or "0") + end +} + +if #arg == 0 then + show_usage() + return +end + +if action0[arg[1]] then + if #arg == 1 then + --print("#arg == 1", arg[1]) + action0[arg[1]]() + elseif #arg == 2 then + --print("#arg == 1", arg[1], arg[2]) + action0[arg[1]](arg[2]) + end +else + print_err("invalid arg \""..arg[1].."\"\n"); +end + diff --git a/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/inspect.lua b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/inspect.lua new file mode 100644 index 0000000000..d809de09b0 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/inspect.lua @@ -0,0 +1,337 @@ +local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local math = _tl_compat and _tl_compat.math or math; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table +local inspect = {Options = {}, } + + + + + + + + + + + + + + + + + +inspect._VERSION = 'inspect.lua 3.1.0' +inspect._URL = 'http://github.com/kikito/inspect.lua' +inspect._DESCRIPTION = 'human-readable representations of tables' +inspect._LICENSE = [[ + MIT LICENSE + + Copyright (c) 2022 Enrique García Cota + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]] +inspect.KEY = setmetatable({}, { __tostring = function() return 'inspect.KEY' end }) +inspect.METATABLE = setmetatable({}, { __tostring = function() return 'inspect.METATABLE' end }) + +local tostring = tostring +local rep = string.rep +local match = string.match +local char = string.char +local gsub = string.gsub +local fmt = string.format + +local function rawpairs(t) + return next, t, nil +end + + + +local function smartQuote(str) + if match(str, '"') and not match(str, "'") then + return "'" .. str .. "'" + end + return '"' .. gsub(str, '"', '\\"') .. '"' +end + + +local shortControlCharEscapes = { + ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", + ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\127"] = "\\127", +} +local longControlCharEscapes = { ["\127"] = "\127" } +for i = 0, 31 do + local ch = char(i) + if not shortControlCharEscapes[ch] then + shortControlCharEscapes[ch] = "\\" .. i + longControlCharEscapes[ch] = fmt("\\%03d", i) + end +end + +local function escape(str) + return (gsub(gsub(gsub(str, "\\", "\\\\"), + "(%c)%f[0-9]", longControlCharEscapes), + "%c", shortControlCharEscapes)) +end + +local function isIdentifier(str) + return type(str) == "string" and not not str:match("^[_%a][_%a%d]*$") +end + +local flr = math.floor +local function isSequenceKey(k, sequenceLength) + return type(k) == "number" and + flr(k) == k and + 1 <= (k) and + k <= sequenceLength +end + +local defaultTypeOrders = { + ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4, + ['function'] = 5, ['userdata'] = 6, ['thread'] = 7, +} + +local function sortKeys(a, b) + local ta, tb = type(a), type(b) + + + if ta == tb and (ta == 'string' or ta == 'number') then + return (a) < (b) + end + + local dta = defaultTypeOrders[ta] or 100 + local dtb = defaultTypeOrders[tb] or 100 + + + return dta == dtb and ta < tb or dta < dtb +end + +local function getKeys(t) + + local seqLen = 1 + while rawget(t, seqLen) ~= nil do + seqLen = seqLen + 1 + end + seqLen = seqLen - 1 + + local keys, keysLen = {}, 0 + for k in rawpairs(t) do + if not isSequenceKey(k, seqLen) then + keysLen = keysLen + 1 + keys[keysLen] = k + end + end + table.sort(keys, sortKeys) + return keys, keysLen, seqLen +end + +local function countCycles(x, cycles) + if type(x) == "table" then + if cycles[x] then + cycles[x] = cycles[x] + 1 + else + cycles[x] = 1 + for k, v in rawpairs(x) do + countCycles(k, cycles) + countCycles(v, cycles) + end + countCycles(getmetatable(x), cycles) + end + end +end + +local function makePath(path, a, b) + local newPath = {} + local len = #path + for i = 1, len do newPath[i] = path[i] end + + newPath[len + 1] = a + newPath[len + 2] = b + + return newPath +end + + +local function processRecursive(process, + item, + path, + visited) + if item == nil then return nil end + if visited[item] then return visited[item] end + + local processed = process(item, path) + if type(processed) == "table" then + local processedCopy = {} + visited[item] = processedCopy + local processedKey + + for k, v in rawpairs(processed) do + processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) + if processedKey ~= nil then + processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) + end + end + + local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) + if type(mt) ~= 'table' then mt = nil end + setmetatable(processedCopy, mt) + processed = processedCopy + end + return processed +end + +local function puts(buf, str) + buf.n = buf.n + 1 + buf[buf.n] = str +end + + + +local Inspector = {} + + + + + + + + + + +local Inspector_mt = { __index = Inspector } + +local function tabify(inspector) + puts(inspector.buf, inspector.newline .. rep(inspector.indent, inspector.level)) +end + +function Inspector:getId(v) + local id = self.ids[v] + local ids = self.ids + if not id then + local tv = type(v) + id = (ids[tv] or 0) + 1 + ids[v], ids[tv] = id, id + end + return tostring(id) +end + +function Inspector:putValue(v) + local buf = self.buf + local tv = type(v) + if tv == 'string' then + puts(buf, smartQuote(escape(v))) + elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or + tv == 'cdata' or tv == 'ctype' then + puts(buf, tostring(v)) + elseif tv == 'table' and not self.ids[v] then + local t = v + + if t == inspect.KEY or t == inspect.METATABLE then + puts(buf, tostring(t)) + elseif self.level >= self.depth then + puts(buf, '{...}') + else + if self.cycles[t] > 1 then puts(buf, fmt('<%d>', self:getId(t))) end + + local keys, keysLen, seqLen = getKeys(t) + + puts(buf, '{') + self.level = self.level + 1 + + for i = 1, seqLen + keysLen do + if i > 1 then puts(buf, ',') end + if i <= seqLen then + puts(buf, ' ') + self:putValue(t[i]) + else + local k = keys[i - seqLen] + tabify(self) + if isIdentifier(k) then + puts(buf, k) + else + puts(buf, "[") + self:putValue(k) + puts(buf, "]") + end + puts(buf, ' = ') + self:putValue(t[k]) + end + end + + local mt = getmetatable(t) + if type(mt) == 'table' then + if seqLen + keysLen > 0 then puts(buf, ',') end + tabify(self) + puts(buf, ' = ') + self:putValue(mt) + end + + self.level = self.level - 1 + + if keysLen > 0 or type(mt) == 'table' then + tabify(self) + elseif seqLen > 0 then + puts(buf, ' ') + end + + puts(buf, '}') + end + + else + puts(buf, fmt('<%s %d>', tv, self:getId(v))) + end +end + + + + +function inspect.inspect(root, options) + options = options or {} + + local depth = options.depth or (math.huge) + local newline = options.newline or '\n' + local indent = options.indent or ' ' + local process = options.process + + if process then + root = processRecursive(process, root, {}, {}) + end + + local cycles = {} + countCycles(root, cycles) + + local inspector = setmetatable({ + buf = { n = 0 }, + ids = {}, + cycles = cycles, + depth = depth, + level = 0, + newline = newline, + indent = indent, + }, Inspector_mt) + + inspector:putValue(root) + + return table.concat(inspector.buf) +end + +setmetatable(inspect, { + __call = function(_, root, options) + return inspect.inspect(root, options) + end, +}) + +return inspect \ No newline at end of file diff --git a/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/l1dat_parser.lua b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/l1dat_parser.lua new file mode 100755 index 0000000000..35cda81baf --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/l1dat_parser.lua @@ -0,0 +1,349 @@ +#!/usr/bin/env lua + +--[[ + * A lua library to manipulate mtk's wifi driver. used in luci-app-mtk. + * + * Copyright (C) 2016 MTK + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +]] + +local l1dat_parser = { + L1_DAT_PATH = "/etc/wireless/l1profile.dat", + IF_RINDEX = "ifname_ridx", + DEV_RINDEX = "devname_ridx", + MAX_NUM_APCLI = 1, + MAX_NUM_WDS = 4, + MAX_NUM_MESH = 1, + MAX_NUM_EXTIF = 16, + MAX_NUM_DBDC_BAND = 2, +} + +local l1cfg_options = { + ext_ifname="", + apcli_ifname="apcli", + wds_ifname="wds", + mesh_ifname="mesh" + } + +function l1dat_parser.__trim(s) + if s then return (s:gsub("^%s*(.-)%s*$", "%1")) end +end + +function l1dat_parser.__cfg2list(str) + -- delimeter == ";" + local i = 1 + local list = {} + for k in string.gmatch(str, "([^;]+)") do + list[i] = k + i = i + 1 + end + return list +end + +function l1dat_parser.token_get(str, n, v) + -- n starts from 1 + -- v is the backup in case token n is nil + if not str then return v end + local tmp = l1dat_parser.__cfg2list(str) + return tmp[tonumber(n)] or v +end + +function l1dat_parser.add_default_value(l1cfg) + for k, v in ipairs(l1cfg) do + + for opt, default in pairs(l1cfg_options) do + if ( opt == "ext_ifname" ) then + v[opt] = v[opt] or v["main_ifname"].."_" + else + v[opt] = v[opt] or default..k.."_" + end + end + end + + return l1cfg +end + +function l1dat_parser.get_value_by_idx(devidx, mainidx, subidx, key) + --print("Enter l1dat_parser.get_value_by_idx("..devidx..","..mainidx..", "..subidx..", "..key..")
") + if not devidx or not mainidx or not key then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + local dev_ridx = l1dat_parser.DEV_RINDEX + local sidx = subidx or 1 + local devname1 = devidx.."."..mainidx + local devname2 = devidx.."."..mainidx.."."..sidx + + --print("devnam1=", devname1, "devname2=", devname2, "
") + return devs[dev_ridx][devname2] and devs[dev_ridx][devname2][key] + or devs[dev_ridx][devname1] and devs[dev_ridx][devname1][key] +end + +-- path to zone is 1 to 1 mapping +function l1dat_parser.l1_path_to_zone(path) + --print("Enter l1dat_parser.l1_path_to_zone("..path..")
") + if not path then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + for _, dev in pairs(devs[l1dat_parser.IF_RINDEX]) do + if dev.profile_path == path then + return dev.nvram_zone + end + end + + return +end + +-- zone to path is 1 to n mapping +function l1dat_parser.l1_zone_to_path(zone) + if not zone then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + local plist = {} + for _, dev in pairs(devs[l1dat_parser.IF_RINDEX]) do + if dev.nvram_zone == zone then + if not next(plist) then + table.insert(plist,dev.profile_path) + else + local plist_str = table.concat(plist) + if not plist_str:match(dev.profile_path) then + table.insert(plist,dev.profile_path) + end + end + end + end + + return next(plist) and plist or nil +end + +function l1dat_parser.l1_ifname_to_datpath(ifname) + if not ifname then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + local ridx = l1dat_parser.IF_RINDEX + return devs[ridx][ifname] and devs[ridx][ifname].profile_path +end + +function l1dat_parser.l1_ifname_to_zone(ifname) + if not ifname then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + local ridx = l1dat_parser.IF_RINDEX + return devs[ridx][ifname] and devs[ridx][ifname].nvram_zone +end + +function l1dat_parser.l1_zone_to_ifname(zone) + if not zone then return end + + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + if not devs then return end + + local zone_dev + for _, dev in pairs(devs[l1dat_parser.DEV_RINDEX]) do + if dev.nvram_zone == zone then + zone_dev = dev + end + end + + if not zone_dev then + return nil + else + return zone_dev.main_ifname, zone_dev.ext_ifname, zone_dev.apcli_ifname, zone_dev.wds_ifname, zone_dev.mesh_ifname + end +end + +-- input: L1 profile path. +-- output A table, devs, contains +-- 1. devs[%d] = table of each INDEX# in the L1 profile +-- 2. devs.ifname_ridx[ifname] +-- = table of each ifname and point to relevant contain in dev[$d] +-- 3. devs.devname_ridx[devname] similar to devs.ifnameridx, but use devname. +-- devname = INDEX#_value.mainidx(.subidx) +-- Using *_ridx do not need to handle name=k1;k2 case of DBDC card. +function l1dat_parser.load_l1_profile(path) + local devs = setmetatable({}, {__index= + function(tbl, key) + local util = require("luci.util") + --print("metatable function:", util.serialize_data(tbl), key) + --print("-----------------------------------------------") + if ( string.match(key, "^%d+")) then + tbl[key] = {} + return tbl[key] + end + end + }) + local nixio = require("nixio") + local chipset_num = {} + local dir = io.popen("ls /etc/wireless/") + if not dir then return end + local fd = io.open(path, "r") + if not fd then return end + + -- convert l1 profile into lua table + for line in fd:lines() do + line = l1dat_parser.__trim(line) + if string.byte(line) ~= string.byte("#") then + local i = string.find(line, "=") + if i then + local k, v, k1, k2 + k = l1dat_parser.__trim( string.sub(line, 1, i-1) ) + v = l1dat_parser.__trim( string.sub(line, i+1) ) + k1, k2 = string.match(k, "INDEX(%d+)_(.+)") + if k1 then + k1 = tonumber(k1) + 1 + if devs[k1][k2] then + nixio.syslog("warning", "skip repeated key"..line) + end + devs[k1][k2] = v or "" + else + k1 = string.match(k, "INDEX(%d+)") + k1 = tonumber(k1) + 1 + devs[k1]["INDEX"] = v + + chipset_num[v] = (not chipset_num[v] and 1) or chipset_num[v] + 1 + devs[k1]["mainidx"] = chipset_num[v] + end + --else + -- nixio.syslog("warning", "skip line without '=' "..line) + end + --else + -- nixio.syslog("warning", "skip comment line "..line) + end + end + + l1dat_parser.add_default_value(devs) + --local util = require("luci.util") + --local seen2 = {} + -- print("Before setup ridx", util.serialize_data(devs, seen2)) + + -- Force to setup reverse indice for quick search. + -- Benifit: + -- 1. O(1) search with ifname, devname + -- 2. Seperate DBDC name=k1;k2 format in the L1 profile into each + -- ifname, devname. + local dbdc_if = {} + local ridx = l1dat_parser.IF_RINDEX + local dridx = l1dat_parser.DEV_RINDEX + local band_num = l1dat_parser.MAX_NUM_DBDC_BAND + local k, v, dev, i , j, last + local devname + devs[ridx] = {} + devs[dridx] = {} + for _, dev in ipairs(devs) do + dbdc_if[band_num] = l1dat_parser.token_get(dev.main_ifname, band_num, nil) + if dbdc_if[band_num] then + for i = 1, band_num - 1 do + dbdc_if[i] = l1dat_parser.token_get(dev.main_ifname, i, nil) + end + for i = 1, band_num do + devs[ridx][dbdc_if[i]] = {} + devs[ridx][dbdc_if[i]]["subidx"] = i + + for k, v in pairs(dev) do + if k == "INDEX" or k == "EEPROM_offset" or k == "EEPROM_size" + or k == "mainidx" then + devs[ridx][dbdc_if[i]][k] = v + else + devs[ridx][dbdc_if[i]][k] = l1dat_parser.token_get(v, i, "") + end + end + devname = dev.INDEX.."."..dev.mainidx.."."..devs[ridx][dbdc_if[i]]["subidx"] + devs[dridx][devname] = devs[ridx][dbdc_if[i]] + end + + local apcli_if, wds_if, ext_if, mesh_if = {}, {}, {}, {} + + for i = 1, band_num do + ext_if[i] = l1dat_parser.token_get(dev.ext_ifname, i, nil) + apcli_if[i] = l1dat_parser.token_get(dev.apcli_ifname, i, nil) + wds_if[i] = l1dat_parser.token_get(dev.wds_ifname, i, nil) + mesh_if[i] = l1dat_parser.token_get(dev.mesh_ifname, i, nil) + end + + for i = 1, l1dat_parser.MAX_NUM_EXTIF - 1 do -- ifname idx is from 0 + for j = 1, band_num do + devs[ridx][ext_if[j]..i] = devs[ridx][dbdc_if[j]] + end + end + + for i = 0, l1dat_parser.MAX_NUM_APCLI - 1 do + for j = 1, band_num do + devs[ridx][apcli_if[j]..i] = devs[ridx][dbdc_if[j]] + end + end + + for i = 0, l1dat_parser.MAX_NUM_WDS - 1 do + for j = 1, band_num do + devs[ridx][wds_if[j]..i] = devs[ridx][dbdc_if[j]] + end + end + + for i = 0, l1dat_parser.MAX_NUM_MESH - 1 do + for j = 1, band_num do + if mesh_if[j] then + devs[ridx][mesh_if[j]..i] = devs[ridx][dbdc_if[j]] + end + end + end + + else + devs[ridx][dev.main_ifname] = dev + + devname = dev.INDEX.."."..dev.mainidx + devs[dridx][devname] = dev + + for i = 1, l1dat_parser.MAX_NUM_EXTIF - 1 do -- ifname idx is from 0 + devs[ridx][dev.ext_ifname..i] = dev + end + + for i = 0, l1dat_parser.MAX_NUM_APCLI - 1 do -- ifname idx is from 0 + devs[ridx][dev.apcli_ifname..i] = dev + end + + for i = 0, l1dat_parser.MAX_NUM_WDS - 1 do -- ifname idx is from 0 + devs[ridx][dev.wds_ifname..i] = dev + end + + for i = 0, l1dat_parser.MAX_NUM_MESH - 1 do -- ifname idx is from 0 + devs[ridx][dev.mesh_ifname..i] = dev + end + end + end + + fd:close() + return devs +end + +function l1dat_parser.creat_link_for_nvram( ) + local devs = l1dat_parser.load_l1_profile(l1dat_parser.L1_DAT_PATH) + for devname, dev in pairs(devs.devname_ridx) do + local dev = devs.devname_ridx[devname] + profile = dev.profile_path + os.execute("mkdir -p /tmp/mtk/wifi/") + if dev.nvram_zone == "dev1" then + os.execute("ln -sf " ..profile.." /tmp/mtk/wifi/2860") + elseif dev.nvram_zone == "dev2" then + os.execute("ln -sf " ..profile.." /tmp/mtk/wifi/rtdev") + elseif dev.nvram_zone == "dev3" then + os.execute("ln -sf " ..profile.." /tmp/mtk/wifi/wifi3") + end + end +end +return l1dat_parser diff --git a/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/mtkwifi.lua b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/mtkwifi.lua new file mode 100644 index 0000000000..ad508dc8e4 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/mtkwifi.lua @@ -0,0 +1,1712 @@ +#!/usr/bin/env lua + +--[[ + * A lua library to manipulate mtk's wifi driver. used in luci-app-mtk. + * + * Copyright (C) 2016 Hua Shao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +]] + +require("datconf") +local ioctl_help = require "ioctl_helper" +local mtkwifi = {} +local logDisable = 0 + +function debug_write(...) + -- luci.http.write(...) + if logDisable == 1 then + return + end + local syslog_msg = ""; + local ff = io.open("/tmp/mtkwifi", "a") + local nargs = select('#',...) + + + + for n=1, nargs do + local v = select(n,...) + if (type(v) == "string" or type(v) == "number") then + ff:write(v.." ") + syslog_msg = syslog_msg..v.." "; + elseif (type(v) == "boolean") then + if v then + ff:write("true ") + syslog_msg = syslog_msg.."true "; + else + ff:write("false ") + syslog_msg = syslog_msg.."false "; + end + elseif (type(v) == "nil") then + ff:write("nil ") + syslog_msg = syslog_msg.."nil "; + else + ff:write(" ") + syslog_msg = syslog_msg.." "; + end + end + ff:write("\n") + ff:close() + nixio.syslog("debug", syslog_msg) +end + +function mtkwifi.get_table_length(T) + local count = 0 + for _ in pairs(T) do + count = count + 1 + end + return count +end + +function mtkwifi.get_file_lines(fileName) + local fd = io.open(fileName, "r") + if not fd then return end + local content = fd:read("*all") + fd:close() + return mtkwifi.__lines(content) +end + +function mtkwifi.__split(s, delimiter) + if s == nil then s = "0" end + local result = {}; + for match in (s..delimiter):gmatch("(.-)"..delimiter) do + table.insert(result, match); + end + return result; +end + +function string:split(sep) + local sep, fields = sep or ":", {} + local pattern = string.format("([^%s]+)", sep) + self:gsub(pattern, function(c) fields[#fields+1] = c end) + return fields +end + +function mtkwifi.__trim(s) + if s then return (s:gsub("^%s*(.-)%s*$", "%1")) end +end + +function mtkwifi.__handleSpecialChars(s) + s = s:gsub("\\", "\\\\") + s = s:gsub("\"", "\\\"") + return s +end + +function mtkwifi.__spairs(t, order) + -- collect the keys + local keys = {} + for k in pairs(t) do keys[#keys+1] = k end + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + --[[ + if order then + table.sort(keys, function(a,b) return order(t, a, b) end) + -- table.sort(keys, order) + else + table.sort(keys) + end + ]] + table.sort(keys, order) + -- return the iterator function + local i = 0 + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end +end + +function mtkwifi.__lines(str) + local t = {} + local function helper(line) table.insert(t, line) return "" end + helper((str:gsub("(.-)\r?\n", helper))) + return t +end + +function mtkwifi.__get_l1dat() + if not pcall(require, "l1dat_parser") then + return + end + + local parser = require("l1dat_parser") + local l1dat = parser.load_l1_profile(parser.L1_DAT_PATH) + + return l1dat, parser +end + +function mtkwifi.sleep(s) + local ntime = os.clock() + s + repeat until os.clock() > ntime +end + +function mtkwifi.deepcopy(orig) + local orig_type = type(orig) + local copy + if orig_type == 'table' then + copy = {} + for orig_key, orig_value in next, orig, nil do + copy[mtkwifi.deepcopy(orig_key)] = mtkwifi.deepcopy(orig_value) + end + setmetatable(copy, mtkwifi.deepcopy(getmetatable(orig))) + else -- number, string, boolean, etc + copy = orig + end + return copy +end + +function mtkwifi.read_pipe(pipe) + local retry_count = 10 + local fp, txt, err + repeat -- fp:read() may return error, "Interrupted system call", and can be recovered by doing it again + fp = io.popen(pipe) + txt, err = fp:read("*a") + fp:close() + retry_count = retry_count - 1 + until err == nil or retry_count == 0 + return txt +end + +function mtkwifi.detect_triband() + local devs = mtkwifi.get_all_devs() + local l1dat, l1 = mtkwifi.__get_l1dat() + local dridx = l1.DEV_RINDEX + local main_ifname + local bands = 0 + for _,dev in ipairs(devs) do + main_ifname = l1dat and l1dat[dridx][dev.devname].main_ifname or dbdc_prefix[mainidx][subidx].."0" + if mtkwifi.exists("/sys/class/net/"..main_ifname) then + bands = bands + 1 + end + end + return bands +end + +function mtkwifi.detect_first_card() + local devs = mtkwifi.get_all_devs() + local first_card_profile + + for i,dev in ipairs(devs) do + first_card_profile = dev.profile + if i == 1 then break end + end + + return first_card_profile +end + +function mtkwifi.load_profile(path, raw) + local cfgs = {} + + cfgobj = datconf.openfile(path) + if cfgobj then + cfgs = cfgobj:getall() + cfgobj:close() + elseif raw then + cfgs = datconf.parse(raw) + end + + return cfgs +end + +function mtkwifi.save_profile(cfgs, path) + + if not cfgs then + debug_write("configuration was empty, nothing saved") + return + end + + -- Keep a backup of last profile settings + -- if string.match(path, "([^/]+)\.dat") then + -- os.execute("cp -f "..path.." "..mtkwifi.__profile_previous_settings_path(path)) + -- end + local datobj = datconf.openfile(path) + datobj:merge(cfgs) + datobj:close(true) -- means close and commit + + os.execute("sync >/dev/null 2>&1") +end + +function mtkwifi.split_profile(path, path_2g, path_5g) + assert(path) + assert(path_2g) + assert(path_5g) + local cfgs = mtkwifi.load_profile(path) + local dirty = { + "Channel", + "WirelessMode", + "TxRate", + "WmmCapable", + "NoForwarding", + "HideSSID", + "IEEE8021X", + "PreAuth", + "AuthMode", + "EncrypType", + "RekeyMethod", + "RekeyInterval", + "PMKCachePeriod", + "DefaultKeyId", + "Key{n}Type", + "HT_EXTCHA", + "RADIUS_Server", + "RADIUS_Port", + } + local cfg5g = mtkwifi.deepcopy(cfgs) + for _,v in ipairs(dirty) do + cfg5g[v] = mtkwifi.token_get(cfgs[v], 1, 0) + assert(cfg5g[v]) + end + mtkwifi.save_profile(cfg5g, path_5g) + + local cfg2g = mtkwifi.deepcopy(cfgs) + for _,v in ipairs(dirty) do + cfg2g[v] = mtkwifi.token_get(cfgs[v], 1, 0) + assert(cfg2g[v]) + end + mtkwifi.save_profile(cfg2g, path_2g) +end + +function mtkwifi.merge_profile(path, path_2g, path_5g) + local cfg2g = mtkwifi.load_profile(path_2g) + local cfg5g = mtkwifi.load_profile(path_5g) + local dirty = { + "Channel", + "WirelessMode", + "TxRate", + "WmmCapable", + "NoForwarding", + "HideSSID", + "IEEE8021X", + "PreAuth", + "AuthMode", + "EncrypType", + "RekeyMethod", + "RekeyInterval", + "PMKCachePeriod", + "DefaultKeyId", + "Key{n}Type", + "HT_EXTCHA", + "RADIUS_Server", + "RADIUS_Port", + } + local cfgs = mtkwifi.deepcopy(cfg2g) + for _,v in dirty do + -- TODO + end + mtkwifi.save_profile(cfgs, path) +end + +-- update path1 by path2 +function mtkwifi.update_profile(path1, path2) + local cfg1 = datconf.openfile(path1) + local cfg2 = datconf.openfile(path2) + + cfg1:merge(cfg2:getall()) + cfg1:close(true) + cfg2:close() + os.execute("sync >/dev/null 2>&1") +end + +function mtkwifi.__child_info_path() + local path = "/tmp/mtk/wifi/child_info.dat" + os.execute("mkdir -p /tmp/mtk/wifi") + return path +end + +function mtkwifi.__profile_previous_settings_path(profile) + assert(type(profile) == "string") + local bak = "/tmp/mtk/wifi/"..string.match(profile, "([^/]+)\.dat")..".last" + os.execute("mkdir -p /tmp/mtk/wifi") + return bak +end + +function mtkwifi.__profile_applied_settings_path(profile) + assert(type(profile) == "string") + local bak + if string.match(profile, "([^/]+)\.dat") then + os.execute("mkdir -p /tmp/mtk/wifi") + bak = "/tmp/mtk/wifi/"..string.match(profile, "([^/]+)\.dat")..".applied" + elseif string.match(profile, "([^/]+)\.txt") then + os.execute("mkdir -p /tmp/mtk/wifi") + bak = "/tmp/mtk/wifi/"..string.match(profile, "([^/]+)\.txt")..".applied" + elseif string.match(profile, "([^/]+)$") then + os.execute("mkdir -p /tmp/mtk/wifi") + bak = "/tmp/mtk/wifi/"..string.match(profile, "([^/]+)$")..".applied" + else + bak = "" + end + + return bak +end + +-- if path2 is not given, use backup of path1. +function mtkwifi.diff_profile(path1, path2) + assert(path1) + if not path2 then + path2 = mtkwifi.__profile_applied_settings_path(path1) + if not mtkwifi.exists(path2) then + return {} + end + end + assert(path2) + + local cfg1 + local cfg2 + local diff = {} + + cfg1 = mtkwifi.load_profile(path1) or {} + cfg2 = mtkwifi.load_profile(path2) or {} + + for k,v in pairs(cfg1) do + if cfg2[k] ~= cfg1[k] then + diff[k] = {cfg1[k] or "", cfg2[k] or ""} + end + end + + for k,v in pairs(cfg2) do + if cfg2[k] ~= cfg1[k] then + diff[k] = {cfg1[k] or "", cfg2[k] or ""} + end + end + + return diff +end + +function mtkwifi.__fork_exec(command) + if type(command) ~= type("") or command == "" then + debug_write("__fork_exec : Incorrect command! Expected non-empty string type, got ",type(command)) + nixio.syslog("err", "__fork_exec : Incorrect command! Expected non-empty string type, got "..type(command)) + else + local nixio = require("nixio") + -- If nixio.exec() fails, then child process will be reaped automatically and + -- it will be achieved by ignoring SIGCHLD signal here in parent process! + if not nixio.signal(17,"ign") then + nixio.syslog("warning", "__fork_exec : Failed to set SIG_IGN for SIGCHLD!") + debug_write("__fork_exec : Failed to set SIG_IGN for SIGCHLD!") + end + local pid = nixio.fork() + if pid < 0 then + nixio.syslog("err", "__fork_exec : [Fork Failure] "..command) + debug_write("__fork_exec : [Fork Failure] "..command) + elseif pid == 0 then + -- change to root dir to flush out any opened directory streams of parent process. + nixio.chdir("/") + + -- As file descriptors are inherited by child process, all unused file descriptors must be closed. + -- Make stdin, out, err file descriptors point to /dev/null using dup2. + -- As a result, it will not corrupt stdin, out, err file descriptors of parent process. + local null = nixio.open("/dev/null", "w+") + if null then + nixio.dup(null, nixio.stderr) + nixio.dup(null, nixio.stdout) + nixio.dup(null, nixio.stdin) + if null:fileno() > 2 then + null:close() + end + end + debug_write("__fork_exec : cmd = "..command) + -- replaces the child process image with the new process image generated by provided command + nixio.exec("/bin/sh", "-c", command) + os.exit(true) + end + end +end + +function mtkwifi.is_child_active() + local fd = io.open(mtkwifi.__child_info_path(), "r") + if not fd then + os.execute("rm -f "..mtkwifi.__child_info_path()) + return false + end + local content = fd:read("*all") + fd:close() + if not content then + os.execute("rm -f "..mtkwifi.__child_info_path()) + return false + end + local active_pid_list = {} + for _,pid in ipairs(mtkwifi.__lines(content)) do + pid = pid:match("CHILD_PID=%s*(%d+)%s*") + if pid then + if tonumber(mtkwifi.read_pipe("ps | grep -v grep | grep -cw "..pid)) == 1 then + table.insert(active_pid_list, pid) + end + end + end + if next(active_pid_list) ~= nil then + return true + else + os.execute("rm -f "..mtkwifi.__child_info_path()) + return false + end + os.execute("sync >/dev/null 2>&1") +end + +function mtkwifi.__run_in_child_env(cbFn,...) + if type(cbFn) ~= "function" then + debug_write("__run_in_child_env : Function type expected, got ", type(cbFn)) + nixio.syslog("err", "__run_in_child_env : Function type expected, got "..type(cbFn)) + else + local unpack = unpack or table.unpack + local cbArgs = {...} + local nixio = require("nixio") + -- Let child process reap automatically! + if not nixio.signal(17,"ign") then + nixio.syslog("warning", "__run_in_child_env : Failed to set SIG_IGN for SIGCHLD!") + debug_write("__run_in_child_env : Failed to set SIG_IGN for SIGCHLD!") + end + local pid = nixio.fork() + if pid < 0 then + debug_write("__run_in_child_env : Fork failure") + nixio.syslog("err", "__run_in_child_env : Fork failure") + elseif pid == 0 then + -- Change to root dir to flush out any opened directory streams of parent process. + nixio.chdir("/") + + -- As file descriptors are inherited by child process, all unnecessary file descriptors must be closed. + -- Make stdin, out, err file descriptors point to /dev/null using dup2. + -- As a result, it will not corrupt stdin, out, err file descriptors of parent process. + local null = nixio.open("/dev/null", "w+") + if null then + nixio.dup(null, nixio.stderr) + nixio.dup(null, nixio.stdout) + nixio.dup(null, nixio.stdin) + if null:fileno() > 2 then + null:close() + end + end + local fd = io.open(mtkwifi.__child_info_path(), "a") + if fd then + fd:write("CHILD_PID=",nixio.getpid(),"\n") + fd:close() + end + cbFn(unpack(cbArgs)) + os.exit(true) + end + end + os.execute("sync >/dev/null 2>&1") +end + +-- Mode 12 and 13 are only available for STAs. +local WirelessModeList = { + [0] = "B/G mixed", + [1] = "B only", + [2] = "A only", + -- [3] = "A/B/G mixed", + [4] = "G only", + -- [5] = "A/B/G/GN/AN mixed", + [6] = "N in 2.4G only", + [7] = "G/GN", -- i.e., no CCK mode + [8] = "A/N in 5 band", + [9] = "B/G/GN mode", + -- [10] = "A/AN/G/GN mode", --not support B mode + [11] = "only N in 5G band", + -- [12] = "B/G/GN/A/AN/AC mixed", + -- [13] = "G/GN/A/AN/AC mixed", -- no B mode + [14] = "A/AC/AN mixed", + [15] = "AC/AN mixed", --but no A mode + [16] = "HE_2G mode", --HE Wireless Mode + [17] = "HE_5G mode", --HE Wireless Mode + [18] = "HE_6G mode", --HE Wireless Mode +} + +local DevicePropertyMap = { + -- 2.4G + { + device="MT7622", + band={"0", "1", "4", "9"}, + isPowerBoostSupported=true, + isMultiAPSupported=true, + isWPA3_192bitSupported=true + }, + + { + device="MT7620", + band={"0", "1", "4", "9"}, + maxTxStream=2, + maxRxStream=2, + maxVif=8 + }, + + { + device="MT7628", + band={"0", "1", "4", "6", "7", "9"}, + maxTxStream=2, + maxRxStream=2, + maxVif=8, + isMultiAPSupported=true, + isWPA3_192bitSupported=true + }, + + { + device="MT7603", + band={"0", "1", "4", "6", "7", "9"}, + maxTxStream=2, + maxRxStream=2, + maxVif=8, + isMultiAPSupported=true, + isWPA3_192bitSupported=true + }, + + -- 5G + { + device="MT7612", + band={"2", "8", "11", "14", "15"}, + maxTxStream=2, + maxRxStream=2, + }, + + { + device="MT7662", + band={"2", "8", "11", "14", "15"}, + maxTxStream=2, + maxRxStream=2, + }, + + -- Mix + { + device="MT7615", + band={"0", "1", "4", "9", "2", "8", "14", "15"}, + isPowerBoostSupported=false, + isMultiAPSupported=true, + isWPA3_192bitSupported=true, + maxVif=16, + maxDBDCVif=8 + }, + + { + device="MT7915", + band={"0", "1", "4", "9", "2", "8", "14", "15", "16", "17", "18"}, + isPowerBoostSupported=false, + isMultiAPSupported=true, + isWPA3_192bitSupported=true, + maxVif=16, + maxDBDCVif=16, + invalidChBwList={161} + }, + + { + device="MT7916", + band={"0", "1", "4", "9", "2", "8", "14", "15", "16", "17", "18"}, + isPowerBoostSupported=false, + isMultiAPSupported=true, + isWPA3_192bitSupported=true, + maxVif=16, + maxDBDCVif=16, + invalidChBwList={161}, + maxTxStream=2, + maxRxStream=2, + }, + + { + device="MT7981", + band={"0", "1", "4", "9", "2", "8", "14", "15", "16", "17", "18"}, + isPowerBoostSupported=false, + isMultiAPSupported=true, + isWPA3_192bitSupported=true, + maxVif=16, + maxDBDCVif=16, + invalidChBwList={161}, + maxTxStream=2, + maxRxStream=2, + }, + + { + device="MT7986", + band={"0", "1", "4", "9", "2", "8", "14", "15", "16", "17", "18"}, + isPowerBoostSupported=false, + isMultiAPSupported=true, + isWPA3_192bitSupported=true, + maxVif=16, + maxDBDCVif=16, + invalidChBwList={161}, + maxTxStream=4, + maxRxStream=4, + }, + + { + device="MT7663", + band={"0", "1", "4", "9", "2", "8", "14", "15"}, + maxTxStream=2, + maxRxStream=2, + invalidChBwList={160,161}, + isMultiAPSupported=true, + isWPA3_192bitSupported=true + }, + + { + device="MT7613", + band={"0", "1", "4", "9", "2", "8", "14", "15"}, + maxTxStream=2, + maxRxStream=2, + invalidChBwList={160,161}, + isMultiAPSupported=true, + isWPA3_192bitSupported=true + }, + + { + device="MT7626", + band={"0", "1", "4", "9", "2", "8", "14", "15"}, + maxTxStream=3, + maxRxStream=3, + invalidChBwList={160,161}, + wdsBand="2.4G", + mimoBand="5G", + maxDBDCVif=8 + }, + + { + device="MT7629", + band={"0", "1", "4", "9", "2", "8", "14", "15"}, + maxTxStream=3, + maxRxStream=3, + invalidChBwList={160,161}, + wdsBand="2.4G", + mimoBand="5G", + maxDBDCVif=8, + isMultiAPSupported=true + } +} + +mtkwifi.CountryRegionList_6G_All = { + {region=0, text="0: Ch1~233"}, + {region=1, text="1: Ch1~97"}, + {region=2, text="2: Ch101~117"}, + {region=3, text="3: Ch121~185"}, + {region=4, text="4: Ch189~233"}, + {region=5, text="5: Ch1~97"}, + {region=6, text="6: Ch1~97"}, + {region=7, text="7: Ch1~97, Ch101~109"}, +} + +mtkwifi.CountryRegionList_5G_All = { + {region=0, text="0: Ch36~64, Ch149~165"}, + {region=1, text="1: Ch36~64, Ch100~140"}, + {region=2, text="2: Ch36~64"}, + {region=3, text="3: Ch52~64, Ch149~161"}, + {region=4, text="4: Ch149~165"}, + {region=5, text="5: Ch149~161"}, + {region=6, text="6: Ch36~48"}, + {region=7, text="7: Ch36~64, Ch100~140, Ch149~165"}, + {region=8, text="8: Ch52~64"}, + {region=9, text="9: Ch36~64, Ch100~116, Ch132~140, Ch149~165"}, + {region=10, text="10: Ch36~48, Ch149~165"}, + {region=11, text="11: Ch36~64, Ch100~120, Ch149~161"}, + {region=12, text="12: Ch36~64, Ch100~144"}, + {region=13, text="13: Ch36~64, Ch100~144, Ch149~165"}, + {region=14, text="14: Ch36~64, Ch100~116, Ch132~144, Ch149~165"}, + {region=15, text="15: Ch149~173"}, + {region=16, text="16: Ch52~64, Ch149~165"}, + {region=17, text="17: Ch36~48, Ch149~161"}, + {region=18, text="18: Ch36~64, Ch100~116, Ch132~140"}, + {region=19, text="19: Ch56~64, Ch100~140, Ch149~161"}, + {region=20, text="20: Ch36~64, Ch100~124, Ch149~161"}, + {region=21, text="21: Ch36~64, Ch100~140, Ch149~161"}, + {region=22, text="22: Ch100~140"}, + {region=30, text="30: Ch36~48, Ch52~64, Ch100~140, Ch149~165"}, + {region=31, text="31: Ch52~64, Ch100~140, Ch149~165"}, + {region=32, text="32: Ch36~48, Ch52~64, Ch100~140, Ch149~161"}, + {region=33, text="33: Ch36~48, Ch52~64, Ch100~140"}, + {region=34, text="34: Ch36~48, Ch52~64, Ch149~165"}, + {region=35, text="35: Ch36~48, Ch52~64"}, + {region=36, text="36: Ch36~48, Ch100~140, Ch149~165"}, + {region=37, text="37: Ch36~48, Ch52~64, Ch149~165, Ch173"} +} + +mtkwifi.CountryRegionList_2G_All = { + {region=0, text="0: Ch1~11"}, + {region=1, text="1: Ch1~13"}, + {region=2, text="2: Ch10~11"}, + {region=3, text="3: Ch10~13"}, + {region=4, text="4: Ch14"}, + {region=5, text="5: Ch1~14"}, + {region=6, text="6: Ch3~9"}, + {region=7, text="7: Ch5~13"}, + {region=31, text="31: Ch1~11, Ch12~14"}, + {region=32, text="32: Ch1~11, Ch12~13"}, + {region=33, text="33: Ch1~14"} +} + +mtkwifi.ChannelList_6G_All = { + {channel= 0 , text="Channel 0 (Auto )", region={}}, + {channel= 1 , text="Channel 1 (5.955 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 5 , text="Channel 5 (5.975 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 9 , text="Channel 9 (5.995 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 13 , text="Channel 13 (6.015 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 17 , text="Channel 17 (6.035 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 21 , text="Channel 21 (6.055 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 25 , text="Channel 25 (6.075 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 29 , text="Channel 29 (6.095 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 33 , text="Channel 33 (6.115 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 37 , text="Channel 37 (6.135 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 41 , text="Channel 41 (6.155 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 45 , text="Channel 45 (6.175 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 49 , text="Channel 49 (6.195 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 53 , text="Channel 53 (6.215 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 57 , text="Channel 57 (6.235 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 61 , text="Channel 61 (6.255 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 65 , text="Channel 65 (6.275 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 69 , text="Channel 69 (6.295 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 73 , text="Channel 73 (6.315 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 77 , text="Channel 77 (6.335 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 81 , text="Channel 81 (6.355 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 85 , text="Channel 85 (6.375 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 89 , text="Channel 89 (6.395 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 93 , text="Channel 93 (6.415 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 97 , text="Channel 97 (6.435 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1}}, + {channel= 101, text="Channel 101 (6.455 GHz)", region={[0]=1, [2]=1, [7]=1}}, + {channel= 105, text="Channel 105 (6.475 GHz)", region={[0]=1, [2]=1, [7]=1}}, + {channel= 109, text="Channel 109 (6.495 GHz)", region={[0]=1, [2]=1, [7]=1}}, + {channel= 113, text="Channel 113 (6.515 GHz)", region={[0]=1, [2]=1}}, + {channel= 117, text="Channel 117 (6.535 GHz)", region={[0]=1, [2]=1}}, + {channel= 121, text="Channel 121 (6.555 GHz)", region={[0]=1, [3]=1}}, + {channel= 125, text="Channel 125 (6.575 GHz)", region={[0]=1, [3]=1}}, + {channel= 129, text="Channel 129 (6.595 GHz)", region={[0]=1, [3]=1}}, + {channel= 133, text="Channel 133 (6.615 GHz)", region={[0]=1, [3]=1}}, + {channel= 137, text="Channel 137 (6.635 GHz)", region={[0]=1, [3]=1}}, + {channel= 141, text="Channel 141 (6.655 GHz)", region={[0]=1, [3]=1}}, + {channel= 145, text="Channel 145 (6.675 GHz)", region={[0]=1, [3]=1}}, + {channel= 149, text="Channel 149 (6.695 GHz)", region={[0]=1, [3]=1}}, + {channel= 153, text="Channel 153 (6.715 GHz)", region={[0]=1, [3]=1}}, + {channel= 157, text="Channel 157 (6.735 GHz)", region={[0]=1, [3]=1}}, + {channel= 161, text="Channel 161 (6.755 GHz)", region={[0]=1, [3]=1}}, + {channel= 165, text="Channel 165 (6.775 GHz)", region={[0]=1, [3]=1}}, + {channel= 169, text="Channel 169 (6.795 GHz)", region={[0]=1, [3]=1}}, + {channel= 173, text="Channel 173 (6.815 GHz)", region={[0]=1, [3]=1}}, + {channel= 177, text="Channel 177 (6.835 GHz)", region={[0]=1, [3]=1}}, + {channel= 181, text="Channel 181 (6.855 GHz)", region={[0]=1, [3]=1}}, + {channel= 185, text="Channel 185 (6.875 GHz)", region={[0]=1, [3]=1}}, + {channel= 189, text="Channel 189 (6.895 GHz)", region={[0]=1, [4]=1}}, + {channel= 193, text="Channel 193 (6.915 GHz)", region={[0]=1, [4]=1}}, + {channel= 197, text="Channel 197 (6.935 GHz)", region={[0]=1, [4]=1}}, + {channel= 201, text="Channel 201 (6.955 GHz)", region={[0]=1, [4]=1}}, + {channel= 205, text="Channel 205 (6.975 GHz)", region={[0]=1, [4]=1}}, + {channel= 209, text="Channel 209 (6.995 GHz)", region={[0]=1, [4]=1}}, + {channel= 213, text="Channel 213 (7.015 GHz)", region={[0]=1, [4]=1}}, + {channel= 217, text="Channel 217 (7.035 GHz)", region={[0]=1, [4]=1}}, + {channel= 221, text="Channel 221 (7.055 GHz)", region={[0]=1, [4]=1}}, + {channel= 225, text="Channel 225 (7.075 GHz)", region={[0]=1, [4]=1}}, + {channel= 229, text="Channel 229 (7.095 GHz)", region={[0]=1, [4]=1}}, + {channel= 233, text="Channel 233 (7.115 GHz)", region={[0]=1, [4]=1}}, +} + +mtkwifi.ChannelList_5G_All = { + {channel=0, text="Channel 0 (Auto )", region={}}, + {channel= 36, text="Channel 36 (5.180 GHz)", region={[0]=1, [1]=1, [2]=1, [6]=1, [7]=1, [9]=1, [10]=1, [11]=1, [12]=1, [13]=1, [14]=1, [17]=1, [18]=1, [20]=1, [21]=1, [30]=1, [32]=1, [33]=1, [34]=1, [35]=1, [36]=1, [37]=1}}, + {channel= 40, text="Channel 40 (5.200 GHz)", region={[0]=1, [1]=1, [2]=1, [6]=1, [7]=1, [9]=1, [10]=1, [11]=1, [12]=1, [13]=1, [14]=1, [17]=1, [18]=1, [20]=1, [21]=1, [30]=1, [32]=1, [33]=1, [34]=1, [35]=1, [36]=1, [37]=1}}, + {channel= 44, text="Channel 44 (5.220 GHz)", region={[0]=1, [1]=1, [2]=1, [6]=1, [7]=1, [9]=1, [10]=1, [11]=1, [12]=1, [13]=1, [14]=1, [17]=1, [18]=1, [20]=1, [21]=1, [30]=1, [32]=1, [33]=1, [34]=1, [35]=1, [36]=1, [37]=1}}, + {channel= 48, text="Channel 48 (5.240 GHz)", region={[0]=1, [1]=1, [2]=1, [6]=1, [7]=1, [9]=1, [10]=1, [11]=1, [12]=1, [13]=1, [14]=1, [17]=1, [18]=1, [20]=1, [21]=1, [30]=1, [32]=1, [33]=1, [34]=1, [35]=1, [36]=1, [37]=1}}, + {channel= 52, text="Channel 52 (5.260 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [7]=1, [8]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [16]=1, [18]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [33]=1, [34]=1, [35]=1, [37]=1}}, + {channel= 56, text="Channel 56 (5.280 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [7]=1, [8]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [16]=1, [18]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [33]=1, [34]=1, [35]=1, [37]=1}}, + {channel= 60, text="Channel 60 (5.300 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [7]=1, [8]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [16]=1, [18]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [33]=1, [34]=1, [35]=1, [37]=1}}, + {channel= 64, text="Channel 64 (5.320 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [7]=1, [8]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [16]=1, [18]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [33]=1, [34]=1, [35]=1, [37]=1}}, + {channel=100, text="Channel 100 (5.500 GHz)", region={[1]=1, [7]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=104, text="Channel 104 (5.520 GHz)", region={[1]=1, [7]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=108, text="Channel 108 (5.540 GHz)", region={[1]=1, [7]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=112, text="Channel 112 (5.560 GHz)", region={[1]=1, [7]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=116, text="Channel 116 (5.580 GHz)", region={[1]=1, [7]=1, [9]=1, [11]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=120, text="Channel 120 (5.600 GHz)", region={[1]=1, [7]=1, [11]=1, [12]=1, [13]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=124, text="Channel 124 (5.620 GHz)", region={[1]=1, [7]=1, [12]=1, [13]=1, [19]=1, [20]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=128, text="Channel 128 (5.640 GHz)", region={[1]=1, [7]=1, [12]=1, [13]=1, [19]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=132, text="Channel 132 (5.660 GHz)", region={[1]=1, [7]=1, [9]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=136, text="Channel 136 (5.680 GHz)", region={[1]=1, [7]=1, [9]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=140, text="Channel 140 (5.700 GHz)", region={[1]=1, [7]=1, [9]=1, [12]=1, [13]=1, [14]=1, [18]=1, [19]=1, [21]=1, [22]=1, [30]=1, [31]=1, [32]=1, [33]=1, [36]=1}}, + {channel=144, text="Channel 144 (5.720 GHz)", region={[12]=1, [13]=1, [14]=1}}, + {channel=149, text="Channel 149 (5.745 GHz)", region={[0]=1, [3]=1, [4]=1, [5]=1, [7]=1, [9]=1, [10]=1, [11]=1, [13]=1, [14]=1, [15]=1, [16]=1, [17]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [34]=1, [36]=1, [37]=1}}, + {channel=153, text="Channel 153 (5.765 GHz)", region={[0]=1, [3]=1, [4]=1, [5]=1, [7]=1, [9]=1, [10]=1, [11]=1, [13]=1, [14]=1, [15]=1, [16]=1, [17]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [34]=1, [36]=1, [37]=1}}, + {channel=157, text="Channel 157 (5.785 GHz)", region={[0]=1, [3]=1, [4]=1, [5]=1, [7]=1, [9]=1, [10]=1, [11]=1, [13]=1, [14]=1, [15]=1, [16]=1, [17]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [34]=1, [36]=1, [37]=1}}, + {channel=161, text="Channel 161 (5.805 GHz)", region={[0]=1, [3]=1, [4]=1, [5]=1, [7]=1, [9]=1, [10]=1, [11]=1, [13]=1, [14]=1, [15]=1, [16]=1, [17]=1, [19]=1, [20]=1, [21]=1, [30]=1, [31]=1, [32]=1, [34]=1, [36]=1, [37]=1}}, + {channel=165, text="Channel 165 (5.825 GHz)", region={[0]=1, [4]=1, [7]=1, [9]=1, [10]=1, [13]=1, [14]=1, [15]=1, [16]=1, [30]=1, [31]=1, [34]=1, [36]=1, [37]=1}}, + {channel=169, text="Channel 169 (5.845 GHz)", region={[15]=1}}, + {channel=173, text="Channel 173 (5.865 GHz)", region={[15]=1, [37]=1}} +} + +mtkwifi.ChannelList_2G_All = { + {channel=0, text="Channel 0 (Auto )", region={}}, + {channel= 1, text="Channel 1 (2412 GHz)", region={[0]=1, [1]=1, [5]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 2, text="Channel 2 (2417 GHz)", region={[0]=1, [1]=1, [5]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 3, text="Channel 3 (2422 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 4, text="Channel 4 (2427 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 5, text="Channel 5 (2432 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 6, text="Channel 6 (2437 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 7, text="Channel 7 (2442 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 8, text="Channel 8 (2447 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel= 9, text="Channel 9 (2452 GHz)", region={[0]=1, [1]=1, [5]=1, [6]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel=10, text="Channel 10 (2457 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [5]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel=11, text="Channel 11 (2462 GHz)", region={[0]=1, [1]=1, [2]=1, [3]=1, [5]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel=12, text="Channel 12 (2467 GHz)", region={[1]=1, [3]=1, [5]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel=13, text="Channel 13 (2472 GHz)", region={[1]=1, [3]=1, [5]=1, [7]=1, [31]=1, [32]=1, [33]=1}}, + {channel=14, text="Channel 14 (2477 GHz)", region={[4]=1, [5]=1, [31]=1, [33]=1}} +} + +mtkwifi.ChannelList_5G_2nd_80MHZ_ALL = { + {channel=36, text="Ch36(5.180 GHz) - Ch48(5.240 GHz)", chidx=2}, + {channel=52, text="Ch52(5.260 GHz) - Ch64(5.320 GHz)", chidx=6}, + {channel=-1, text="Channel between 64 100", chidx=-1}, + {channel=100, text="Ch100(5.500 GHz) - Ch112(5.560 GHz)", chidx=10}, + {channel=112, text="Ch116(5.580 GHz) - Ch128(5.640 GHz)", chidx=14}, + {channel=-1, text="Channel between 128 132", chidx=-1}, + {channel=132, text="Ch132(5.660 GHz) - Ch144(5.720 GHz)", chidx=18}, + {channel=-1, text="Channel between 144 149", chidx=-1}, + {channel=149, text="Ch149(5.745 GHz) - Ch161(5.805 GHz)", chidx=22} +} + +local AuthModeList = { + "Disable", + "OPEN",--OPENWEP + "Enhanced Open", + "SHARED",--SHAREDWEP + "WEPAUTO", + "WPA2", + "WPA3", + "WPA3-192-bit", + "WPA2PSK", + "WPA3PSK", + "WPAPSKWPA2PSK", + "WPA2PSKWPA3PSK", + "WPA1WPA2", + "IEEE8021X" +} + +local AuthModeList_6G = { + "Enhanced Open", + "WPA3PSK" +} + +local WpsEnableAuthModeList = { + "Disable", + "OPEN",--OPENWEP + "WPA2PSK", + "WPAPSKWPA2PSK" +} + +local WpsEnableAuthModeList_6G = { + "Disable", + "WPA2PSK", + "WPAPSKWPA2PSK" +} + +local ApCliAuthModeList = { + "Disable", + "OPEN", + "SHARED", + "Enhanced Open", + "WPAPSK", + "WPA2PSK", + "WPA3PSK", + -- "WPAPSKWPA2PSK", + -- "WPA2PSKWPA3PSK", + -- "WPA", + -- "WPA2", + -- "WPAWPA2", + -- "8021X", +} + +local EncryptionTypeList = { + "WEP", + "TKIP", + "TKIPAES", + "AES", + "GCMP256" +} + +local EncryptionTypeList_6G = { + "WEP", + "AES", + "GCMP256" +} + +local dbdc_prefix = { + {"ra", "rax"}, + {"rai", "ray"}, + {"rae", "raz"} +} + +local dbdc_apcli_prefix = { + {"apcli", "apclix"}, + {"apclii", "apcliy"}, + {"apclie", "apcliz"} +} + +function mtkwifi.band(mode) + local i = tonumber(mode) + if i == 0 + or i == 1 + or i == 4 + or i == 6 + or i == 7 + or i == 9 + or i == 16 then + return "2.4G" + elseif i == 18 then + return "6G" + else + return "5G" + end +end + + +function mtkwifi.__cfg2list(str) + -- delimeter == ";" + local i = 1 + local list = {} + for k in string.gmatch(str, "([^;]+)") do + list[i] = k + i = i + 1 + end + return list +end + +function mtkwifi.token_set(str, n, v) + -- n start from 1 + -- delimeter == ";" + if not str then return end + local tmp = mtkwifi.__cfg2list(str) + if type(v) ~= type("") and type(v) ~= type(0) then + nixio.syslog("err", "invalid value type in token_set, "..type(v)) + return + end + if #tmp < tonumber(n) then + for i=#tmp, tonumber(n) do + if not tmp[i] then + tmp[i] = v -- pad holes with v ! + end + end + else + tmp[n] = v + end + return table.concat(tmp, ";"):gsub("^;*(.-);*$", "%1"):gsub(";+",";") +end + + +function mtkwifi.token_get(str, n, v) + -- n starts from 1 + -- v is the backup in case token n is nil + if not str then return v end + local tmp = mtkwifi.__cfg2list(str) + return tmp[tonumber(n)] or v +end + +function mtkwifi.search_dev_and_profile_orig() + local nixio = require("nixio") + local dir = io.popen("ls /etc/wireless/") + if not dir then return end + local result = {} + -- case 1: mt76xx.dat (best) + -- case 2: mt76xx.n.dat (multiple card of same dev) + -- case 3: mt76xx.n.nG.dat (case 2 plus dbdc and multi-profile, bloody hell....) + for line in dir:lines() do + -- nixio.syslog("debug", "scan "..line) + local tmp = io.popen("find /etc/wireless/"..line.." -type f -name \"*.dat\"") + for datfile in tmp:lines() do + -- nixio.syslog("debug", "test "..datfile) + + repeat do + -- for case 1 + local devname = string.match(datfile, "("..line..").dat") + if devname then + result[devname] = datfile + -- nixio.syslog("debug", "yes "..devname.."="..datfile) + break + end + -- for case 2 + local devname = string.match(datfile, "("..line.."%.%d)%.dat") + if devname then + result[devname] = datfile + -- nixio.syslog("debug", "yes "..devname.."="..datfile) + break + end + -- for case 3 + local devname = string.match(datfile, "("..line.."%.%d%.%dG)%.dat") + if devname then + result[devname] = datfile + -- nixio.syslog("debug", "yes "..devname.."="..datfile) + break + end + end until true + end + end + + for k,v in pairs(result) do + nixio.syslog("debug", "search_dev_and_profile_orig: "..k.."="..v) + end + + return result +end + +function mtkwifi.search_dev_and_profile_l1() + local l1dat = mtkwifi.__get_l1dat() + + if not l1dat then return end + + local nixio = require("nixio") + local result = {} + local dbdc_2nd_if = "" + + for k, dev in ipairs(l1dat) do + dbdc_2nd_if = mtkwifi.token_get(dev.main_ifname, 2, nil) + if dbdc_2nd_if then + result[dev["INDEX"].."."..dev["mainidx"]..".1"] = mtkwifi.token_get(dev.profile_path, 1, nil) + result[dev["INDEX"].."."..dev["mainidx"]..".2"] = mtkwifi.token_get(dev.profile_path, 2, nil) + else + result[dev["INDEX"].."."..dev["mainidx"]] = dev.profile_path + end + end + +-- for k,v in pairs(result) do +-- nixio.syslog("debug", "search_dev_and_profile_l1: "..k.."="..v) +-- end + + return result +end + +function mtkwifi.search_dev_and_profile() + return mtkwifi.search_dev_and_profile_l1() or mtkwifi.search_dev_and_profile_orig() +end + +function mtkwifi.__setup_vifs(cfgs, devname, mainidx, subidx) + local l1dat, l1 = mtkwifi.__get_l1dat() + local dridx = l1dat and l1.DEV_RINDEX + + local prefix + local main_ifname + local vifs = {} + local dev_idx = "" + + + prefix = l1dat and l1dat[dridx][devname].ext_ifname or dbdc_prefix[mainidx][subidx] + + dev_idx = string.match(devname, "(%w+)") + + vifs["__prefix"] = prefix + if (cfgs.BssidNum == nil) then + debug_write("BssidNum configuration value not found.") + nixio.syslog("debug","BssidNum configuration value not found.") + return + end + + for j=1,tonumber(cfgs.BssidNum) do + vifs[j] = {} + vifs[j].vifidx = j -- start from 1 + dev_idx = string.match(devname, "(%w+)") + main_ifname = l1dat and l1dat[dridx][devname].main_ifname or dbdc_prefix[mainidx][subidx].."0" + vifs[j].vifname = j == 1 and main_ifname or prefix..(j-1) + if mtkwifi.exists("/sys/class/net/"..vifs[j].vifname) then + local flags = tonumber(mtkwifi.read_pipe("cat /sys/class/net/"..vifs[j].vifname.."/flags 2>/dev/null")) or 0 + vifs[j].state = flags%2 == 1 and "up" or "down" + end + vifs[j].__ssid = cfgs["SSID"..j] + local rd_pipe_output = mtkwifi.read_pipe("cat /sys/class/net/"..prefix..(j-1).."/address 2>/dev/null") + vifs[j].__bssid = rd_pipe_output and string.match(rd_pipe_output, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") or "?" + + vifs[j].__temp_ssid = mtkwifi.__trim(mtkwifi.read_pipe("iwconfig "..vifs[j].vifname.." | grep ESSID | cut -d : -f 2")) + vifs[j].__temp_channel = mtkwifi.read_pipe("iwconfig "..vifs[j].vifname.." | grep Channel | cut -d = -f 2 | cut -d \" \" -f 1") + if string.gsub(vifs[j].__temp_channel, "^%s*(.-)%s*$", "%1") == "" then + vifs[j].__temp_channel = mtkwifi.read_pipe("iwconfig "..vifs[j].vifname.." | grep Channel | cut -d : -f 3 | cut -d \" \" -f 1") + end + vifs[j].__wirelessmode_table = c_getWMode(vifs[j].vifname) + vifs[j].__temp_wirelessmode = vifs[j].__wirelessmode_table['getwmode'] + + if (vifs[j].__temp_ssid ~= "") then + vifs[j].__ssid = vifs[j].__temp_ssid:gsub("^\"(.-)\"$","%1") + else + vifs[j].__ssid = cfgs["SSID"..j] + end + + if (vifs[j].__temp_channel ~= "" ) then + vifs[j].__channel = vifs[j].__temp_channel + else + vifs[j].__channel = cfgs.Channel + end + + if (vifs[j].__temp_wirelessmode ~= "" and vifs[j].__temp_wirelessmode ~= "0") then + vifs[j].__wirelessmode = vifs[j].__temp_wirelessmode + else + vifs[j].__wirelessmode = mtkwifi.token_get(cfgs.WirelessMode, j, 0) + end + + vifs[j].__authmode = mtkwifi.token_get(cfgs.AuthMode, j, mtkwifi.__split(cfgs.AuthMode,";")[1]) + vifs[j].__encrypttype = mtkwifi.token_get(cfgs.EncrypType, j, mtkwifi.__split(cfgs.EncrypType,";")[1]) + vifs[j].__hidessid = mtkwifi.token_get(cfgs.HideSSID, j, mtkwifi.__split(cfgs.HideSSID,";")[1]) + vifs[j].__noforwarding = mtkwifi.token_get(cfgs.NoForwarding, j, mtkwifi.__split(cfgs.NoForwarding,";")[1]) + vifs[j].__wmmcapable = mtkwifi.token_get(cfgs.WmmCapable, j, mtkwifi.__split(cfgs.WmmCapable,";")[1]) + vifs[j].__txrate = mtkwifi.token_get(cfgs.TxRate, j, mtkwifi.__split(cfgs.TxRate,";")[1]) + vifs[j].__ieee8021x = mtkwifi.token_get(cfgs.IEEE8021X, j, mtkwifi.__split(cfgs.IEEE8021X,";")[1]) + vifs[j].__preauth = mtkwifi.token_get(cfgs.PreAuth, j, mtkwifi.__split(cfgs.PreAuth,";")[1]) + vifs[j].__rekeymethod = mtkwifi.token_get(cfgs.RekeyMethod, j, mtkwifi.__split(cfgs.RekeyMethod,";")[1]) + vifs[j].__rekeyinterval = mtkwifi.token_get(cfgs.RekeyInterval, j, mtkwifi.__split(cfgs.RekeyInterval,";")[1]) + vifs[j].__pmkcacheperiod = mtkwifi.token_get(cfgs.PMKCachePeriod, j, mtkwifi.__split(cfgs.PMKCachePeriod,";")[1]) + vifs[j].__ht_extcha = mtkwifi.token_get(cfgs.HT_EXTCHA, j, mtkwifi.__split(cfgs.HT_EXTCHA,";")[1]) + vifs[j].__radius_server = mtkwifi.token_get(cfgs.RADIUS_Server, j, mtkwifi.__split(cfgs.RADIUS_Server,";")[1]) + vifs[j].__radius_port = mtkwifi.token_get(cfgs.RADIUS_Port, j, mtkwifi.__split(cfgs.RADIUS_Port,";")[1]) + vifs[j].__wepkey_id = mtkwifi.token_get(cfgs.DefaultKeyID, j, mtkwifi.__split(cfgs.DefaultKeyID,";")[1]) + vifs[j].__wscconfmode = mtkwifi.token_get(cfgs.WscConfMode, j, mtkwifi.__split(cfgs.WscConfMode,";")[1]) + vifs[j].__wepkeys = { + cfgs["Key1Str"..j], + cfgs["Key2Str"..j], + cfgs["Key3Str"..j], + cfgs["Key4Str"..j], + } + vifs[j].__wpapsk = cfgs["WPAPSK"..j] + vifs[j].__ht_stbc = mtkwifi.token_get(cfgs.HT_STBC, j, mtkwifi.__split(cfgs.HT_STBC,";")[1]) + vifs[j].__ht_ldpc = mtkwifi.token_get(cfgs.HT_LDPC, j, mtkwifi.__split(cfgs.HT_LDPC,";")[1]) + vifs[j].__vht_stbc = mtkwifi.token_get(cfgs.VHT_STBC, j, mtkwifi.__split(cfgs.VHT_STBC,";")[1]) + vifs[j].__vht_ldpc = mtkwifi.token_get(cfgs.VHT_LDPC, j, mtkwifi.__split(cfgs.VHT_LDPC,";")[1]) + vifs[j].__dls_capable = mtkwifi.token_get(cfgs.DLSCapable, j, mtkwifi.__split(cfgs.DLSCapable,";")[1]) + vifs[j].__apsd_capable = mtkwifi.token_get(cfgs.APSDCapable, j, mtkwifi.__split(cfgs.APSDCapable,";")[1]) + vifs[j].__frag_threshold = mtkwifi.token_get(cfgs.FragThreshold, j, mtkwifi.__split(cfgs.FragThreshold,";")[1]) + vifs[j].__rts_threshold = mtkwifi.token_get(cfgs.RTSThreshold, j, mtkwifi.__split(cfgs.RTSThreshold,";")[1]) + vifs[j].__vht_sgi = mtkwifi.token_get(cfgs.VHT_SGI, j, mtkwifi.__split(cfgs.VHT_SGI,";")[1]) + vifs[j].__vht_bw_signal = mtkwifi.token_get(cfgs.VHT_BW_SIGNAL, j, mtkwifi.__split(cfgs.VHT_BW_SIGNAL,";")[1]) + vifs[j].__ht_protect = mtkwifi.token_get(cfgs.HT_PROTECT, j, mtkwifi.__split(cfgs.HT_PROTECT,";")[1]) + vifs[j].__ht_gi = mtkwifi.token_get(cfgs.HT_GI, j, mtkwifi.__split(cfgs.HT_GI,";")[1]) + vifs[j].__ht_opmode = mtkwifi.token_get(cfgs.HT_OpMode, j, mtkwifi.__split(cfgs.HT_OpMode,";")[1]) + vifs[j].__ht_amsdu = mtkwifi.token_get(cfgs.HT_AMSDU, j, mtkwifi.__split(cfgs.HT_AMSDU,";")[1]) + vifs[j].__ht_autoba = mtkwifi.token_get(cfgs.HT_AutoBA, j, mtkwifi.__split(cfgs.HT_AutoBA,";")[1]) + vifs[j].__igmp_snenable = mtkwifi.token_get(cfgs.IgmpSnEnable, j, mtkwifi.__split(cfgs.IgmpSnEnable,";")[1]) + vifs[j].__wdsenable = mtkwifi.token_get(cfgs.WdsEnable, j, mtkwifi.__split(cfgs.WdsEnable,";")[1]) + + -- VoW + vifs[j].__atc_tp = mtkwifi.token_get(cfgs.VOW_Rate_Ctrl_En, j, mtkwifi.__split(cfgs.VOW_Rate_Ctrl_En,";")[1]) + vifs[j].__atc_min_tp = mtkwifi.token_get(cfgs.VOW_Group_Min_Rate, j, mtkwifi.__split(cfgs.VOW_Group_Min_Rate,";")[1]) + vifs[j].__atc_max_tp = mtkwifi.token_get(cfgs.VOW_Group_Max_Rate, j, mtkwifi.__split(cfgs.VOW_Group_Max_Rate,";")[1]) + vifs[j].__atc_at = mtkwifi.token_get(cfgs.VOW_Airtime_Ctrl_En, j, mtkwifi.__split(cfgs.VOW_Airtime_Ctrl_En,";")[1]) + vifs[j].__atc_min_at = mtkwifi.token_get(cfgs.VOW_Group_Min_Ratio, j, mtkwifi.__split(cfgs.VOW_Group_Min_Ratio,";")[1]) + vifs[j].__atc_max_at = mtkwifi.token_get(cfgs.VOW_Group_Max_Ratio, j, mtkwifi.__split(cfgs.VOW_Group_Max_Ratio,";")[1]) + + -- TODO index by vifname + vifs[vifs[j].vifname] = vifs[j] + + -- OFDMA and MU-MIMO + vifs[j].__muofdma_dlenable = mtkwifi.token_get(cfgs.MuOfdmaDlEnable, j, mtkwifi.__split(cfgs.MuOfdmaDlEnable,";")[1]) + vifs[j].__muofdma_ulenable = mtkwifi.token_get(cfgs.MuOfdmaUlEnable, j, mtkwifi.__split(cfgs.MuOfdmaUlEnable,";")[1]) + vifs[j].__mumimo_dlenable = mtkwifi.token_get(cfgs.MuMimoDlEnable, j, mtkwifi.__split(cfgs.MuMimoDlEnable,";")[1]) + vifs[j].__mumimo_ulenable = mtkwifi.token_get(cfgs.MuMimoUlEnable, j, mtkwifi.__split(cfgs.MuMimoUlEnable,";")[1]) + + end + + return vifs +end + +function mtkwifi.__setup_apcli(cfgs, devname, mainidx, subidx) + local l1dat, l1 = mtkwifi.__get_l1dat() + local dridx = l1dat and l1.DEV_RINDEX + + local apcli = {} + local dev_idx = string.match(devname, "(%w+)") + local apcli_prefix = l1dat and l1dat[dridx][devname].apcli_ifname or + dbdc_apcli_prefix[mainidx][subidx] + + local apcli_name = apcli_prefix.."0" + + if mtkwifi.exists("/sys/class/net/"..apcli_name) then + apcli.vifname = apcli_name + apcli.devname = apcli_name + apcli.vifidx = "1" + local rd_pipe_output = mtkwifi.read_pipe("iwconfig "..apcli_name.." | grep ESSID 2>/dev/null") + local ssid = rd_pipe_output and string.match(rd_pipe_output, "ESSID:\"(.*)\"") + if not ssid or ssid == "" then + apcli.status = "Disconnected" + else + apcli.ssid = ssid + apcli.status = "Connected" + end + local flags = tonumber(mtkwifi.read_pipe("cat /sys/class/net/"..apcli_name.."/flags 2>/dev/null")) or 0 + apcli.state = flags%2 == 1 and "up" or "down" + rd_pipe_output = mtkwifi.read_pipe("cat /sys/class/net/"..apcli_name.."/address 2>/dev/null") + apcli.mac_addr = rd_pipe_output and string.match(rd_pipe_output, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") or "?" + rd_pipe_output = mtkwifi.read_pipe("iwconfig "..apcli_name.." | grep 'Access Point' 2>/dev/null") + apcli.bssid = rd_pipe_output and string.match(rd_pipe_output, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x") or "Not-Associated" + return apcli + else + return + end +end + +function mtkwifi.__setup_eths() + local etherInfo = {} + local all_eth_devs = mtkwifi.read_pipe("ls /sys/class/net/ | grep eth | grep -v grep") + if not all_eth_devs or all_eth_devs == "" then + return + end + for ethName in string.gmatch(all_eth_devs, "(eth%d)") do + local ethInfo = {} + ethInfo['ifname'] = ethName + local flags = tonumber(mtkwifi.read_pipe("cat /sys/class/net/"..ethName.."/flags 2>/dev/null")) or 0 + ethInfo['state'] = flags%2 == 1 and "up" or "down" + ethInfo['mac_addr'] = mtkwifi.read_pipe("cat /sys/class/net/"..ethName.."/address 2>/dev/null") or "?" + table.insert(etherInfo,ethInfo) + end + return etherInfo +end + +function mtkwifi.get_all_devs() + local nixio = require("nixio") + local devs = {} + local i = 1 -- dev idx + local profiles = mtkwifi.search_dev_and_profile() + local wpa_support = 0 + local wapi_support = 0 + + for devname,profile in mtkwifi.__spairs(profiles, function(a,b) return string.upper(a) < string.upper(b) end) do + local fd = io.open(profile,"r") + if not fd then + nixio.syslog("debug", "cannot find "..profile) + else + fd:close() + local cfgs = mtkwifi.load_profile(profile) + if not cfgs then + debug_write("error loading profile"..profile) + nixio.syslog("err", "error loading "..profile) + return + end + devs[i] = {} + devs[i].vifs = {} + devs[i].apcli = {} + devs[i].devname = devname + devs[i].profile = profile + local tmp = "" + tmp = string.split(devname, ".") + devs[i].maindev = tmp[1] + devs[i].mainidx = tonumber(tmp[2]) or 1 + devs[i].subdev = devname + devs[i].subidx = string.match(tmp[3] or "", "(%d+)")=="2" and 2 or 1 + devs[i].devband = tonumber(tmp[3]) + if devs[i].devband then + devs[i].multiprofile = true + devs[i].dbdc = true + devs[i].dbdcBandName = (profile:match("2[gG]") and "2.4G") or (profile:match("5[gG]") and "5G") + if not devs[i].dbdcBandName then + -- Make 1st band as 2.4G and 2nd band as 5G. + devs[i].dbdcBandName = (devs[i].devband == 1) and "2.4G" or "5G" + end + end + + devs[i].ApCliEnable = cfgs.ApCliEnable + devs[i].WirelessMode = string.split(cfgs.WirelessMode,";")[1] + devs[i].WirelessModeList = {} + for key, value in pairs(DevicePropertyMap) do + local found = string.find(string.upper(devname), string.upper(value.device)) + if found then + for k=1,#value.band do + devs[i].WirelessModeList[tonumber(value.band[k])] = WirelessModeList[tonumber(value.band[k])] + end + + if devs[i].dbdc == true then + devs[i].maxVif = value.maxDBDCVif or value.maxVif/2 + else + devs[i].maxVif = value.maxVif or 16 + end + + devs[i].maxTxStream = value.maxTxStream + devs[i].maxRxStream = value.maxRxStream + devs[i].invalidChBwList = value.invalidChBwList + devs[i].isPowerBoostSupported = value.isPowerBoostSupported + devs[i].wdsBand = value.wdsBand + devs[i].mimoBand = value.mimoBand + devs[i].isMultiAPSupported = value.isMultiAPSupported + devs[i].isWPA3_192bitSupported = value.isWPA3_192bitSupported + end + end + devs[i].WscConfMode = cfgs.WscConfMode + devs[i].AuthModeList = AuthModeList + devs[i].AuthModeList_6G = AuthModeList_6G + devs[i].WpsEnableAuthModeList = WpsEnableAuthModeList + devs[i].WpsEnableAuthModeList_6G = WpsEnableAuthModeList_6G + + if wpa_support == 1 then + table.insert(devs[i].AuthModeList,"WPAPSK") + table.insert(devs[i].AuthModeList,"WPA") + end + + if wapi_support == 1 then + table.insert(devs[i].AuthModeList,"WAIPSK") + table.insert(devs[i].AuthModeList,"WAICERT") + end + devs[i].ApCliAuthModeList = ApCliAuthModeList + devs[i].EncryptionTypeList = EncryptionTypeList + devs[i].EncryptionTypeList_6G = EncryptionTypeList_6G + devs[i].Channel = tonumber(cfgs.Channel) + devs[i].DBDC_MODE = tonumber(cfgs.DBDC_MODE) + devs[i].band = devs[i].devband or mtkwifi.band(string.split(cfgs.WirelessMode,";")[1]) + + if cfgs.MUTxRxEnable then + if tonumber(cfgs.ETxBfEnCond)==1 + and tonumber(cfgs.MUTxRxEnable)==0 + and tonumber(cfgs.ITxBfEn)==0 + then devs[i].__mimo = 0 + elseif tonumber(cfgs.ETxBfEnCond)==0 + and tonumber(cfgs.MUTxRxEnable)==0 + and tonumber(cfgs.ITxBfEn)==1 + then devs[i].__mimo = 1 + elseif tonumber(cfgs.ETxBfEnCond)==1 + and tonumber(cfgs.MUTxRxEnable)==0 + and tonumber(cfgs.ITxBfEn)==1 + then devs[i].__mimo = 2 + elseif tonumber(cfgs.ETxBfEnCond)==1 + and tonumber(cfgs.MUTxRxEnable)>0 + and tonumber(cfgs.ITxBfEn)==0 + then devs[i].__mimo = 3 + elseif tonumber(cfgs.ETxBfEnCond)==1 + and tonumber(cfgs.MUTxRxEnable)>0 + and tonumber(cfgs.ITxBfEn)==1 + then devs[i].__mimo = 4 + else devs[i].__mimo = 5 + end + end + + if cfgs.HT_BW == "0" or not cfgs.HT_BW then + devs[i].__bw = "20" + elseif cfgs.HT_BW == "1" and cfgs.VHT_BW == "0" or not cfgs.VHT_BW then + if cfgs.HT_BSSCoexistence == "0" or not cfgs.HT_BSSCoexistence then + devs[i].__bw = "40" + else + devs[i].__bw = "60" -- 20/40 coexist + end + elseif cfgs.HT_BW == "1" and cfgs.VHT_BW == "1" then + devs[i].__bw = "80" + elseif cfgs.HT_BW == "1" and cfgs.VHT_BW == "2" then + devs[i].__bw = "160" + elseif cfgs.HT_BW == "1" and cfgs.VHT_BW == "3" then + devs[i].__bw = "161" + end + + devs[i].vifs = mtkwifi.__setup_vifs(cfgs, devname, devs[i].mainidx, devs[i].subidx) + devs[i].apcli = mtkwifi.__setup_apcli(cfgs, devname, devs[i].mainidx, devs[i].subidx) + + if mtkwifi.exists("cat /etc/wireless/"..devs[i].maindev.."/version") then + local version = mtkwifi.read_pipe("cat /etc/wireless/"..devs[i].maindev.."/version 2>/dev/null") + devs[i].version = (type(version) == "string" and version ~= "") and version or "Unknown: Empty version file!" + else + local vif_name = nil + if devs[i].apcli and devs[i].apcli["state"] == "up" then + vif_name = devs[i].apcli["vifname"] + elseif devs[i].vifs then + for _,vif in ipairs(devs[i].vifs) do + if vif["state"] == "up" then + vif_name = vif["vifname"] + break + end + end + end + if not vif_name then + if tonumber(cfgs.BssidNum) >= 1 then + devs[i].version = "Enable an interface to get the driver version." + elseif devs[i].apcli and devs[i].apcli["state"] ~= "up" then + devs[i].version = "Enable ApCli interface i.e. "..devs[i].apcli["vifname"].." to get the driver version." + else + devs[i].version = "Add an interface to get the driver version." + end + else + local version = mtkwifi.read_pipe("iwpriv "..vif_name.." get_driverinfo") + version = version and version:match("Driver version: (.-)\n") or "" + devs[i].version = version ~= "" and version or "Unknown: Incorrect response from version command!" + end + end + + -- Setup reverse indices by devname + devs[devname] = devs[i] + + if devs[i].apcli then + devs[i][devs[i].apcli.devname] = devs[i].apcli + end + + i = i + 1 + end + end + devs['etherInfo'] = mtkwifi.__setup_eths() + return devs +end + +function mtkwifi.exists(path) + local fp = io.open(path, "rb") + if fp then fp:close() end + return fp ~= nil +end + +function mtkwifi.parse_mac(str) + local macs = {} + local pat = "^[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]:[0-9a-fA-F][0-9a-fA-F]$" + + local function ismac(str) + if str:match(pat) then return str end + end + + if not str then return macs end + local t = str:split("\n") + for _,v in pairs(t) do + local mac = ismac(mtkwifi.__trim(v)) + if mac then + table.insert(macs, mac) + end + end + + return macs + -- body +end + + +function mtkwifi.scan_ap(vifname) + os.execute("iwpriv "..vifname.." set SiteSurvey=0") + os.execute("sleep 10") -- depends on your env + local op = c_scanResult(vifname, 0) + local scan_result = op["scanresult"] + local next_line_index = 0 + local cur_index + local total_index = 0 + local ap_list = {} + local xx = {} + local tmp + + while (1) do + for i, line in ipairs(mtkwifi.__lines(scan_result)) do + local is_mac_addr_present = string.match(line, "%s+%x%x:%x%x:%x%x:%x%x:%x%x:%x%x%s+") + -- If the line does not contain any MAC address and length is greater than 40 bytes, + -- then, the line is the header of the get_site_survey page. + local total_str = string.find(line, "Total=") + if total_str == 1 then + total_index = tonumber(line:match("%d+")) + end + + if #line>40 and not is_mac_addr_present then + xx.Ch = {string.find(line, "Ch "),3} + xx.SSID = {string.find(line, "SSID "),32} + local fidx = string.find(line, "SSID_Len") + if fidx then + xx.SSID_len = {fidx,2} + end + xx.BSSID = {string.find(line, "BSSID "),17} + xx.Security = {string.find(line, "Security "),22} + xx.Signal = {string.find(line, "Sig%a%al"),4} + xx.Mode = {string.find(line, "W-Mode"),5} + xx.ExtCh = {string.find(line, "ExtCH"),6} + xx.WPS = {string.find(line, "WPS"),3} + xx.NT = {string.find(line, "NT"),2} + fidx = string.find(line, "OWETranIe") + if fidx then + xx.OWETranIe = {fidx,9} + end + end + + if #line>40 and is_mac_addr_present then + tmp = {} + tmp.channel = mtkwifi.__trim(string.sub(line, xx.Ch[1], xx.Ch[1]+xx.Ch[2])) + if xx.SSID_len then + -- Maximum xx.SSID[2] characters are supported in SSID + tmp.ssid_len = tonumber(mtkwifi.__trim(string.sub(line, xx.SSID_len[1], xx.SSID_len[1]+xx.SSID_len[2]))) or xx.SSID[2] + if tmp.ssid_len > xx.SSID[2] or tmp.ssid_len < 0 then + tmp.ssid_len = xx.SSID[2] + tmp.ssid = string.sub(line, xx.SSID[1], xx.SSID[1]+tmp.ssid_len-1) + else + tmp.ssid = string.sub(line, xx.SSID[1], xx.BSSID[1]-1) + if string.find(tmp.ssid, "0x") == nil then + tmp.ssid = string.sub(line, xx.SSID[1], xx.SSID[1]+tmp.ssid_len-1) + end + end + else + tmp.ssid = mtkwifi.__trim(string.sub(line, xx.SSID[1], xx.SSID[1]+xx.SSID[2])) + tmp.ssid_len = tmp.ssid:len() + end + tmp.bssid = string.upper(mtkwifi.__trim(string.sub(line, xx.BSSID[1], xx.BSSID[1]+xx.BSSID[2]))) + tmp.security = mtkwifi.__trim(string.sub(line, xx.Security[1], xx.Security[1]+xx.Security[2])) + tmp.authmode = mtkwifi.__trim(string.split(tmp.security, "/")[1]) + tmp.encrypttype = mtkwifi.__trim(string.split(tmp.security, "/")[2] or "NONE") + tmp.rssi = mtkwifi.__trim(string.sub(line, xx.Signal[1], xx.Signal[1]+xx.Signal[2])) + tmp.extch = mtkwifi.__trim(string.sub(line, xx.ExtCh[1], xx.ExtCh[1]+xx.ExtCh[2])) + tmp.mode = mtkwifi.__trim(string.sub(line, xx.Mode[1], xx.Mode[1]+xx.Mode[2])) + tmp.wps = mtkwifi.__trim(string.sub(line, xx.WPS[1], xx.WPS[1]+xx.WPS[2])) + tmp.nt = mtkwifi.__trim(string.sub(line, xx.NT[1], xx.NT[1]+xx.NT[2])) + if xx.OWETranIe then + tmp.OWETranIe = mtkwifi.__trim(string.sub(line, xx.OWETranIe[1], xx.OWETranIe[1]+xx.OWETranIe[2])) + end + table.insert(ap_list, tmp) + cur_index = tonumber(line:match("^%d+")) + if cur_index == total_index - 1 then + break; + end + next_line_index = cur_index and cur_index + 1 or next_line_index + end + end + if cur_index and cur_index == next_line_index - 1 then + --scan_result = mtkwifi.read_pipe("iwpriv "..vifname.." get_site_survey "..next_line_index) + if next_line_index == total_index - 1 then + scan_result = nil + else + op = c_scanResult(vifname, next_line_index) + scan_result = op["scanresult"] + end + else + scan_result = nil + end + + if not scan_result or not string.match(scan_result, "%s+%x%x:%x%x:%x%x:%x%x:%x%x:%x%x%s+") then + break + end + end + + return ap_list +end + +function mtkwifi.__any_wsc_enabled(wsc_conf_mode) + if (wsc_conf_mode == "") then + return 0; + end + if (wsc_conf_mode == "7") then + return 1; + end + if (wsc_conf_mode == "4") then + return 1; + end + if (wsc_conf_mode == "2") then + return 1; + end + if (wsc_conf_mode == "1") then + return 1; + end + return 0; +end + +function mtkwifi.__restart_if_wps(devname, ifname, cfgs) + local devs = mtkwifi.get_all_devs() + local ssid_index = devs[devname]["vifs"][ifname].vifidx + local wsc_conf_mode = "" + + wsc_conf_mode=mtkwifi.token_get(cfgs["WscConfMode"], ssid_index, "") + + os.execute("iwpriv "..ifname.." set WscConfMode=0") + debug_write("iwpriv "..ifname.." set WscConfMode=0") + os.execute("route delete 239.255.255.250") + debug_write("route delete 239.255.255.250") + if(mtkwifi.__any_wsc_enabled(wsc_conf_mode)) then + os.execute("iwpriv "..ifname.." set WscConfMode=7") + debug_write("iwpriv "..ifname.." set WscConfMode=7") + os.execute("route add -host 239.255.255.250 dev br0") + debug_write("route add -host 239.255.255.250 dev br0") + end + + return cfgs +end + +function mtkwifi.restart_8021x(devname, devices) + local l1dat, l1 = mtkwifi.__get_l1dat() + local dridx = l1dat and l1.DEV_RINDEX + + local devs = devices or mtkwifi.get_all_devs() + local dev = devs[devname] + local main_ifname = l1dat and l1dat[dridx][devname].main_ifname or dbdc_prefix[mainidx][subidx].."0" + local prefix = l1dat and l1dat[dridx][devname].ext_ifname or dbdc_prefix[mainidx][subidx] + + local ps_cmd = "ps | grep -v grep | grep rt2860apd | grep "..main_ifname.." | awk '{print $1}'" + local pid_cmd = "cat /var/run/rt2860apd_"..devs[devname].vifs[1].vifname..".pid" + local apd_pid = mtkwifi.read_pipe(pid_cmd) or mtkwifi.read_pipe(ps_cmd) + if tonumber(apd_pid) then + os.execute("kill "..apd_pid) + end + + local cfgs = mtkwifi.load_profile(devs[devname].profile) + local auth_mode = cfgs['AuthMode'] + local ieee8021x = cfgs['IEEE8021X'] + local pat_auth_mode = {"WPA$", "WPA;", "WPA2$", "WPA2;", "WPA1WPA2$", "WPA1WPA2;"} + local pat_ieee8021x = {"1$", "1;"} + local apd_en = false + + for _, pat in ipairs(pat_auth_mode) do + if string.find(auth_mode, pat) then + apd_en = true + end + end + + for _, pat in ipairs(pat_ieee8021x) do + if string.find(ieee8021x, pat) then + apd_en = true + end + end + + if not apd_en then + return + end + if prefix == "ra" then + mtkwifi.__fork_exec("rt2860apd -i "..main_ifname.." -p "..prefix) + elseif prefix == "rae" then + mtkwifi.__fork_exec("rtwifi3apd -i "..main_ifname.." -p "..prefix) + elseif prefix == "rai" then + mtkwifi.__fork_exec("rtinicapd -i "..main_ifname.." -p "..prefix) + elseif prefix == "rax" or prefix == "ray" or prefix == "raz" then + mtkwifi.__fork_exec("rt2860apd_x -i "..main_ifname.." -p "..prefix) + end +end + +function mtkwifi.dat2uci(datfile, ucifile) + local shuci = require("shuci") + local cfgs = mtkwifi.load_profile(datfile) + + local uci = {} + + uci["wifi-device"]={} + uci["wifi-device"][".name"] = device + uci["wifi-device"]["type"] = device + uci["wifi-device"]["vendor"] = "ralink" + uci["wifi-device"]["iface"] = {} + + local i = 1 -- index of wifi-iface + + uci["iface"] = {} + while i <= tonumber(cfgs.BssidNum) do + uci["iface"][i] = {} + local iface = uci["iface"][i] + iface["ssid"] = cfgs["SSID"..(i)] + iface["mode"] = "ap" + iface["network"] = "lan" + iface["ifname"] = "ra0" + iface[".name"] = device.."."..iface["ifname"] + + i=i+1 + end + + shuci.encode(uci, ucifile) +end + +function mtkwifi.uci2dat(ucifile, devname, datfile) + local shuci = require("shuci") + local uci = shuci.decode(ucifile) + local cfgs = mtkwifi.load_profile(datfile) or {} + + if not ucifile or not devname then return end + + for _,dev in ipairs(uci["wifi-device"][devname]) do + for k,v in pairs(dev) do + if string.byte(k) ~= string.byte(".") + and string.byte(k) ~= string.byte("_") then + cfgs.k = v + end + end + end + if datfile then + save_profile(cfgs, datfile) + end +end + +function mtkwifi.get_referer_url() + local to_url + local script_name = luci.http.getenv('SCRIPT_NAME') + local http_referer = luci.http.getenv('HTTP_REFERER') + if script_name and http_referer then + local fIdx = http_referer:find(script_name,1,true) + if fIdx then + to_url = http_referer:sub(fIdx) + end + end + if not to_url or to_url == "" then + to_url = luci.dispatcher.build_url("admin", "mtk", "wifi") + end + return to_url +end + +return mtkwifi diff --git a/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/shuci.lua b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/shuci.lua new file mode 100644 index 0000000000..87de6a2ee6 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/usr/lib/lua/shuci.lua @@ -0,0 +1,130 @@ +#!/usr/bin/env lua + +--[[ + * A pure lua library to translate between: + * lua table <--> uci config + * + * For UCI: http://wiki.openwrt.org/doc/techref/uci + * http://wiki.openwrt.org/doc/uci + * + * Copyright (C) 2015 Hua Shao + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. +]] + + +local shuci = {} + +function shuci.decode(path) + function file_exists(name) + local f=io.open(name,"r") + if f~=nil then io.close(f) return true else return false end + end + local function linebreaker(str) + local i,_ = string.find(str, "([^%s])") + if not i then return nil end + if string.find(str, "config%s+%w+") then + local i,j,k,v = string.find(str, "config%s+([%w-_]+)%s*['\"]*([^%s\'\"]*)") + return "section", k, v + elseif string.find(str, "option%s+%w+") then + local i,j,k,v = string.find(str, "option%s+([%w-_]+)%s*['\"]([^'\"]+)['\"]") + if not k or not v then + i,j,k,v = string.find(str, "option%s+([%w-_]+)%s*['\"]*([^%s\'\"]*)") + end + return "option", k, v + elseif string.find(str, "list%s+%w+") then + local i,j,k,v = string.find(str, "list%s+([%w-_]+)%s*['\"]([^'\"]+)['\"]") + if not k or not v then + i,j,k,v = string.find(str, "list%s+([%w-_]+)%s*['\"]*([^%s\'\"]*)") + end + return "list", k, v + end + end + + if not file_exists(path) then + return + end + + local _sect_ = nil + local t = {} + for line in io.lines(path) do + local _type, _name, _value = linebreaker(line) + if _type == "section" then + if not t[_name] then + t[_name] = {} + end + t[_name][#t[_name]+1] = {} + _sect_ = t[_name][#t[_name]] + if _value then + _sect_[".name"] = _value + end + end + if _type == "option" then + if _name and _value then + _sect_[_name] = _value + end + end + if _type == "list" and _name and _value then + local idx + if not _sect_[_name] then + _sect_[_name] = {} + _sect_[_name][1] = _value + else + idx = #_sect_[_name] + _sect_[_name][idx+1] = _value + end + end + end + + return t +end + + +function shuci.encode(t, path) + local dump = io.write + if path then + local fp = io.open(path, "w") + dump = function(str) fp:write(str) end + end + for stype,ss in pairs(t) do + if #ss > 0 then + for _,s in ipairs(ss) do + dump(string.format("config\t%s\t'%s'\n", stype, s[".name"] or "")) + for k,v in pairs(s) do + if type(v) == "table" then + for _,vv in ipairs(v) do + dump(string.format("\tlist\t%s\t'%s'\n",k,vv)) + end + elseif type(v) == "string" and k ~= ".name" then + dump(string.format("\toption\t%s\t'%s'\n",k,v)) + elseif type(v) == "number" and k ~= ".name" then + dump(string.format("\toption\t%s\t'%s'\n",k,tonumber(v))) + end + end + dump("\n") + end + else + dump(string.format("config\t%s\t'%s'\n", stype, ss[".name"] or "")) + for k,v in pairs(ss) do + if type(v) == "table" then + for _,vv in ipairs(v) do + dump(string.format("\tlist\t%s\t'%s'\n",k,vv)) + end + elseif type(v) == "string" and k ~= ".name" then + dump(string.format("\toption\t%s\t'%s'\n",k,v)) + elseif type(v) == "number" and k ~= ".name" then + dump(string.format("\toption\t%s\t'%s'\n",k,tonumber(v))) + end + end + end + end +end + +return shuci diff --git a/package/mtk/applications/luci-app-mtk/root/www/luci-static/resources/monCon.js b/package/mtk/applications/luci-app-mtk/root/www/luci-static/resources/monCon.js new file mode 100644 index 0000000000..bec2845bcd --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/root/www/luci-static/resources/monCon.js @@ -0,0 +1,28 @@ + +MonCon = function() +{ + + this.conOk = function() + { + window.setTimeout(MonCon.ping, 5000); + } + + this.ping = function() + { + var img = document.createElement('img'); + img.onload = this.conOk; + img.onerror = this.conErr; + img.src = '/luci-static/resources/icons/loading.gif?' + Math.random(); + } + + this.conErr = function() + { + alert('Device unreachable!'); + window.location.reload(true); + } + +} +MonCon.ping = function() +{ + (new MonCon()).ping(); +} diff --git a/package/mtk/applications/luci-app-mtk/src/Makefile b/package/mtk/applications/luci-app-mtk/src/Makefile new file mode 100644 index 0000000000..69e5ed735c --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/src/Makefile @@ -0,0 +1,24 @@ +OBJ_IOCTL = ioctl_helper.o +CFLAGS += -I. +CFLAGS += -I$(ROOTDIR)/user/luci/lua-5.1.5/src +CFLAGS += -Wall -shared -fPIC +LUCI_APP_MTK_TARGET = ioctl_helper + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +all: $(LUCI_APP_MTK_TARGET) + +ioctl_helper: $(OBJ_IOCTL) + $(CC) -o $@.so $^ $(CFLAGS) + +compile: $(LUCI_APP_MTK_TARGET) + +install: compile + mkdir -p $(DESTDIR)/usr/lib/lua + cp -pR ioctl_helper.so $(DESTDIR)/usr/lib/lua/ + +clean: + rm -f *.o *.so + +romfs: diff --git a/package/mtk/applications/luci-app-mtk/src/ioctl_helper.c b/package/mtk/applications/luci-app-mtk/src/ioctl_helper.c new file mode 100644 index 0000000000..254ab00101 --- /dev/null +++ b/package/mtk/applications/luci-app-mtk/src/ioctl_helper.c @@ -0,0 +1,1199 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Always include this */ +#include /* Always include this */ +#include /* Always include this */ + +#define PACKED __attribute__ ((packed)) +#define USHORT unsigned short +#define UCHAR unsigned char +#define UCHAR unsigned char +typedef struct PACKED _WSC_CONFIGURED_VALUE { + USHORT WscConfigured; // 1 un-configured; 2 configured + UCHAR WscSsid[32 + 1]; + USHORT WscAuthMode; // mandatory, 0x01: open, 0x02: wpa-psk, 0x04: shared, 0x08:wpa, 0x10: wpa2, 0x + USHORT WscEncrypType; // 0x01: none, 0x02: wep, 0x04: tkip, 0x08: aes + UCHAR DefaultKeyIdx; + UCHAR WscWPAKey[64 + 1]; +}WSC_CONFIGURED_VALUE; + +typedef struct PACKED _NDIS80211SSID +{ + unsigned int SsidLength; // length of SSID field below, in bytes; + // this can be zero. + unsigned char Ssid[32]; // SSID information field +} NDIS80211SSID; + +// WSC configured credential +typedef struct _WSC_CREDENTIAL +{ + NDIS80211SSID SSID; // mandatory + USHORT AuthType; // mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa-psk2 + USHORT EncrType; // mandatory, 1: none, 2: wep, 4: tkip, 8: aes + UCHAR Key[64]; // mandatory, Maximum 64 byte + USHORT KeyLength; + UCHAR MacAddr[6]; // mandatory, AP MAC address + UCHAR KeyIndex; // optional, default is 1 + UCHAR Rsvd[3]; // Make alignment +} WSC_CREDENTIAL, *PWSC_CREDENTIAL; + +// WSC configured profiles +typedef struct _WSC_PROFILE +{ +#ifndef UINT +#define UINT unsigned int +#endif + UINT ProfileCnt; + UINT ApplyProfileIdx; // add by johnli, fix WPS test plan 5.1.1 + WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles +} WSC_PROFILE, *PWSC_PROFILE; + +typedef union _MACHTTRANSMIT_SETTING { + struct { + unsigned short MCS:6; // MCS + unsigned short rsv:1; + unsigned short BW:2; //channel bandwidth 20MHz or 40 MHz + unsigned short ShortGI:1; + unsigned short STBC:1; //SPACE + unsigned short eTxBF:1; + unsigned short iTxBF:1; + unsigned short MODE:3; // Use definition MODE_xxx. + } field; + unsigned short word; +} MACHTTRANSMIT_SETTING; + +typedef struct _RT_802_11_MAC_ENTRY { + unsigned char ApIdx; + unsigned char Addr[6]; + unsigned char Aid; + unsigned char Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE + unsigned char MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled + signed char AvgRssi0; + signed char AvgRssi1; + signed char AvgRssi2; + signed char AvgRssi3; + unsigned int ConnectedTime; + MACHTTRANSMIT_SETTING TxRate; + unsigned int LastRxRate; + short StreamSnr[3]; + short SoundingRespSnr[3]; +#if 0 + short TxPER; + short reserved; +#endif +} RT_802_11_MAC_ENTRY; + +#define MAX_NUMBER_OF_MAC 554 + +typedef struct _RT_802_11_MAC_TABLE { + unsigned long Num; + RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC]; //MAX_LEN_OF_MAC_TABLE = 32 +} RT_802_11_MAC_TABLE; + +#define IF_NAMESIZE 16 +#define SIOCIWFIRSTPRIV 0x8BE0 +#define RTPRIV_IOCTL_WSC_PROFILE (SIOCIWFIRSTPRIV + 0x12) +#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) +#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B +#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750 +#define RT_OID_APCLI_WSC_PIN_CODE 0x074A + +#define RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT (SIOCIWFIRSTPRIV + 0x1F) + +/* for WPS --YY */ +#define RT_OID_SYNC_RT61 0x0D010750 +#define RT_OID_WSC_QUERY_STATUS ((RT_OID_SYNC_RT61 + 0x01) & 0xffff) +#define RT_OID_WSC_PIN_CODE ((RT_OID_SYNC_RT61 + 0x02) & 0xffff) +#if defined (RT2860_APCLI_SUPPORT) || defined (RTDEV_APCLI_SUPPORT) +#define RT_OID_APCLI_WSC_PIN_CODE 0x074A +#endif +#define OID_GET_WMODE 0x099E +#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D) + +int getCurrentWscProfile(lua_State *L); +int getApPin(lua_State *L); +int get_macaddr(lua_State *L); +int apcli_get_wps_status(lua_State *L); +int apcli_wps_get_pincode(lua_State *L); +int convert_string_display(lua_State *L); +int StaInfo(lua_State *L); +int getWMOde(lua_State *L); +int scanResult(lua_State *L); + +int luaopen_ioctl_helper(lua_State *L) +{ + lua_register(L,"c_getCurrentWscProfile",getCurrentWscProfile); + lua_register(L,"c_getApPin",getApPin); + lua_register(L,"c_get_macaddr",get_macaddr); + lua_register(L,"c_apcli_get_wps_status",apcli_get_wps_status); + lua_register(L,"c_apcli_wps_get_pincode",apcli_wps_get_pincode); + lua_register(L,"c_convert_string_display",convert_string_display); + lua_register(L,"c_StaInfo",StaInfo); + lua_register(L,"c_getWMode",getWMOde); + lua_register(L,"c_scanResult",scanResult); + return 0; +} + +int scanResult(lua_State *L) +{ + int socket_id; + const char *interface = luaL_checkstring(L, 1); + const char *tmp_idx = luaL_checkstring(L, 2); + struct iwreq wrq; + char *data = NULL; + unsigned int data_len = 5000; + + if((data = (char *)malloc(data_len)) == NULL){ + fprintf(stderr, "%s: malloc failed\n", __func__); + return -1; + } + memset(data, 0, data_len); + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + free(data); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + snprintf(data, data_len, "%s", tmp_idx); + wrq.u.data.length = data_len; + wrq.u.data.pointer = (caddr_t)data; + wrq.u.data.flags = 0; + if (ioctl(socket_id, RTPRIV_IOCTL_GSITESURVEY, &wrq) < 0) { + fprintf(stderr, "ioctl -> RTPRIV_IOCTL_GSITESURVEY Fail !"); + close(socket_id); + free(data); + return -1; + } + lua_newtable(L); + lua_pushstring(L, "scanresult"); /* push key */ + lua_pushstring(L, data); /* push value */ + lua_settable(L, -3); + close(socket_id); + free(data); + + return 1; +} + +static unsigned int get_ap_pin(const char *interface) +{ + int socket_id; + struct iwreq wrq; + unsigned int data = 0; + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof(data); + wrq.u.data.pointer = (caddr_t) &data; + wrq.u.data.flags = RT_OID_WSC_PIN_CODE; + if( ioctl(socket_id, RT_PRIV_IOCTL, &wrq) == -1) + fprintf(stderr, "%s: ioctl fail\n", __func__); + close(socket_id); + + return data; +} + +static unsigned int get_w_mode(const char *interface) +{ + int socket_id; + struct iwreq wrq; + unsigned char data = 0; + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof(data); + wrq.u.data.pointer = (caddr_t) &data; + wrq.u.data.flags = OID_GET_WMODE; + if( ioctl(socket_id, RT_PRIV_IOCTL, &wrq) == -1) + fprintf(stderr, "%s: ioctl fail\n", __func__); + close(socket_id); + + return data; +} + +void getWPSAuthMode(WSC_CONFIGURED_VALUE *result, char *ret_str, size_t size) +{ + if(result->WscAuthMode & 0x1) + strncat(ret_str, "Open", size - 1); + if(result->WscAuthMode & 0x2) + strncat(ret_str, "WPA-PSK", size - 1); + if(result->WscAuthMode & 0x4) + strncat(ret_str, "Shared", size - 1); + if(result->WscAuthMode & 0x8) + strncat(ret_str, "WPA", size - 1); + if(result->WscAuthMode & 0x10) + strncat(ret_str, "WPA2", size - 1); + if(result->WscAuthMode & 0x20) + strncat(ret_str, "WPA2-PSK", size - 1); +} + +void getWPSEncrypType(WSC_CONFIGURED_VALUE *result, char *ret_str, size_t size) +{ + if(result->WscEncrypType & 0x1) + strncat(ret_str, "None", size - 1); + if(result->WscEncrypType & 0x2) + strncat(ret_str, "WEP", size - 1); + if(result->WscEncrypType & 0x4) + strncat(ret_str, "TKIP", size - 1); + if(result->WscEncrypType & 0x8) + strncat(ret_str, "AES", size - 1); +} + +/* + * * these definitions are from rt2860v2 driver include/wsc.h + * */ +char *getWscStatusStr(int status) +{ + switch(status){ + case 0: + return "Not used"; + case 1: + return "Idle"; + case 2: + return "WSC Fail(Ignore this if Intel/Marvell registrar used)"; + case 3: + return "Start WSC Process"; + case 4: + return "Received EAPOL-Start"; + case 5: + return "Sending EAP-Req(ID)"; + case 6: + return "Receive EAP-Rsp(ID)"; + case 7: + return "Receive EAP-Req with wrong WSC SMI Vendor Id"; + case 8: + return "Receive EAPReq with wrong WSC Vendor Type"; + case 9: + return "Sending EAP-Req(WSC_START)"; + case 10: + return "Send M1"; + case 11: + return "Received M1"; + case 12: + return "Send M2"; + case 13: + return "Received M2"; + case 14: + return "Received M2D"; + case 15: + return "Send M3"; + case 16: + return "Received M3"; + case 17: + return "Send M4"; + case 18: + return "Received M4"; + case 19: + return "Send M5"; + case 20: + return "Received M5"; + case 21: + return "Send M6"; + case 22: + return "Received M6"; + case 23: + return "Send M7"; + case 24: + return "Received M7"; + case 25: + return "Send M8"; + case 26: + return "Received M8"; + case 27: + return "Processing EAP Response (ACK)"; + case 28: + return "Processing EAP Request (Done)"; + case 29: + return "Processing EAP Response (Done)"; + case 30: + return "Sending EAP-Fail"; + case 31: + return "WSC_ERROR_HASH_FAIL"; + case 32: + return "WSC_ERROR_HMAC_FAIL"; + case 33: + return "WSC_ERROR_DEV_PWD_AUTH_FAIL"; + case 34: + return "Configured"; + case 35: + return "SCAN AP"; + case 36: + return "EAPOL START SENT"; + case 37: + return "WSC_EAP_RSP_DONE_SENT"; + case 38: + return "WAIT PINCODE"; + case 39: + return "WSC_START_ASSOC"; + case 0x101: + return "PBC:TOO MANY AP"; + case 0x102: + return "PBC:NO AP"; + case 0x103: + return "EAP_FAIL_RECEIVED"; + case 0x104: + return "EAP_NONCE_MISMATCH"; + case 0x105: + return "EAP_INVALID_DATA"; + case 0x106: + return "PASSWORD_MISMATCH"; + case 0x107: + return "EAP_REQ_WRONG_SMI"; + case 0x108: + return "EAP_REQ_WRONG_VENDOR_TYPE"; + case 0x109: + return "PBC_SESSION_OVERLAP"; + default: + return "Unknown"; + } +} + +int getWscStatus(const char *interface) +{ + int socket_id; + struct iwreq wrq; + int data = 0; + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof(data); + wrq.u.data.pointer = (caddr_t) &data; + wrq.u.data.flags = RT_OID_WSC_QUERY_STATUS; + if( ioctl(socket_id, RT_PRIV_IOCTL, &wrq) == -1) + { + fprintf(stderr, "%s: ioctl fail\n", __func__); + } + close(socket_id); + + + return data; +} + +int get_macaddr(lua_State *L) +{ + const char *ifname = luaL_checkstring(L, 1); + struct ifreq ifr; + char *ptr; + int skfd; + static char if_hw[18] = {0}; + + if((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + //printf(stderr, "%s: open socket error\n", __func__); + return skfd; + } + snprintf(ifr.ifr_name, IF_NAMESIZE, "%s", ifname); + if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) { + close(skfd); + fprintf(stderr, "%s: ioctl fail\n", __func__); + return -1; + } + + ptr = (char *)&ifr.ifr_addr.sa_data; + sprintf(if_hw, "%02X:%02X:%02X:%02X:%02X:%02X", + (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), + (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)); + close(skfd); + + lua_newtable(L); + lua_pushstring(L, "macaddr"); /* push key */ + lua_pushstring(L, if_hw); /* push value */ + lua_settable(L, -3); + /* Returning one table which is already on top of Lua stack. */ + return 1; +} + +int getApPin(lua_State *L) +{ + char new_pin[9]; + const char *interface = luaL_checkstring(L, 1); + snprintf(new_pin, sizeof(new_pin), "%08d", get_ap_pin(interface)); + //printf("{\"genpincode\":\"%s\"}", new_pin); + lua_newtable(L); + lua_pushstring(L, "genpincode"); /* push key */ + lua_pushstring(L, new_pin); /* push value */ + lua_settable(L, -3); + /* Returning one table which is already on top of Lua stack. */ + return 1; +} + +int getWMOde(lua_State *L) +{ + char w_mode[5]; + const char *interface = luaL_checkstring(L, 1); + snprintf(w_mode, sizeof(w_mode), "%d", get_w_mode(interface)); + lua_newtable(L); + lua_pushstring(L, "getwmode"); /* push key */ + lua_pushstring(L, w_mode); /* push value */ + lua_settable(L, -3); + /* Returning one table which is already on top of Lua stack. */ + return 1; +} + +int getCurrentWscProfile(lua_State *L) +{ + int status, WscResult = 0; + char tmp_str[128]; + int socket_id; + struct iwreq wrq; + const char *interface = luaL_checkstring(L, 1); + WSC_CONFIGURED_VALUE *data; + if((data = (WSC_CONFIGURED_VALUE *)malloc(sizeof(WSC_CONFIGURED_VALUE))) == NULL){ + fprintf(stderr, "%s: malloc failed\n", __func__); + return -1; + } + + if ((socket_id = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ + fprintf(stderr, "%s: Unable to open a socket\n", __func__); + free(data); + return -1; + } + snprintf((char *)data, sizeof(WSC_CONFIGURED_VALUE), "%s", "get_wsc_profile"); + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof( WSC_CONFIGURED_VALUE); + wrq.u.data.pointer = data; + wrq.u.data.flags = 0; + if (ioctl(socket_id, RTPRIV_IOCTL_WSC_PROFILE, &wrq) < 0) { + fprintf(stderr, "ioctl -> RTPRIV_IOCTL_WSC_PROFILE Fail !"); + close(socket_id); + free(data); + return -1; + } + + lua_newtable(L); + lua_pushstring(L, "Conf"); /* push key */ + lua_pushnumber(L, data->WscConfigured); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "SSID"); /* push key */ + lua_pushstring(L, (char *)data->WscSsid); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "DefKey"); /* push key */ + lua_pushnumber(L, data->DefaultKeyIdx); /* push value */ + lua_settable(L, -3); + + //WPSAuthMode + tmp_str[0] = '\0'; + getWPSAuthMode(data, tmp_str, 128); + lua_pushstring(L, "AuthMode"); /* push key */ + lua_pushstring(L, tmp_str); /* push value */ + lua_settable(L, -3); + + //EncrypType + tmp_str[0] = '\0'; + getWPSEncrypType(data, tmp_str, 128); + lua_pushstring(L, "EncType"); /* push key */ + lua_pushstring(L, tmp_str); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "WscWPAKey"); /* push key */ + lua_pushstring(L, (char *)data->WscWPAKey); /* push value */ + lua_settable(L, -3); + + //7. WSC Status + status = getWscStatus(interface); + lua_pushstring(L, "WscStatus"); /* push key */ + lua_pushstring(L, getWscStatusStr(status)); /* push value */ + lua_settable(L, -3); + + //8. WSC Result + if (status == 0x2 || status == 0x109) + WscResult = -1; + else if (status == 34) + WscResult = 1; + + lua_pushstring(L, "WscResult"); /* push key */ + lua_pushnumber(L, WscResult); /* push value */ + lua_settable(L, -3); + + close(socket_id); + /* Returning one table which is already on top of Lua stack. */ + return 1; +} + +int getWscProfile(const char *interface, WSC_PROFILE *wsc_profile) +{ + int socket_id; + struct iwreq wrq; + + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof(WSC_PROFILE); + wrq.u.data.pointer = (caddr_t) wsc_profile; + wrq.u.data.flags = RT_OID_802_11_WSC_QUERY_PROFILE; + if( ioctl(socket_id, RT_PRIV_IOCTL, &wrq) == -1){ + fprintf(stderr, "ioctl error\n"); + close(socket_id); + return -1; + } + close(socket_id); + + return 0; +} + +int OidQueryInformation(unsigned long OidQueryCode, int socket_id, const char *DeviceName, void *ptr, unsigned long PtrLength) +{ + struct iwreq wrq; + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", DeviceName); + wrq.u.data.length = PtrLength; + wrq.u.data.pointer = (caddr_t) ptr; + wrq.u.data.flags = OidQueryCode; + + return (ioctl(socket_id, RT_PRIV_IOCTL, &wrq)); +} + +static unsigned int apcli_get_pincode_ioctl(const char *interface) +{ + int socket_id; + struct iwreq wrq; + unsigned int data = 0; + socket_id = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_id < 0) { + perror("socket() failed"); + return socket_id; + } + + snprintf(wrq.ifr_name, sizeof(wrq.ifr_name), "%s", interface); + wrq.u.data.length = sizeof(data); + wrq.u.data.pointer = (caddr_t) &data; + wrq.u.data.flags = RT_OID_APCLI_WSC_PIN_CODE; + if( ioctl(socket_id, RT_PRIV_IOCTL, &wrq) == -1) + fprintf(stderr, "RT_PRIV_IOCTL ioctl error"); + close(socket_id); + + return data; +} + +int apcli_wps_get_pincode(lua_State *L) +{ + char new_pin[9]; + + const char *interface = luaL_checkstring(L, 1); + lua_newtable(L); + + snprintf(new_pin, sizeof(new_pin), "%08d", apcli_get_pincode_ioctl(interface)); + + lua_pushstring(L, "getpincode"); /* push key */ + lua_pushstring(L, new_pin); /* push value */ + lua_settable(L, -3); + + return 1; +} + +int port_secured(const char *ifname) +{ + int s; + unsigned int ConnectStatus = 0; + + if (ifname == NULL) + return -1; + + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + perror("socket() failed"); + return s; + } + + if (OidQueryInformation(OID_GEN_MEDIA_CONNECT_STATUS, s, ifname, &ConnectStatus, sizeof(ConnectStatus)) < 0) { + fprintf(stderr, "Query OID_GEN_MEDIA_CONNECT_STATUS error!"); + close(s); + return -1; + } + close(s); + if (ConnectStatus == 1) + return 1; + else + return 0; +} + +int convert_string_display(lua_State *L) +{ +#define BUF_SIZE 199 + int len, i; + char buffer[BUF_SIZE]; // 33(characters in SSID) * 6(maximum length of a HTML entity) = 198 + 1(null character) = 199 + char *pOut,*pBufLimit; + const char *str = luaL_checkstring(L, 1); + + memset(buffer,0,BUF_SIZE); + len = strlen(str); + pOut = &buffer[0]; + pBufLimit = &buffer[BUF_SIZE - 1]; + for (i = 0; i < len && (pBufLimit - pOut) >=7; i++) { // 6(maximum length of a HTML entity) + 1(null character) = 7 + switch (str[i]) { + case 38: + strncpy(pOut, "&", BUF_SIZE - 1); // '&' + pOut += 5; + break; + + case 60: + strncpy(pOut, "<", BUF_SIZE - 1); // '<' + pOut += 4; + break; + + case 62: + strncpy(pOut, ">", BUF_SIZE - 1); // '>' + pOut += 4; + break; + + case 34: + strncpy(pOut, """, BUF_SIZE - 1); // '"' + pOut += 5; + break; + + case 39: + strncpy(pOut, "'", BUF_SIZE - 1); // ''' + pOut += 5; + break; + case 32: + strncpy(pOut, " ", BUF_SIZE - 1); // ' ' + pOut += 6; + break; + + default: + if ((str[i]>=0) && (str[i]<=31)) { + //Device Control Characters + sprintf(pOut, "&#%02d;", str[i]); + pOut += 5; + } else if ((str[i]==39) || (str[i]==47) || (str[i]==59) || (str[i]==92)) { + // ' / ; (backslash) + sprintf(pOut, "&#%02d;", str[i]); + pOut += 5; + } else if (str[i]>=127) { + //Device Control Characters + sprintf(pOut, "&#%03d;", str[i]); + pOut += 6; + } else { + *pOut = str[i]; + pOut++; + } + break; + } + } + *pOut = '\0'; + lua_newtable(L); + lua_pushstring(L, "output"); /* push key */ + lua_pushstring(L, buffer); /* push value */ + lua_settable(L, -3); + return 1; +} + +int StaInfo(lua_State *L) +{ + int i, s; + struct iwreq iwr; + RT_802_11_MAC_TABLE *table; + char tmpBuff[128]; + char *phyMode[12] = {"CCK", "OFDM", "MM", "GF", "VHT", "HE", + "HE5G", "HE2G", "HE_SU", "HE_EXT_SU", "HE_TRIG", "HE_MU"}; + const char *interface = luaL_checkstring(L, 1); + + table = (RT_802_11_MAC_TABLE *)calloc(1, sizeof(RT_802_11_MAC_TABLE)); + if (!table) + return -ENOMEM; + + s = socket(AF_INET, SOCK_DGRAM, 0); + + snprintf(iwr.ifr_name, IFNAMSIZ, "%s", interface); + + iwr.u.data.pointer = (caddr_t) &table; + + if (s < 0) { + free(table); + return 0; + } + + if (ioctl(s, RTPRIV_IOCTL_GET_MAC_TABLE_STRUCT, &iwr) < 0) { + free(table); + close(s); + return 0; + } + + close(s); + + + /* Creates parent table of size table.Num array elements: */ + lua_createtable(L, table->Num, 0); + + for (i = 0; i < table->Num; i++) { + + lua_pushnumber(L, i); + + RT_802_11_MAC_ENTRY *pe = &(table->Entry[i]); + unsigned int lastRxRate = pe->LastRxRate; + unsigned int mcs = pe->LastRxRate & 0x7F; + unsigned int vht_nss; + unsigned int vht_mcs = pe->TxRate.field.MCS; + unsigned int vht_nss_r; + unsigned int vht_mcs_r = pe->LastRxRate & 0x3F; + int hr, min, sec; + + hr = pe->ConnectedTime/3600; + min = (pe->ConnectedTime % 3600)/60; + sec = pe->ConnectedTime - hr*3600 - min*60; + + /*Creates first child table of size 28 non-array elements: */ + lua_createtable(L, 0, 28); + + // MAC Address + snprintf(tmpBuff, sizeof(tmpBuff), "%02X:%02X:%02X:%02X:%02X:%02X", pe->Addr[0], pe->Addr[1], pe->Addr[2], pe->Addr[3], + pe->Addr[4], pe->Addr[5]); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "MacAddr"); + + // AID, Power Save mode, MIMO Power Save + snprintf(tmpBuff, sizeof(tmpBuff), "%d", pe->Aid); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Aid"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%d", pe->Psm); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Psm"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%d", pe->MimoPs); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "MimoPs"); + + // TX Rate + if (pe->TxRate.field.MODE == 4){ + vht_nss = ((vht_mcs & (0x3 << 4)) >> 4) + 1; + vht_mcs = vht_mcs & 0xF; + snprintf(tmpBuff, sizeof(tmpBuff), "%dS-M%d/", vht_nss, vht_mcs); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Mcs"); + } else{ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", pe->TxRate.field.MCS); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Mcs"); + } + + if (pe->TxRate.field.BW == 0){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 20); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Bw"); + } else if (pe->TxRate.field.BW == 1){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 40); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Bw"); + } else if (pe->TxRate.field.BW == 2){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 80); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Bw"); + } + + snprintf(tmpBuff, sizeof(tmpBuff), "%c", pe->TxRate.field.ShortGI? 'S': 'L'); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Gi"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%s", phyMode[pe->TxRate.field.MODE]); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "PhyMode"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%s", pe->TxRate.field.STBC? "STBC": " "); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Stbc"); + + // TxBF configuration + snprintf(tmpBuff, sizeof(tmpBuff), "%c", pe->TxRate.field.iTxBF? 'I': '-'); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "iTxBF"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%c", pe->TxRate.field.eTxBF? 'E': '-'); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "eTxBF"); + + // RSSI + snprintf(tmpBuff, sizeof(tmpBuff), "%d", (int)(pe->AvgRssi0)); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "AvgRssi0"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%d", (int)(pe->AvgRssi1)); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "AvgRssi1"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%d", (int)(pe->AvgRssi2)); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "AvgRssi2"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%d", (int)(pe->AvgRssi3)); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "AvgRssi3"); + + // Per Stream SNR + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->StreamSnr[0]*0.25); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "StreamSnr0"); + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->StreamSnr[1]*0.25); //mcs>7? pe->StreamSnr[1]*0.25: 0.0); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "StreamSnr1"); + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->StreamSnr[2]*0.25); //mcs>15? pe->StreamSnr[2]*0.25: 0.0); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "StreamSnr2"); + + // Sounding Response SNR + if (pe->TxRate.field.eTxBF) { + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->SoundingRespSnr[0]*0.25); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "SoundingRespSnr0"); + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->SoundingRespSnr[1]*0.25); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "SoundingRespSnr1"); + snprintf(tmpBuff, sizeof(tmpBuff), "%0.1f", pe->SoundingRespSnr[2]*0.25); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "SoundingRespSnr2"); + } + + // Last RX Rate + if (((lastRxRate>>13) & 0x7) == 4){ + vht_nss_r = ((vht_mcs_r & (0x3 << 4)) >> 4) + 1; + vht_mcs_r = vht_mcs_r & 0xF; + snprintf(tmpBuff, sizeof(tmpBuff), "%dS-M%d", vht_nss_r, vht_mcs_r); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastMcs"); + } else{ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", mcs); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastMcs"); + } + + if (((lastRxRate>>7) & 0x3) == 0){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 20); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastBw"); + } else if (((lastRxRate>>7) & 0x3) == 1){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 40); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastBw"); + } else if (((lastRxRate>>7) & 0x3) == 2){ + snprintf(tmpBuff, sizeof(tmpBuff), "%d", 80); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastBw"); + } + + snprintf(tmpBuff, sizeof(tmpBuff), "%c", ((lastRxRate>>8) & 0x1)? 'S': 'L'); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastGi"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%s", phyMode[(lastRxRate>>13) & 0x7]); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastPhyMode"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%s", ((lastRxRate>>9) & 0x3)? "STBC": " "); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "LastStbc"); + + // Connect time + snprintf(tmpBuff, sizeof(tmpBuff), "%02d", hr); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Hr"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%02d", min); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Min"); + + snprintf(tmpBuff, sizeof(tmpBuff), "%02d", sec); + lua_pushstring(L, tmpBuff); + lua_setfield(L, -2, "Sec"); + + lua_settable(L, -3); + } + free(table); + return 1; +} + +int apcli_get_wps_status(lua_State *L) +{ + int status; + unsigned int profile_idx = 0; + char tmp_str[68] = {0}; + const char *interface = luaL_checkstring(L, 1); + lua_newtable(L); + + //7. WSC Status + status = getWscStatus(interface); + + //8. WSC Result + if (status == 0x2 || status == 0x109) { + lua_pushstring(L, "wps_result"); /* push key */ + lua_pushstring(L, "Failed"); /* push value */ + lua_settable(L, -3); + } else if (status == 34) { + lua_pushstring(L, "wps_result"); /* push key */ + lua_pushstring(L, "Success"); /* push value */ + lua_settable(L, -3); + } else { + lua_pushstring(L, "wps_result"); /* push key */ + lua_pushstring(L, "Continuing"); /* push value */ + lua_settable(L, -3); + } + + //9. WSC Status Index + lua_pushstring(L, "wps_status_code"); /* push key */ + lua_pushnumber(L, status); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "wps_status"); /* push key */ + lua_pushstring(L, getWscStatusStr(status)); /* push value */ + lua_settable(L, -3); + + if (port_secured(interface) <= 0) { + lua_pushstring(L, "wps_port_secured"); /* push key */ + lua_pushstring(L, "NO"); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "apcli_get_wps_status"); /* push key */ + lua_pushstring(L, "OK"); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "Error"); /* push key */ + lua_pushstring(L, "Port is not secured"); /* push value */ + lua_settable(L, -3); + return 1; + } + + lua_pushstring(L, "wps_port_secured"); /* push key */ + lua_pushstring(L, "YES"); /* push value */ + lua_settable(L, -3); + + if (strstr(interface,"apcli") != NULL) { + WSC_PROFILE *wsc_profile; + + if ((wsc_profile = (WSC_PROFILE *)malloc(sizeof(WSC_PROFILE))) == NULL) { + lua_pushstring(L, "apcli_get_wps_status"); /* push key */ + lua_pushstring(L, "NG"); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "Error"); /* push key */ + lua_pushstring(L, "Interface name does not contain apcli"); /* push value */ + lua_settable(L, -3); + return 1; + } + + getWscProfile(interface, wsc_profile); + if (wsc_profile != NULL) { + lua_pushstring(L, "enr_profile_cnt"); /* push key */ + lua_pushnumber(L, wsc_profile->ProfileCnt); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "enr_profile_idx"); /* push key */ + lua_pushnumber(L, wsc_profile->ApplyProfileIdx); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "enr_SSID"); /* push key */ + lua_pushstring(L, (char *)wsc_profile->Profile[profile_idx].SSID.Ssid); /* push value */ + lua_settable(L, -3); + + profile_idx = wsc_profile->ApplyProfileIdx; + switch (wsc_profile->Profile[profile_idx].AuthType) { + case 0x0002: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPAPSK"); /* push value */ + lua_settable(L, -3); + break; + case 0x0004: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "SHARED"); /* push value */ + lua_settable(L, -3); + break; + case 0x0008: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPA"); /* push value */ + lua_settable(L, -3); + break; + case 0x0010: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPA2"); /* push value */ + lua_settable(L, -3); + break; + case 0x0020: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPA2PSK"); /* push value */ + lua_settable(L, -3); + break; + case 0x0022: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPAPSKWPA2PSK"); /* push value */ + lua_settable(L, -3); + break; + case 0x0001: + default: + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "OPEN"); /* push value */ + lua_settable(L, -3); + } + + switch (wsc_profile->Profile[profile_idx].EncrType) { + case 0x0002: + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "WEP"); /* push value */ + lua_settable(L, -3); + + if ((wsc_profile->Profile[profile_idx].KeyLength == 10) || + (wsc_profile->Profile[profile_idx].KeyLength == 26)) { + /* Key Entry Method == HEX */ + lua_pushstring(L, "enr_Key1Type"); /* push key */ + lua_pushstring(L, "0"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key2Type"); /* push key */ + lua_pushstring(L, "0"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key3Type"); /* push key */ + lua_pushstring(L, "0"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key4Type"); /* push key */ + lua_pushstring(L, "0"); /* push value */ + lua_settable(L, -3); + } else { + /* Key Entry Method == ASCII */ + lua_pushstring(L, "enr_Key1Type"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key2Type"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key3Type"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_Key4Type"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + } + if (wsc_profile->Profile[profile_idx].KeyIndex == 1) { + lua_pushstring(L, "enr_KeyStr"); /* push key */ + lua_pushstring(L, (char *)wsc_profile->Profile[profile_idx].Key); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + } else if (wsc_profile->Profile[profile_idx].KeyIndex == 2) { + lua_pushstring(L, "enr_KeyStr"); /* push key */ + lua_pushstring(L, (char *)wsc_profile->Profile[profile_idx].Key); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "2"); /* push value */ + lua_settable(L, -3); + } else if (wsc_profile->Profile[profile_idx].KeyIndex == 3) { + lua_pushstring(L, "enr_KeyStr"); /* push key */ + lua_pushstring(L, (char *)wsc_profile->Profile[profile_idx].Key); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "3"); /* push value */ + lua_settable(L, -3); + } else if (wsc_profile->Profile[profile_idx].KeyIndex == 4) { + lua_pushstring(L, "enr_KeyStr"); /* push key */ + lua_pushstring(L, (char *)wsc_profile->Profile[profile_idx].Key); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "4"); /* push value */ + lua_settable(L, -3); + } + break; + case 0x0004: + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "TKIP"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "2"); /* push value */ + lua_settable(L, -3); + + memset(tmp_str, 0, 65); + memcpy(tmp_str, wsc_profile->Profile[profile_idx].Key, wsc_profile->Profile[profile_idx].KeyLength); + + lua_pushstring(L, "enr_WPAPSK"); /* push key */ + lua_pushstring(L, tmp_str); /* push value */ + lua_settable(L, -3); + break; + case 0x0008: + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "AES"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "2"); /* push value */ + lua_settable(L, -3); + + memset(tmp_str, 0, 65); + memcpy(tmp_str, wsc_profile->Profile[profile_idx].Key, wsc_profile->Profile[profile_idx].KeyLength); + + lua_pushstring(L, "enr_WPAPSK"); /* push key */ + lua_pushstring(L, tmp_str); /* push value */ + lua_settable(L, -3); + break; + case 0x000C: + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "TKIPAES"); /* push value */ + lua_settable(L, -3); + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "2"); /* push value */ + lua_settable(L, -3); + + memset(tmp_str, 0, 65); + memcpy(tmp_str, wsc_profile->Profile[profile_idx].Key, wsc_profile->Profile[profile_idx].KeyLength); + + lua_pushstring(L, "enr_WPAPSK"); /* push key */ + lua_pushstring(L, tmp_str); /* push value */ + lua_settable(L, -3); + break; + case 0x0001: + default: + //printf("Default case"); + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "NONE"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_DefaultKeyID"); /* push key */ + lua_pushstring(L, "1"); /* push value */ + lua_settable(L, -3); + } + + if (wsc_profile->Profile[profile_idx].AuthType == 0x0002 && + wsc_profile->Profile[profile_idx].EncrType == 0x0004) { + lua_pushstring(L, "enr_AuthMode"); /* push key */ + lua_pushstring(L, "WPAPSKWPA2PSK"); /* push value */ + lua_settable(L, -3); + + lua_pushstring(L, "enr_EncrypType"); /* push key */ + lua_pushstring(L, "TKIPAES"); /* push value */ + lua_settable(L, -3); + } + } + + lua_pushstring(L, "apcli_get_wps_status"); /* push key */ + lua_pushstring(L, "OK"); /* push value */ + lua_settable(L, -3); + } + return 1; +} diff --git a/package/mtk/applications/mii_mgr/Makefile b/package/mtk/applications/mii_mgr/Makefile new file mode 100644 index 0000000000..166e3f5fc0 --- /dev/null +++ b/package/mtk/applications/mii_mgr/Makefile @@ -0,0 +1,36 @@ +# +# hua.shao@mediatek.com +# +# MTK Property Software. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mii_mgr +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/mii_mgr + SECTION:=MTK Properties + CATEGORY:=MTK Properties + TITLE:=mii_mgr/mii_mgr_cl45 + SUBMENU:=Applications +endef + +define Package/mii_mgr/description + An mdio r/w phy regs program. +endef + +define Package/mii_mgr/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mii_mgr $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mii_mgr $(1)/usr/sbin/mii_mgr_cl45 +endef + + +$(eval $(call BuildPackage,mii_mgr)) + diff --git a/package/mtk/applications/mii_mgr/src/Makefile b/package/mtk/applications/mii_mgr/src/Makefile new file mode 100644 index 0000000000..55d6a6ff87 --- /dev/null +++ b/package/mtk/applications/mii_mgr/src/Makefile @@ -0,0 +1,16 @@ +EXEC = mii_mgr + +CFLAGS += -Wall -Werror + +all: $(EXEC) + +mii_mgr: mii_mgr.o + + $(CC) $(LDFLAGS) -o $@ $^ + +romfs: + $(ROMFSINST) /bin/mii_mgr + +clean: + -rm -f $(EXEC) *.elf *.gdb *.o + diff --git a/package/mtk/applications/mii_mgr/src/mii_mgr.c b/package/mtk/applications/mii_mgr/src/mii_mgr.c new file mode 100644 index 0000000000..a22c3e84b6 --- /dev/null +++ b/package/mtk/applications/mii_mgr/src/mii_mgr.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "mii_mgr.h" + +void show_usage(void) +{ + printf("mii_mgr -g -i [ifname] -p [phy number] -r [register number]\n"); + printf(" Get: mii_mgr -g -p 3 -r 4\n\n"); + printf("mii_mgr -s -p [phy number] -r [register number] -v [0xvalue]\n"); + printf(" Set: mii_mgr -s -p 4 -r 1 -v 0xff11\n"); + printf("#NOTE: Without -i , eth0 is default ifname!\n"); + printf("----------------------------------------------------------------------------------------\n"); + printf("Get: mii_mgr_cl45 -g -p [port number] -d [dev number] -r [register number]\n"); + printf("Example: mii_mgr_cl45 -g -p 3 -d 0x5 -r 0x4\n\n"); + printf("Set: mii_mgr_cl45 -s -p [port number] -d [dev number] -r [register number] -v [value]\n"); + printf("Example: mii_mgr_cl45 -s -p 4 -d 0x6 -r 0x1 -v 0xff11\n\n"); +} + +static void fill_mii_ioctl(struct mii_ioctl_data *mii, uint16_t phy_id, + uint16_t reg_num, uint16_t *val) +{ + mii->phy_id = phy_id; + mii->reg_num = reg_num; + mii->val_in = *val; + mii->val_out = 0; +} + + +static void fill_mtk_mii_ioctl(struct mtk_mii_ioctl_data *mtk_mii, uint16_t phy_id, + uint16_t reg_num, unsigned int *val) +{ + mtk_mii->phy_id = phy_id; + mtk_mii->reg_num = reg_num; + mtk_mii->val_in = *val; + mtk_mii->val_out = 0; +} + +static int __phy_op(char *ifname, uint16_t phy_id, uint16_t reg_num, unsigned int *val, uint16_t cmd, int is_priv) +{ + static int sd = -1; + + struct ifreq ifr; + struct mii_ioctl_data mii; + struct mtk_mii_ioctl_data mtk_mii; + int err; + + if (sd < 0) + sd = socket(AF_INET, SOCK_DGRAM, 0); + + if (sd < 0) + return sd; + + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) - 1); + ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + + if (is_priv) { + fill_mtk_mii_ioctl(&mtk_mii, phy_id, reg_num, val); + ifr.ifr_data = (char *)&mtk_mii; + } else { + fill_mii_ioctl(&mii, phy_id, reg_num, (uint16_t *)val); + ifr.ifr_data = (char *)&mii; + } + + err = ioctl(sd, cmd, &ifr); + if (err) + return -errno; + + if ((cmd == MTKETH_MII_WRITE) || (cmd == MTKETH_MII_WRITE_CL45) || + (cmd == SIOCSMIIREG)) + *val = (is_priv) ? mtk_mii.val_in : mii.val_in; + else + *val = (is_priv) ? mtk_mii.val_out : mii.val_out; + + return 0; +} + +int main(int argc, char *argv[]) +{ + int opt; + char options[] = "gsui:p:d:r:v:?t"; + int is_write = 0,is_cl45 = 0; + int is_priv = 1; + unsigned int port=0, dev=0,reg_num=0,val=0; + char ifname[IFNAMSIZ]="eth0"; + uint16_t phy_id=0; + uint16_t cmd; + + + if (argc < 6) { + show_usage(); + return 0; + } + + while ((opt = getopt(argc, argv, options)) != -1) { + switch (opt) { + case 'g': + is_write=0; + break; + case 's': + is_write=1; + break; + case 'u': + is_priv = 0; + break; + case 'i': + strncpy(ifname, optarg, 5); + ifname[IFNAMSIZ - 1] = '\0'; + break; + case 'p': + port = strtoul(optarg, NULL, 16); + if (port > INT_MAX) + return -EINVAL; + break; + case 'd': + dev = strtoul(optarg, NULL, 16); + if (dev > INT_MAX) + return -EINVAL; + is_cl45 = 1; + break; + case 'r': + reg_num = strtoul(optarg, NULL, 16); + if (reg_num > INT_MAX) + return -EINVAL; + break; + + case 'v': + val = strtoul(optarg, NULL, 16); + if (val > INT_MAX) + return -EINVAL; + break; + case '?': + show_usage(); + break; + } + } + + if(is_cl45) + phy_id = mdio_phy_id_c45(port, dev); + else + phy_id = port; + + if(is_write) { + if (is_priv) + cmd = (is_cl45) ? MTKETH_MII_WRITE_CL45 : + MTKETH_MII_WRITE; + else + cmd = SIOCSMIIREG; + + __phy_op(ifname,phy_id,reg_num, &val, cmd, is_priv); + + if(is_cl45) + printf("Set: port%x dev%Xh_reg%Xh = 0x%04X\n",port, dev, reg_num, val); + else + printf("Set: phy[%x].reg[%x] = %04x\n",port, reg_num, val); + } + else { + if (is_priv) + cmd = (is_cl45) ? MTKETH_MII_READ_CL45 : + MTKETH_MII_READ; + else + cmd = SIOCGMIIREG; + + __phy_op(ifname,phy_id,reg_num, &val, cmd, is_priv); + + if(is_cl45) + printf("Get: port%x dev%Xh_reg%Xh = 0x%04X\n",port, dev, reg_num, val); + else + printf("Get: phy[%x].reg[%x] = %04x\n",port, reg_num, val); + + } + + return 0; +} diff --git a/package/mtk/applications/mii_mgr/src/mii_mgr.h b/package/mtk/applications/mii_mgr/src/mii_mgr.h new file mode 100644 index 0000000000..66f7a616c8 --- /dev/null +++ b/package/mtk/applications/mii_mgr/src/mii_mgr.h @@ -0,0 +1,20 @@ +/* + * switch_ioctl.h: switch(ioctl) set API + */ + +#ifndef MII_MGR_H +#define MII_MGR_H + +#define MTKETH_MII_READ 0x89F3 +#define MTKETH_MII_WRITE 0x89F4 +#define MTKETH_MII_READ_CL45 0x89FC +#define MTKETH_MII_WRITE_CL45 0x89FD + +struct mtk_mii_ioctl_data { + __u16 phy_id; + __u16 reg_num; + __u32 val_in; + __u32 val_out; +}; + +#endif /* MII_MGR_H */ diff --git a/package/mtk/applications/regs/Makefile b/package/mtk/applications/regs/Makefile new file mode 100644 index 0000000000..d0f2444ad5 --- /dev/null +++ b/package/mtk/applications/regs/Makefile @@ -0,0 +1,39 @@ +# +# hua.shao@mediatek.com +# +# MTK Property Software. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=regs +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/regs + SECTION:=MTK Properties + CATEGORY:=MTK Properties + TITLE:=an program to read/write from/to a pci device from userspace. + SUBMENU:=Applications + DEPENDS:=+@KERNEL_DEVMEM +endef + +define Package/regs/description + Simple program to read/write from/to a pci device from userspace. +endef + +define Build/Configure +endef + +define Package/regs/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/regs $(1)/usr/bin +endef + + +$(eval $(call BuildPackage,regs)) + diff --git a/package/mtk/applications/regs/src/Makefile b/package/mtk/applications/regs/src/Makefile new file mode 100644 index 0000000000..bc3a12fb6f --- /dev/null +++ b/package/mtk/applications/regs/src/Makefile @@ -0,0 +1,13 @@ +EXEC = regs + +all: $(EXEC) + +$(EXEC): $(EXEC).c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $@.c $(LDLIBS) + +romfs: + $(ROMFSINST) /bin/$(EXEC) + +clean: + -rm -f $(EXEC) *.elf *.gdb *.o + diff --git a/package/mtk/applications/regs/src/regs.c b/package/mtk/applications/regs/src/regs.c new file mode 100644 index 0000000000..09e088c32d --- /dev/null +++ b/package/mtk/applications/regs/src/regs.c @@ -0,0 +1,170 @@ +/* + * pcimem.c: Simple program to read/write from/to a pci device from userspace. + * + * Copyright (C) 2010, Bill Farrow (bfarrow@beyondelectronics.us) + * + * Based on the devmem2.c code + * Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PRINT_ERROR \ + do { \ + fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ + __LINE__, __FILE__, errno, strerror(errno)); exit(1); \ + } while(0) + +#define MAP_SIZE 4096UL +#define MAP_MASK (MAP_SIZE - 1) + +void dump_page(uint32_t *vaddr, uint32_t *vbase, uint32_t *pbase) +{ + int i =0; + uint32_t *end = vaddr + (MAP_SIZE >> 6); + uint32_t *start = vaddr; + + while(start < end) { + printf("%p:%08x %08x %08x %08x\n", + start - vbase + pbase, start[0], start[1] , start[2], start[3]); + start+=4; + } +} + +void reg_mod_bits(uint32_t *virt_addr, int data, int start_bit, int data_len) +{ + int mask=0; + int value; + int i; + + if ((start_bit < 0) || (start_bit > 31) || + (data_len < 1) || (data_len > 32) || + (start_bit + data_len > 32)) { + fprintf(stderr, "Startbit range[0~31], and DataLen range[1~32], and Startbit + DataLen <= 32\n"); + return; + } + + for (i = 0; i < data_len; i++) { + if (start_bit + i > 31) + break; + + mask |= 1 << (start_bit + i); + } + + value = *((volatile uint32_t *) virt_addr); + value &= ~mask; + value |= (data << start_bit) & mask;; + + *((uint32_t *) virt_addr) = value; + + printf("Modify 0x%X[%d:%d]; ", data, start_bit + data_len - 1, start_bit); +} + +void usage(void) +{ + fprintf(stderr, "\nUsage:\tregs [Type] [ Offset:Hex ] [ Data:Hex ] [StartBit:Dec] [DataLen:Dec]\n" + "\tType : access operation type : [m]odify, [w]wite, [d]ump\n" + "\tOffset : offset into memory region to act upon\n" + "\tData : data to be written\n" + "\tStartbit: Startbit of Addr that want to be modified. Range[0~31]\n" + "\tDataLen : Data length of Data. Range[1~32], and Startbit + DataLen <= 32\n\n" + "Example:\tRead/Write/Modify register \n" + "\tRead : regs d 0x1b100000 //dump 0x1b100000~0x1b1000f0 \n" + "\tWrite : regs w 0x1b100000 0x1234 //write 0x1b100000=0x1234\n" + "\tModify : regs m 0x1b100000 0x0 29 3 //modify 0x1b100000[29:31]=0\n"); +} + +int main(int argc, char **argv) { + int fd; + void *map_base = NULL; + void *virt_addr = NULL; + uint32_t read_result =0; + uint32_t writeval = 0; + uint32_t startbit = 0; + uint32_t datalen = 0; + char *filename = NULL; + off_t offset = 0; + int access_type = 0; + + if(argc < 3) { + usage(); + exit(1); + } + + access_type = tolower(argv[1][0]); + if ((access_type == 'w' && argc < 4) || (access_type == 'm' && argc < 6)) { + usage(); + exit(1); + } + + filename = "/dev/mem"; + if((fd = open(filename, O_RDWR | O_SYNC)) == -1) + PRINT_ERROR; + + /* Map one page */ + offset = strtoul(argv[2], NULL, 16); + map_base = mmap(0, 2*MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset & ~MAP_MASK); + if(map_base == (void *) -1) + PRINT_ERROR; + + virt_addr = map_base + (offset & MAP_MASK); + read_result = *((volatile uint32_t *) virt_addr); + printf("Value at 0x%llX (%p): 0x%X\n", + (unsigned long long)offset, virt_addr, read_result); + + switch(access_type) { + case 'm': + writeval = strtoul(argv[3], 0, 16); + startbit = strtoul(argv[4], 0, 10); + datalen = strtoul(argv[5], 0, 10); + reg_mod_bits((uint32_t *)virt_addr, writeval, startbit, datalen); + break; + case 'w': + writeval = strtoul(argv[3], 0, 16); + *((uint32_t *) virt_addr) = writeval; + printf("Written 0x%X; ", writeval); + break; + case 'd': + dump_page(virt_addr, map_base, (uint32_t *)(offset & ~MAP_MASK)); + goto out; + default: + fprintf(stderr, "Illegal data type '%c'.\n", access_type); + goto out; + } + + read_result = *((volatile uint32_t *) virt_addr); + printf("Readback 0x%X\n", read_result); + +out: + if(munmap(map_base, MAP_SIZE) == -1) + PRINT_ERROR; + + close(fd); + return 0; +} diff --git a/package/mtk/applications/switch/Makefile b/package/mtk/applications/switch/Makefile new file mode 100644 index 0000000000..0eb3d7ea33 --- /dev/null +++ b/package/mtk/applications/switch/Makefile @@ -0,0 +1,48 @@ +# +# hua.shao@mediatek.com +# +# MTK Property Software. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=switch +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/switch + SECTION:=MTK Properties + CATEGORY:=MTK Properties + DEPENDS:=+libnl-tiny + TITLE:=Command to config switch + SUBMENU:=Applications +endef + +define Package/switch/description + An program to config switch. +endef + +TARGET_CPPFLAGS := \ + -D_GNU_SOURCE \ + -I$(LINUX_DIR)/user_headers/include \ + -I$(STAGING_DIR)/usr/include/libnl-tiny \ + -I$(PKG_BUILD_DIR) \ + $(TARGET_CPPFLAGS) \ + +define Build/Compile + CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + LIBS="$(TARGET_LDFLAGS) -lnl-tiny -lm" +endef + +define Package/switch/install + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/lib/network + $(INSTALL_BIN) $(PKG_BUILD_DIR)/switch $(1)/usr/sbin +endef + +$(eval $(call BuildPackage,switch)) diff --git a/package/mtk/applications/switch/src/Makefile b/package/mtk/applications/switch/src/Makefile new file mode 100644 index 0000000000..81ae127462 --- /dev/null +++ b/package/mtk/applications/switch/src/Makefile @@ -0,0 +1,14 @@ +EXEC = switch + +SRC=switch_fun.c switch_753x.c switch_ioctl.c switch_netlink.c + +all: $(EXEC) + +switch: $(SRC) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SRC) $(LDLIBS) $(LIBS) + +romfs: + $(ROMFSINST) /bin/switch + +clean: + -rm -f $(EXEC) *.elf *.gdb *.o diff --git a/package/mtk/applications/switch/src/NOTICE b/package/mtk/applications/switch/src/NOTICE new file mode 100644 index 0000000000..c031eed0a5 --- /dev/null +++ b/package/mtk/applications/switch/src/NOTICE @@ -0,0 +1,202 @@ +MediaTek (C) 2011 + +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU +General Public License is intended to guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to most of the Free Software Foundation's +software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make +sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you +receive source code or can get it if you want it, that you can change the software or use pieces of it in new free +programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to +surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all +the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them +these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty +for this free software. If the software is modified by someone else and passed on, we want its recipients to know that +what they have is not the original, so that any problems introduced by others will not reflect on the original authors' +reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors +of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, +we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it +may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or +work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to +say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into +another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is +addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its +scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by running the Program). Whether that is true +depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided +that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of +warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection +in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and +copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + +a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any +change. + +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the +Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for +such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright +notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if +the Program itself is interactive but does not normally print such an announcement, your work based on the Program is +not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the +Program, and can be reasonably considered independent and separate works in themselves, then this License, and its +terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same +sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part +regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; +rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the +Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms +of Sections 1 and 2 above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than +your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source +code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; +or, + +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This +alternative is allowed only for noncommercial distribution and only if you received the program in object code or +executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, +complete source code means all the source code for all modules it contains, plus any associated interface definition +files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, +the source code distributed need not include anything that is normally distributed (in either source or binary form) +with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless +that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering +equivalent access to copy the source code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your +rights under this License. However, parties who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you +permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do +not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you +indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or +modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a +license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You +may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to +patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as +to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence +you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy +both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the +section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest +validity of any such claims; this section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many people have made generous contributions to +the wide range of software distributed through that system in reliance on consistent application of that system; it is +up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee +cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted +interfaces, the original copyright holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. +Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or +concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which +applies to it and "any later version", you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are +different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two +goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT +LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY +OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + + diff --git a/package/mtk/applications/switch/src/switch_753x.c b/package/mtk/applications/switch/src/switch_753x.c new file mode 100644 index 0000000000..9c7c9211b6 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_753x.c @@ -0,0 +1,708 @@ +/* + * switch_753x.c: set for 753x switch + */ +#include +#include +#include +#include +#include +#include +#include + +#include "switch_netlink.h" +#include "switch_ioctl.h" +#include "switch_fun.h" + +struct mt753x_attr *attres; +int chip_name; +bool nl_init_flag; + +static void usage(char *cmd) +{ + printf("==================Usage===============================================================================================================================\n"); + + /* 1. basic operations */ + printf("1) mt753x switch Basic operations=================================================================================================================>>>>\n"); + printf(" 1.1) %s devs - list switch device id and model name \n", cmd); + printf(" 1.2) %s sysctl - show the ways to access kenerl driver: netlink or ioctl \n", cmd); + printf(" 1.3) %s reset - sw reset switch fsm and registers\n", cmd); + printf(" 1.4) %s reg r [offset] - read the reg with default switch \n", cmd); + printf(" 1.5) %s reg w [offset] [value] - write the reg with default switch \n", cmd); + printf(" 1.6) %s reg d [offset] - dump the reg with default switch\n", cmd); + printf(" 1.7) %s dev [devid] reg r [addr] - read the reg with the switch devid \n", cmd); + printf(" 1.8) %s dev [devid] reg w [addr] [value] - write the regs with the switch devid \n", cmd); + printf(" 1.9) %s dev [devid] reg d [addr] - dump the regs with the switch devid \n", cmd); + printf(" \n"); + + /* 2. phy operations */ + printf("2) mt753x switch PHY operations===================================================================================================================>>>>\n"); + printf(" 2.1) %s phy - dump all phy registers (clause 22)\n", cmd); + printf(" 2.2) %s phy [phy_addr] - dump phy register of specific port (clause 22)\n", cmd); + printf(" 2.3) %s phy cl22 r [port_num] [phy_reg] - read specific phy register of specific port by clause 22\n", cmd); + printf(" 2.4) %s phy cl22 w [port_num] [phy_reg] [value] - write specific phy register of specific port by clause 22\n", cmd); + printf(" 2.5) %s phy cl45 r [port_num] [dev_num] [phy_reg] - read specific phy register of specific port by clause 45\n", cmd); + printf(" 2.6) %s phy cl45 w [port_num] [dev_num] [phy_reg] [value] - write specific phy register of specific port by clause 45\n", cmd); + printf(" 2.7) %s phy fc [port_num] [enable 0|1] - set switch phy flow control, port is 0~4, enable is 1, disable is 0 \n", cmd); + printf(" 2.8) %s phy an [port_num] [enable 0|1] - set switch phy auto-negotiation, port is 0~4, enable is 1, disable is 0 \n", cmd); + printf(" 2.9) %s trreg r [port_num] [ch_addr] [node_addr] [data_addr] - read phy token-ring of specific port\n", cmd); + printf(" 2.10) %s trreg w [port_num] [ch_addr] [node_addr] [data_addr] - write phy token-ring of specific port\n", cmd); + printf(" [high_value] [low_value] \n"); + printf(" 2.11) %s crossover [port_num] [mode auto|mdi|mdix] - switch auto or force mdi/mdix mode for crossover cable\n", cmd); + printf(" \n"); + + /* 3. mac operations */ + printf("3) mt753x switch MAC operations====================================================================================================================>>>>\n"); + printf(" 3.1) %s dump - dump switch mac table\n", cmd); + printf(" 3.2) %s clear - clear switch mac table\n", cmd); + printf(" 3.3) %s add [mac] [portmap] - add an entry (with portmap) to switch mac table\n", cmd); + printf(" 3.4) %s add [mac] [portmap] [vlan id] - add an entry (with portmap, vlan id) to switch mac table\n", cmd); + printf(" 3.5) %s add [mac] [portmap] [vlan id] [age] - add an entry (with portmap, vlan id, age out time) to switch mac table\n", cmd); + printf(" 3.6) %s del mac [mac] vid [vid] - delete an entry from switch mac table\n", cmd); + printf(" 3.7) %s del mac [mac] fid [fid] - delete an entry from switch mac table\n", cmd); + printf(" 3.8) %s search mac [mac] vid [vid] - search an entry with specific mac and vid\n", cmd); + printf(" 3.9) %s search mac [mac] fid [fid] - search an entry with specific mac and fid\n", cmd); + printf(" 3.10) %s filt [mac] - add a SA filtering entry (with portmap 1111111) to switch mac table\n", cmd); + printf(" 3.11) %s filt [mac] [portmap] - add a SA filtering entry (with portmap)to switch mac table\n", cmd); + printf(" 3.12) %s filt [mac] [portmap] [vlan id - add a SA filtering entry (with portmap, vlan id)to switch mac table\n", cmd); + printf(" 3.13) %s filt [mac] [portmap] [vlan id] [age] - add a SA filtering entry (with portmap, vlan id, age out time) to switch table\n", cmd); + printf(" 3.14) %s arl aging [active:0|1] [time:1~65536] - set switch arl aging timeout value \n", cmd); + printf(" 3.15) %s macctl fc [enable|disable] - set switch mac global flow control,enable is 1, disable is 0 \n", cmd); + printf(" \n"); + + /* 4. mib counter operations */ + printf("4) mt753x switch mib counter operations============================================================================================================>>>>\n"); + printf(" 4.1) %s esw_cnt get -get switch mib counters \n", cmd); + printf(" 4.2) %s esw_cnt clear -clear switch mib counters \n", cmd); + printf(" 4.3) %s output_queue_cnt get -get switch output queue counters \n", cmd); + printf(" 4.4) %s free_page get -get switch system free page counters \n", cmd); + printf(" \n"); + + /* 5. acl function operations */ + printf("5) mt753x switch acl function operations============================================================================================================>>>>\n"); + printf(" 5.1) %s acl enable [port] [port_enable:0|1] - set switch acl function enabled, port is 0~6,enable is 1, disable is 0 \n", cmd); + printf(" 5.2) %s acl etype add [ethtype] [portmap] - drop L2 ethertype packets \n", cmd); + printf(" 5.3) %s acl dmac add [mac] [portmap] - drop L2 dest-Mac packets \n", cmd); + printf(" 5.4) %s acl dip add [dip] [portmap] - drop dip packets \n", cmd); + printf(" 5.5) %s acl port add [sport] [portmap] - drop L4 UDP/TCP source port packets\n", cmd); + printf(" 5.6) %s acl L4 add [2byes] [portmap] - drop L4 packets with 2bytes payload\n", cmd); + printf(" 5.7) %s acl acltbl-add [tbl_idx:0~63/255] [vawd1] [vawd2] - set switch acl table new entry, max index-7530:63,7531:255 \n", cmd); + printf(" 5.8) %s acl masktbl-add [tbl_idx:0~31/127] [vawd1] [vawd2] - set switch acl mask table new entry, max index-7530:31,7531:127 \n", cmd); + printf(" 5.9) %s acl ruletbl-add [tbl_idx:0~31/127] [vawd1] [vawd2] - set switch acl rule table new entry, max index-7530:31,7531:127 \n", cmd); + printf(" 5.10) %s acl ratetbl-add [tbl_idx:0~31] [vawd1] [vawd2] - set switch acl rate table new entry \n", cmd); + printf(" 5.11) %s acl dip meter [dip] [portmap][meter:kbps] - rate limit dip packets \n", cmd); + printf(" 5.12) %s acl dip trtcm [dip] [portmap][CIR:kbps][CBS][PIR][PBS]- TrTCM dip packets \n", cmd); + printf(" 5.13) %s acl dip modup [dip] [portmap][usr_pri] - modify usr priority from ACL \n", cmd); + printf(" 5.14) %s acl dip pppoe [dip] [portmap] - pppoe header removal \n", cmd); + printf(" \n"); + + /* 6. dip table operations */ + printf("6) mt753x switch dip table operations=================================================================================================================>>>>\n"); + printf(" 6.1) %s dip dump - dump switch dip table\n", cmd); + printf(" 6.2) %s dip clear - clear switch dip table\n", cmd); + printf(" 6.3) %s dip add [dip] [portmap] - add a dip entry to switch table\n", cmd); + printf(" 6.4) %s dip del [dip] - del a dip entry to switch table\n", cmd); + printf(" \n"); + + /* 7. sip table operations */ + printf("7) mt753x switch sip table operations=================================================================================================================>>>>\n"); + printf(" 7.1) %s sip dump - dump switch sip table\n", cmd); + printf(" 7.2) %s sip clear - clear switch sip table\n", cmd); + printf(" 7.3) %s sip add [sip] [dip] [portmap] - add a sip entry to switch table\n", cmd); + printf(" 7.4) %s sip del [sip] [dip] - del a sip entry to switch table\n", cmd); + printf(" \n"); + + /* 8. vlan table operations */ + printf("8) mt753x switch sip table operations====================================================================================================================>>>>\n"); + printf(" 8.1) %s vlan dump (egtag) - dump switch vlan table (with per port eg_tag setting)\n", cmd); + printf(" 8.2) %s vlan set [fid:0~7] [vid] [portmap] - set vlan id and associated member at switch vlan table\n", cmd); + printf(" ([stag:0~4095] [eg_con:0|1] [egtagPortMap 0:untagged 2:tagged]) \n"); + printf(" Full Example: %s vlan set 0 3 10000100 0 0 20000200\n", cmd); + printf(" 8.3) %s vlan vid [vlan idx] [active:0|1] [vid] [portMap] - set switch vlan vid elements \n", cmd); + printf(" [egtagPortMap] [ivl_en] [fid] [stag] \n"); + printf(" 8.4) %s vlan pvid [port] [pvid] - set switch vlan pvid \n", cmd); + printf(" 8.5) %s vlan acc-frm [port] [acceptable_frame_type:0~3] - set switch vlan acceptable_frame type : admit all frames: 0, \n", cmd); + printf(" admit only vlan-taged frames: 1,admit only untagged or priority-tagged frames: 2, reserved:3 \n"); + printf(" 8.6) %s vlan port-attr [port] [attr:0~3] - set switch vlan port attribute: user port: 0, statck port: 1, \n", cmd); + printf(" translation port: 2, transparent port:3 \n"); + printf(" 8.7) %s vlan port-mode [port] [mode:0~3] - set switch vlan port mode : port matrix mode: 0, fallback mode: 1, \n", cmd); + printf(" check mode: 2, security mode:3 \n"); + printf(" 8.8) %s vlan eg-tag-pvc [port] [eg_tag:0~7] - set switch vlan eg tag pvc : disable: 0, consistent: 1, reserved: 2, \n", cmd); + printf(" reserved:3,untagged:4,swap:5,tagged:6, stack:7 \n"); + printf(" 8.9) %s vlan eg-tag-pcr [port] [eg_tag:0~3] - set switch vlan eg tag pcr : untagged: 0, swap: 1, tagged: 2, stack:3 \n", cmd); + printf(" \n"); + + /* 9. rate limit operations */ + printf("9) mt753x switch rate limit operations=================================================================================================================>>>>\n"); + printf(" 9.1) %s ratectl [in_ex_gress:0|1] [port] [rate] - set switch port ingress(1) or egress(0) rate \n", cmd); + printf(" 9.2) %s ingress-rate on [port] [Kbps] - set ingress rate limit on port n (n= 0~ switch max port) \n", cmd); + printf(" 9.3) %s egress-rate on [port] [Kbps] - set egress rate limit on port n (n= 0~ switch max port) \n", cmd); + printf(" 9.4) %s ingress-rate off [port] - disable ingress rate limit on port n (n= 0~ switch max port) \n", cmd); + printf(" 9.5) %s egress-rate off [port] - disable egress rate limit on port n (n= 0~ switch max port)\n", cmd); + printf(" \n"); + + /* 10. igmp operations */ + printf("10) mt753x igmp operations===============================================================================================================================>>>>\n"); + printf(" 10.1) %s igmpsnoop on [leaky_en] [wan_num] - turn on IGMP snoop and router port learning\n", cmd); + printf(" leaky_en: 1 or 0. default 0; wan_num: 0 or 4. default 4\n"); + printf(" 10.2) %s igmpsnoop off - turn off IGMP snoop and router port learning\n", cmd); + printf(" 10.3) %s igmpsnoop enable [port#] - enable IGMP HW leave/join/Squery/Gquery\n", cmd); + printf(" 10.4) %s igmpsnoop disable [port#] - disable IGMP HW leave/join/Squery/Gquery\n", cmd); + printf(" \n"); + + /* 11. QoS operations */ + printf("11) mt753x QoS operations================================================================================================================================>>>>\n"); + printf(" 11.1) %s qos sch [port:0~6] [queue:0~7] [shaper:min|max] [type:rr:0|sp:1|wfq:2] - set switch qos sch type\n", cmd); + printf(" 11.2) %s qos base [port:0~6] [base] - set switch qos base(UPW); port-based:0, tag-based:1, \n", cmd); + printf(" dscp-based:2, acl-based:3, arl-based:4, stag-based:5 \n"); + printf(" 11.3) %s qos port-weight [port:0~6] [q0] [q1][q2][q3] - set switch qos port queue weight; \n", cmd); + printf(" [q4][q5][q6][q7] [qn]: the weight of queue n, range: 1~16 \n"); + printf(" 11.4) %s qos port-prio [port:0~6] [prio:0~7] - set switch port qos user priority; port is 0~6, priority is 0~7 \n", cmd); + printf(" 11.5) %s qos dscp-prio [dscp:0~63] [prio:0~7] - set switch qos dscp user priority; dscp is 0~63, priority is 0~7 \n", cmd); + printf(" 11.6) %s qos prio-qmap [port:0~6] [prio:0~7] [queue:0~7] - set switch qos priority queue map; priority is 0~7,queue is 0~7 \n", cmd); + printf(" \n"); + + /*12. port mirror operations*/ + printf(" 12) mt753x port mirror operations========================================================================================================================>>>>\n"); + printf(" 12.1) %s mirror monitor [port] - enable port mirror and indicate monitor port number\n", cmd); + printf(" 12.2) %s mirror target [port] - set port mirror target\n", cmd); + printf(" [direction| 0:off, 1:rx, 2:tx, 3:all] \n"); + printf(" 12.3) %s mirror enable [mirror_en:0|1] [mirror_port: 0-6] - set switch mirror function enable(1) or disabled(0) for port 0~6 \n", cmd); + printf(" 12.4) %s mirror port-based [port] [port_tx_mir:0|1] - set switch mirror port: target tx/rx/acl/vlan/igmp\n", cmd); + printf(" [port_rx_mir:0|1] [acl_mir:0|1] \n"); + printf(" [vlan_mis:0|1] [igmp_mir:0|1] \n"); + printf(" \n"); + + /*13. stp function*/ + printf(" 13) mt753x stp operations===============================================================================================================================>>>>\n"); + printf(" 13.1) %s stp [port] [fid] [state] - set switch spanning tree state, port is 0~6, fid is 0~7, \n", cmd); + printf(" state is 0~3(Disable/Discarding:0,Blocking/Listening/Discarding:1,) \n"); + printf(" Learning:2,Forwarding:3 \n"); + printf(" \n"); + + /*14. collision pool operations*/ + printf("14) mt753x collision pool operations========================================================================================================================>>>>\n"); + printf(" 14.1) %s collision-pool enable [enable 0|1] - enable or disable collision pool\n", cmd); + printf(" 14.2) %s collision-pool mac dump - dump collision pool mac table\n", cmd); + printf(" 14.3) %s collision-pool dip dump - dump collision pool dip table\n", cmd); + printf(" 14.4) %s collision-pool sip dump - dump collision pool sip table\n", cmd); + printf(" \n"); + + /*15. pfc(priority flow control) operations*/ + printf("15) mt753x pfc(priority flow control) operations==============================================================================================================>>>>\n"); + printf(" 15.1) %s pfc enable [port] [enable 0|1] - enable or disable port's pfc \n", cmd); + printf(" 15.2) %s pfc rx_counter [port] - get port n pfc 8 up rx counter \n", cmd); + printf(" 15.3) %s pfc tx_counter [port] - get port n pfc 8 up rx counter \n", cmd); + printf(" \n"); + + /*15. pfc(priority flow control) operations*/ + printf("16) mt753x EEE(802.3az) operations==============================================================================================================>>>>\n"); + printf(" 16.1) %s eee enable [enable 0|1] ([portMap]) - enable or disable EEE (by portMap)\n", cmd); + printf(" 16.2) %s eee dump ([port]) - dump EEE capability (by port)\n", cmd); + printf(" \n"); + + exit_free(); + exit(0); +} + +static void parse_reg_cmd(int argc, char *argv[], int len) +{ + unsigned int val; + unsigned int off; + int i, j; + + if (!strncmp(argv[len - 3], "reg", 4)) { + if (argv[len - 2][0] == 'r') { + off = strtoul(argv[len - 1], NULL, 16); + reg_read(off, &val); + printf(" Read reg=%x, value=%x\n", off, val); + } else if (argv[len - 2][0] == 'w') { + off = strtoul(argv[len - 1], NULL, 16); + if (argc != len + 1) + usage(argv[0]); + val = strtoul(argv[len], NULL, 16); + reg_write(off, val); + printf(" Write reg=%x, value=%x\n", off, val); + } else if (argv[len - 2][0] == 'd') { + off = strtoul(argv[len - 1], NULL, 16); + for (i = 0; i < 16; i++) { + printf("0x%08x: ", off + 0x10 * i); + for (j = 0; j < 4; j++) { + reg_read(off + i * 0x10 + j * 0x4, &val); + printf(" 0x%08x", val); + } + printf("\n"); + } + } else + usage(argv[0]); + } else + usage(argv[0]); +} + +static int get_chip_name() +{ + int temp; + FILE *fp = NULL; + char buff[255]; + + /*judge 7530*/ + reg_read((0x7ffc), &temp); + temp = temp >> 16; + if (temp == 0x7530) + return temp; + /*judge 7531*/ + reg_read(0x781c, &temp); + temp = temp >> 16; + if (temp == 0x7531) + return temp; + + /*judge jaguar embedded switch*/ + fp = fopen("/proc/device-tree/compatible", "r"); + if (fp != NULL) { + temp = -1; + if (fgets(buff, 255, (FILE *)fp) && strstr(buff, "mt7988")) + temp = 0x7988; + + fclose(fp); + return temp; + } + + return -1; +} + +static int phy_operate(int argc, char *argv[]) +{ + unsigned int port_num; + unsigned int dev_num; + unsigned int value, cl_value; + unsigned int reg; + int ret = 0, cl_ret = 0; + char op; + + if (strncmp(argv[2], "cl22", 4) && strncmp(argv[2], "cl45", 4)) + usage(argv[0]); + + op = argv[3][0]; + + switch(op) { + case 'r': + reg = strtoul(argv[argc-1], NULL, 0); + if (argc == 6) { + port_num = strtoul(argv[argc-2], NULL, 0); + ret = mii_mgr_read(port_num, reg, &value); + if (ret < 0) + printf(" Phy read reg fail\n"); + else + printf(" Phy read reg=0x%x, value=0x%x\n", reg, value); + } else if (argc == 7) { + dev_num = strtoul(argv[argc-2], NULL, 0); + port_num = strtoul(argv[argc-3], NULL, 0); + ret = mii_mgr_c45_read(port_num, dev_num, reg, &value); + if (ret < 0) + printf(" Phy read reg fail\n"); + else + printf(" Phy read reg=0x%x, value=0x%x\n", reg, value); + } else + ret = phy_dump(32); + break; + case 'w': + reg = strtoul(argv[argc-2], NULL, 0); + value = strtoul(argv[argc-1], NULL, 0); + if (argc == 7) { + port_num = strtoul(argv[argc-3], NULL, 0); + ret = mii_mgr_write(port_num, reg, value); + cl_ret = mii_mgr_read(port_num, reg, &cl_value); + if (cl_ret < 0) + printf(" Phy read reg fail\n"); + else + printf(" Phy read reg=0x%x, value=0x%x\n", reg, cl_value); + } + else if (argc == 8) { + dev_num = strtoul(argv[argc-3], NULL, 0); + port_num = strtoul(argv[argc-4], NULL, 0); + ret = mii_mgr_c45_write(port_num, dev_num, reg, value); + cl_ret = mii_mgr_c45_read(port_num, dev_num, reg, &cl_value); + if (cl_ret < 0) + printf(" Phy read reg fail\n"); + else + printf(" Phy read reg=0x%x, value=0x%x\n", reg, cl_value); + } + else + usage(argv[0]); + break; + default: + break; + } + + return ret; +} + + +int main(int argc, char *argv[]) +{ + int err; + + attres = (struct mt753x_attr *)malloc(sizeof(struct mt753x_attr)); + attres->dev_id = -1; + attres->port_num = -1; + attres->phy_dev = -1; + nl_init_flag = true; + + /* dsa netlink family might not be enabled. Try gsw netlink family. */ + err = mt753x_netlink_init(MT753X_DSA_GENL_NAME); + if (!err) + chip_name = get_chip_name(); + + if (err < 0) { + err = mt753x_netlink_init(MT753X_GENL_NAME); + if (!err) + chip_name = get_chip_name(); + } + + if (err < 0) { + err = switch_ioctl_init(); + if (!err) { + nl_init_flag = false; + chip_name = get_chip_name(); + if (chip_name < 0) { + printf("no chip unsupport or chip id is invalid!\n"); + exit_free(); + exit(0); + } + } + } + + if (argc < 2) + usage(argv[0]); + + if (!strcmp(argv[1], "dev")) { + attres->dev_id = strtoul(argv[2], NULL, 0); + argv += 2; + argc -= 2; + if (argc < 2) + usage(argv[0]); + + } + + if (argc == 2) { + if (!strcmp(argv[1], "devs")) { + attres->type = MT753X_ATTR_TYPE_MESG; + mt753x_list_swdev(attres, MT753X_CMD_REQUEST); + } else if (!strncmp(argv[1], "dump", 5)) { + table_dump(); + } else if (!strncmp(argv[1], "clear", 6)) { + table_clear(); + printf("done.\n"); + } else if (!strncmp(argv[1], "reset", 5)) { + switch_reset(argc, argv); + } else if (!strncmp(argv[1], "phy", 4)) { + phy_dump(32); //dump all phy register + } else if (!strncmp(argv[1], "sysctl", 7)) { + if (nl_init_flag) + printf("netlink(%s)\n",MT753X_GENL_NAME); + else + printf("ioctl(%s)\n",ETH_DEVNAME); + } else + usage(argv[0]); + } else if (!strncmp(argv[1], "arl", 4)) { + if (!strncmp(argv[2], "aging", 6)) + doArlAging(argc, argv); + } else if (!strncmp(argv[1], "esw_cnt", 8)) { + if (!strncmp(argv[2], "get", 4)) + read_mib_counters(); + else if (!strncmp(argv[2], "clear", 6)) + clear_mib_counters(); + else + usage(argv[0]); + }else if (!strncmp(argv[1], "output_queue_cnt", 17)) { + if (!strncmp(argv[2], "get", 4)) + read_output_queue_counters(); + else + usage(argv[0]); + }else if (!strncmp(argv[1], "free_page", 10)) { + if (!strncmp(argv[2], "get", 4)) + read_free_page_counters(); + else + usage(argv[0]); + } + else if (!strncmp(argv[1], "ratectl", 8)) + rate_control(argc, argv); + else if (!strncmp(argv[1], "add", 4)) + table_add(argc, argv); + else if (!strncmp(argv[1], "filt", 5)) + table_add(argc, argv); + else if (!strncmp(argv[1], "del", 4)) { + if (!strncmp(argv[4], "fid", 4)) + table_del_fid(argc, argv); + else if (!strncmp(argv[4], "vid", 4)) + table_del_vid(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "search", 7)) { + if (!strncmp(argv[4], "fid", 4)) + table_search_mac_fid(argc, argv); + else if (!strncmp(argv[4], "vid", 4)) + table_search_mac_vid(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "phy", 4)) { + if (argc == 3) { + int phy_addr = strtoul(argv[2], NULL, 0); + if (phy_addr < 0 || phy_addr > 31) + usage(argv[0]); + phy_dump(phy_addr); + } else if (argc == 5) { + if (!strncmp(argv[2], "fc", 2)) + phy_set_fc(argc, argv); + else if (!strncmp(argv[2], "an", 2)) + phy_set_an(argc, argv); + else + phy_dump(32); + } else + phy_operate(argc, argv); + } else if (!strncmp(argv[1], "trreg", 4)) { + if (rw_phy_token_ring(argc, argv) < 0) + usage(argv[0]); + } else if (!strncmp(argv[1], "macctl", 7)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "fc", 3)) + global_set_mac_fc(argc, argv); + else if (!strncmp(argv[2], "pfc", 4)) + set_mac_pfc(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "qos", 4)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "sch", 4)) + qos_sch_select(argc, argv); + else if (!strncmp(argv[2], "base", 5)) + qos_set_base(argc, argv); + else if (!strncmp(argv[2], "port-weight", 12)) + qos_wfq_set_weight(argc, argv); + else if (!strncmp(argv[2], "port-prio", 10)) + qos_set_portpri(argc, argv); + else if (!strncmp(argv[2], "dscp-prio", 10)) + qos_set_dscppri(argc, argv); + else if (!strncmp(argv[2], "prio-qmap", 10)) + qos_pri_mapping_queue(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "stp", 3)) { + if (argc < 3) + usage(argv[0]); + else + doStp(argc, argv); + } else if (!strncmp(argv[1], "sip", 5)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "dump", 5)) + sip_dump(); + else if (!strncmp(argv[2], "add", 4)) + sip_add(argc, argv); + else if (!strncmp(argv[2], "del", 4)) + sip_del(argc, argv); + else if (!strncmp(argv[2], "clear", 6)) + sip_clear(); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "dip", 4)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "dump", 5)) + dip_dump(); + else if (!strncmp(argv[2], "add", 4)) + dip_add(argc, argv); + else if (!strncmp(argv[2], "del", 4)) + dip_del(argc, argv); + else if (!strncmp(argv[2], "clear", 6)) + dip_clear(); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "mirror", 7)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "monitor", 8)) + set_mirror_to(argc, argv); + else if (!strncmp(argv[2], "target", 7)) + set_mirror_from(argc, argv); + else if (!strncmp(argv[2], "enable", 7)) + doMirrorEn(argc, argv); + else if (!strncmp(argv[2], "port-based", 11)) + doMirrorPortBased(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "acl", 4)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "dip", 4)) { + if (!strncmp(argv[3], "add", 4)) + acl_dip_add(argc, argv); + else if (!strncmp(argv[3], "modup", 6)) + acl_dip_modify(argc, argv); + else if (!strncmp(argv[3], "pppoe", 6)) + acl_dip_pppoe(argc, argv); + else if (!strncmp(argv[3], "trtcm", 4)) + acl_dip_trtcm(argc, argv); + else if (!strncmp(argv[3], "meter", 6)) + acl_dip_meter(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "dmac", 6)) { + if (!strncmp(argv[3], "add", 4)) + acl_mac_add(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "etype", 6)) { + if (!strncmp(argv[3], "add", 4)) + acl_ethertype(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "port", 5)) { + if (!strncmp(argv[3], "add", 4)) + acl_sp_add(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "L4", 5)) { + if (!strncmp(argv[3], "add", 4)) + acl_l4_add(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "enable", 7)) + acl_port_enable(argc, argv); + else if (!strncmp(argv[2], "acltbl-add", 11)) + acl_table_add(argc, argv); + else if (!strncmp(argv[2], "masktbl-add", 12)) + acl_mask_table_add(argc, argv); + else if (!strncmp(argv[2], "ruletbl-add", 12)) + acl_rule_table_add(argc, argv); + else if (!strncmp(argv[2], "ratetbl-add", 12)) + acl_rate_table_add(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "vlan", 5)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "dump", 5)) + vlan_dump(argc, argv); + else if (!strncmp(argv[2], "set", 4)) + vlan_set(argc, argv); + else if (!strncmp(argv[2], "clear", 6)) + vlan_clear(argc, argv); + else if (!strncmp(argv[2], "vid", 4)) + doVlanSetVid(argc, argv); + else if (!strncmp(argv[2], "pvid", 5)) + doVlanSetPvid(argc, argv); + else if (!strncmp(argv[2], "acc-frm", 8)) + doVlanSetAccFrm(argc, argv); + else if (!strncmp(argv[2], "port-attr", 10)) + doVlanSetPortAttr(argc, argv); + else if (!strncmp(argv[2], "port-mode", 10)) + doVlanSetPortMode(argc, argv); + else if (!strncmp(argv[2], "eg-tag-pcr", 11)) + doVlanSetEgressTagPCR(argc, argv); + else if (!strncmp(argv[2], "eg-tag-pvc", 11)) + doVlanSetEgressTagPVC(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "reg", 4)) { + parse_reg_cmd(argc, argv, 4); + } else if (!strncmp(argv[1], "ingress-rate", 6)) { + int port = 0, bw = 0; + if (argv[2][1] == 'n') { + port = strtoul(argv[3], NULL, 0); + bw = strtoul(argv[4], NULL, 0); + if (ingress_rate_set(1, port, bw) == 0) + printf("switch port=%d, bw=%d\n", port, bw); + } + else if (argv[2][1] == 'f') { + if (argc != 4) + usage(argv[0]); + port = strtoul(argv[3], NULL, 0); + if (ingress_rate_set(0, port, bw) == 0) + printf("switch port=%d ingress rate limit off\n", port); + } else + usage(argv[0]); + } else if (!strncmp(argv[1], "egress-rate", 6)) { + int port = 0, bw = 0; + if (argv[2][1] == 'n') { + port = strtoul(argv[3], NULL, 0); + bw = strtoul(argv[4], NULL, 0); + if (egress_rate_set(1, port, bw) == 0) + printf("switch port=%d, bw=%d\n", port, bw); + } else if (argv[2][1] == 'f') { + if (argc != 4) + usage(argv[0]); + port = strtoul(argv[3], NULL, 0); + if (egress_rate_set(0, port, bw) == 0) + printf("switch port=%d egress rate limit off\n", port); + } else + usage(argv[0]); + } else if (!strncmp(argv[1], "igmpsnoop", 10)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "on", 3)) + igmp_on(argc, argv); + else if (!strncmp(argv[2], "off", 4)) + igmp_off(); + else if (!strncmp(argv[2], "enable", 7)) + igmp_enable(argc, argv); + else if (!strncmp(argv[2], "disable", 8)) + igmp_disable(argc, argv); + else + usage(argv[0]); + } else if (!strncmp(argv[1], "collision-pool", 15)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "enable", 7)) + collision_pool_enable(argc, argv); + else if (!strncmp(argv[2], "mac", 4)){ + if (!strncmp(argv[3], "dump", 5)) + collision_pool_mac_dump(); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "dip", 4)){ + if (!strncmp(argv[3], "dump", 5)) + collision_pool_dip_dump(); + else + usage(argv[0]); + } else if (!strncmp(argv[2], "sip", 4)){ + if (!strncmp(argv[3], "dump", 5)) + collision_pool_sip_dump(); + else + usage(argv[0]); + } + else + usage(argv[0]); + } else if (!strncmp(argv[1], "pfc", 15)) { + if (argc < 4 || argc > 5) + usage(argv[0]); + if (!strncmp(argv[2], "enable", 7)) + set_mac_pfc(argc, argv); + else if (!strncmp(argv[2], "rx_counter", 11)){ + pfc_get_rx_counter(argc, argv); + } else if (!strncmp(argv[2], "tx_counter", 11)){ + pfc_get_tx_counter(argc, argv); + } else + usage(argv[0]); + } else if (!strncmp(argv[1], "crossover", 10)) { + if (argc < 4) + usage(argv[0]); + else + phy_crossover(argc, argv); + } else if (!strncmp(argv[1], "eee", 4)) { + if (argc < 3) + usage(argv[0]); + if (!strncmp(argv[2], "enable", 7) || + !strncmp(argv[2], "disable", 8)) + eee_enable(argc, argv); + else if (!strncmp(argv[2], "dump", 5)) + eee_dump(argc, argv); + else + usage(argv[0]); + } else + usage(argv[0]); + + exit_free(); + return 0; +} diff --git a/package/mtk/applications/switch/src/switch_extend.h b/package/mtk/applications/switch/src/switch_extend.h new file mode 100644 index 0000000000..c35276792c --- /dev/null +++ b/package/mtk/applications/switch/src/switch_extend.h @@ -0,0 +1,342 @@ +#define atoi(x) strtoul(x, NULL,10) + +#define EXTEND_SETVID_PARAM 1 +#define SQA_VERIFY 1 +#define ETHCMD_DBG 1 +#define ACTIVED (1<<0) +#define SWITCH_MAX_PORT 7 + +#define GENERAL_TABLE 0 +#define COLLISION_TABLE 1 + +#define GSW_BASE 0x0 +#define GSW_ARL_BASE (GSW_BASE + 0x0000) +#define GSW_BMU_BASE (GSW_BASE + 0x1000) +#define GSW_PORT_BASE (GSW_BASE + 0x2000) +#define GSW_MAC_BASE (GSW_BASE + 0x3000) +#define GSW_MIB_BASE (GSW_BASE + 0x4000) +#define GSW_CFG_BASE (GSW_BASE + 0x7000) + +#define GSW_PCR(n) (GSW_PORT_BASE + (n)*0x100 + 0x04) +#define GSW_MFC (GSW_ARL_BASE + 0x10) +#define GSW_UPW(n) (GSW_PORT_BASE + (n)*0x100 + 0x40) +//#define GSW_PEM(n) (GSW_ARL_BASE + (n)*0x4 + 0x48) +#define GSW_PEM(n) (GSW_PORT_BASE + (n)*0x4 + 0x44) + +#define GSW_MMSCR0_Q(n) (GSW_BMU_BASE + (n)*0x8) +#define GSW_MMSCR1_Q(n) (GSW_BMU_BASE + (n)*0x8 + 0x04) + +#define GSW_PMCR(n) (GSW_MAC_BASE + (n)*0x100) +#define GSW_PMSR(n) (GSW_MAC_BASE + (n)*0x100 + 0x08) +#define GSW_PINT_EN(n) (GSW_MAC_BASE + (n)*0x100 + 0x10) +#define GSW_SMACCR0 (GSW_MAC_BASE + 0xe4) +#define GSW_SMACCR1 (GSW_MAC_BASE + 0xe8) +#define GSW_CKGCR (GSW_MAC_BASE + 0xf0) + +#define GSW_ESR(n) (GSW_MIB_BASE + (n)*0x100 + 0x00) +#define GSW_INTS(n) (GSW_MIB_BASE + (n)*0x100 + 0x04) +#define GSW_TGPC(n) (GSW_MIB_BASE + (n)*0x100 + 0x10) +#define GSW_TBOC(n) (GSW_MIB_BASE + (n)*0x100 + 0x14) +#define GSW_TGOC(n) (GSW_MIB_BASE + (n)*0x100 + 0x18) +#define GSW_TEPC(n) (GSW_MIB_BASE + (n)*0x100 + 0x1C) +#define GSW_RGPC(n) (GSW_MIB_BASE + (n)*0x100 + 0x20) +#define GSW_RBOC(n) (GSW_MIB_BASE + (n)*0x100 + 0x24) +#define GSW_RGOC(n) (GSW_MIB_BASE + (n)*0x100 + 0x28) +#define GSW_REPC1(n) (GSW_MIB_BASE + (n)*0x100 + 0x2C) +#define GSW_REPC2(n) (GSW_MIB_BASE + (n)*0x100 + 0x30) +#define GSW_MIBCNTEN (GSW_MIB_BASE + 0x800) +#define GSW_AECNT1 (GSW_MIB_BASE + 0x804) +#define GSW_AECNT2 (GSW_MIB_BASE + 0x808) + +#define GSW_CFG_PPSC (GSW_CFG_BASE + 0x0) +#define GSW_CFG_PIAC (GSW_CFG_BASE + 0x4) +#define GSW_CFG_GPC (GSW_CFG_BASE + 0x14) + +#define MAX_VID_VALUE (4095) +#define MAX_VLAN_RULE (16) + + +#define REG_MFC_ADDR (0x0010) +#define REG_ISC_ADDR (0x0018) + +#define REG_CFC_ADDR (0x0004) +#define REG_CFC_MIRROR_PORT_OFFT (16) +#define REG_CFC_MIRROR_PORT_LENG (3) +#define REG_CFC_MIRROR_PORT_RELMASK (0x00000007) +#define REG_CFC_MIRROR_PORT_MASK (REG_CFC_MIRROR_PORT_RELMASK << REG_CFC_MIRROR_PORT_OFFT) +#define REG_CFC_MIRROR_EN_OFFT (19) +#define REG_CFC_MIRROR_EN_LENG (1) +#define REG_CFC_MIRROR_EN_RELMASK (0x00000001) +#define REG_CFC_MIRROR_EN_MASK (REG_CFC_MIRROR_EN_RELMASK << REG_CFC_MIRROR_EN_OFFT) + +#define REG_ATA1_ADDR (0x0074) +#define REG_ATA2_ADDR (0x0078) + +#define REG_ATWD_ADDR (0x007C) +#define REG_ATWD_STATUS_OFFT (2) +#define REG_ATWD_STATUS_LENG (2) +#define REG_ATWD_STATUS_RELMASK (0x00000003) +#define REG_ATWD_STATUS_MASK (REG_ATWD_STATUS_RELMASK << REG_ATWD_STATUS_OFFT) +#define REG_ATWD_PORT_OFFT (4) +#define REG_ATWD_PORT_LENG (8) +#define REG_ATWD_PORT_RELMASK (0x000000FF) +#define REG_ATWD_PORT_MASK (REG_ATWD_PORT_RELMASK << REG_ATWD_PORT_OFFT) +#define REG_ATWD_LEAKY_EN_OFFT (12) +#define REG_ATWD_LEAKY_EN_LENG (1) +#define REG_ATWD_LEAKY_EN_RELMASK (0x00000001) +#define REG_ATWD_LEAKY_EN_MASK (REG_ATWD_LEAKY_EN_RELMASK << REG_ATWD_LEAKY_EN_OFFT) +#define REG_ATWD_EG_TAG_OFFT (13) +#define REG_ATWD_EG_TAG_LENG (3) +#define REG_ATWD_EG_TAG_RELMASK (0x00000007) +#define REG_ATWD_EG_TAG_MASK (REG_ATWD_EG_TAG_RELMASK << REG_ATWD_EG_TAG_OFFT) +#define REG_ATWD_USR_PRI_OFFT (16) +#define REG_ATWD_USR_PRI_LENG (3) +#define REG_ATWD_USR_PRI_RELMASK (0x00000007) +#define REG_ATWD_USR_PRI_MASK (REG_ATWD_USR_PRI_RELMASK << REG_ATWD_USR_PRI_OFFT) +#define REG_ATWD_SA_MIR_EN_OFFT (19) +#define REG_ATWD_SA_MIR_EN_LENG (1) +#define REG_ATWD_SA_MIR_EN_RELMASK (0x00000001) +#define REG_ATWD_SA_MIR_EN_MASK (REG_ATWD_SA_MIR_EN_RELMASK << REG_ATWD_SA_MIR_EN_OFFT) +#define REG_ATWD_SA_PORT_FW_OFFT (20) +#define REG_ATWD_SA_PORT_FW_LENG (3) +#define REG_ATWD_SA_PORT_FW_RELMASK (0x00000007) +#define REG_ATWD_SA_PORT_FW_MASK (REG_ATWD_SA_PORT_FW_RELMASK << REG_ATWD_SA_PORT_FW_OFFT) + +#define REG_ATC_ADDR (0x0080) +#define REG_ATC_AC_CMD_OFFT (0) +#define REG_ATC_AC_CMD_LENG (3) +#define REG_ATC_AC_CMD_RELMASK (0x00000007) +#define REG_ATC_AC_CMD_MASK (REG_ATC_AC_CMD_RELMASK << REG_ATC_AC_CMD_OFFT) +#define REG_ATC_AC_SAT_OFFT (4) +#define REG_ATC_AC_SAT_LENG (2) +#define REG_ATC_AC_SAT_RELMASK (0x00000003) +#define REG_ATC_AC_SAT_MASK (REG_ATC_AC_SAT_RELMASK << REG_ATC_AC_SAT_OFFT) +#define REG_ATC_AC_MAT_OFFT (8) +#define REG_ATC_AC_MAT_LENG (4) +#define REG_ATC_AC_MAT_RELMASK (0x0000000F) +#define REG_ATC_AC_MAT_MASK (REG_ATC_AC_MAT_RELMASK << REG_ATC_AC_MAT_OFFT) +#define REG_AT_SRCH_HIT_OFFT (13) +#define REG_AT_SRCH_HIT_RELMASK (0x00000001) +#define REG_AT_SRCH_HIT_MASK (REG_AT_SRCH_HIT_RELMASK << REG_AT_SRCH_HIT_OFFT) +#define REG_AT_SRCH_END_OFFT (14) +#define REG_AT_SRCH_END_RELMASK (0x00000001) +#define REG_AT_SRCH_END_MASK (REG_AT_SRCH_END_RELMASK << REG_AT_SRCH_END_OFFT) +#define REG_ATC_BUSY_OFFT (15) +#define REG_ATC_BUSY_LENG (1) +#define REG_ATC_BUSY_RELMASK (0x00000001) +#define REG_ATC_BUSY_MASK (REG_ATC_BUSY_RELMASK << REG_ATC_BUSY_OFFT) +#define REG_AT_ADDR_OFFT (16) +#define REG_AT_ADDR_LENG (12) +#define REG_AT_ADDR_RELMASK (0x00000FFF) +#define REG_AT_ADDR_MASK (REG_AT_ADDR_RELMASK << REG_AT_ADDR_OFFT) + +#define REG_TSRA1_ADDR (0x0084) +#define REG_TSRA2_ADDR (0x0088) +#define REG_ATRD_ADDR (0x008C) + +#define REG_VTCR_ADDR (0x0090) +#define REG_VTCR_VID_OFFT (0) +#define REG_VTCR_VID_LENG (12) +#define REG_VTCR_VID_RELMASK (0x00000FFF) +#define REG_VTCR_VID_MASK (REG_VTCR_VID_RELMASK << REG_VTCR_VID_OFFT) +#define REG_VTCR_FUNC_OFFT (12) +#define REG_VTCR_FUNC_LENG (4) +#define REG_VTCR_FUNC_RELMASK (0x0000000F) +#define REG_VTCR_FUNC_MASK (REG_VTCR_FUNC_RELMASK << REG_VTCR_FUNC_OFFT) +#define REG_VTCR_IDX_INVLD_OFFT (16) +#define REG_VTCR_IDX_INVLD_RELMASK (0x00000001) +#define REG_VTCR_IDX_INVLD_MASK (REG_VTCR_IDX_INVLD_RELMASK << REG_VTCR_IDX_INVLD_OFFT) +#define REG_VTCR_BUSY_OFFT (31) +#define REG_VTCR_BUSY_RELMASK (0x00000001) +#define REG_VTCR_BUSY_MASK (REG_VTCR_BUSY_RELMASK << REG_VTCR_BUSY_OFFT) + +#define REG_VAWD1_ADDR (0x0094) +#define REG_VAWD2_ADDR (0x0098) +#define REG_VLAN_ID_BASE (0x0100) + +#define REG_CPGC_ADDR (0xB0) +#define REG_CPCG_COL_EN_OFFT (0) +#define REG_CPCG_COL_EN_RELMASK (0x00000001) +#define REG_CPCG_COL_EN_MASK (REG_CPCG_COL_EN_RELMASK << REG_CPCG_COL_EN_OFFT) +#define REG_CPCG_COL_CLK_EN_OFFT (1) +#define REG_CPCG_COL_CLK_EN_RELMASK (0x00000001) +#define REG_CPCG_COL_CLK_EN_MASK (REG_CPCG_COL_CLK_EN_RELMASK << REG_CPCG_COL_CLK_EN_OFFT) +#define REG_CPCG_COL_RST_N_OFFT (2) +#define REG_CPCG_COL_RST_N_RELMASK (0x00000001) +#define REG_CPCG_COL_RST_N_MASK (REG_CPCG_COL_RST_N_RELMASK << REG_CPCG_COL_RST_N_OFFT) + +#define REG_GFCCR0_ADDR (0x1FE0) +#define REG_FC_EN_OFFT (31) +#define REG_FC_EN_RELMASK (0x00000001) +#define REG_FC_EN_MASK (REG_FC_EN_RELMASK << REG_FC_EN_OFFT) + +#define REG_PFC_CTRL_ADDR (0x30b0) +#define PFC_RX_COUNTER_L(n) (0x3030 + (n)*0x100) +#define PFC_RX_COUNTER_H(n) (0x3034 + (n)*0x100) +#define PFC_TX_COUNTER_L(n) (0x3040 + (n)*0x100) +#define PFC_TX_COUNTER_H(n) (0x3044 + (n)*0x100) +#define PMSR_P(n) (0x3008 + (n)*0x100) + + +#define REG_SSC_P0_ADDR (0x2000) + +#define REG_PCR_P0_ADDR (0x2004) +#define REG_PCR_VLAN_MIS_OFFT (2) +#define REG_PCR_VLAN_MIS_LENG (1) +#define REG_PCR_VLAN_MIS_RELMASK (0x00000001) +#define REG_PCR_VLAN_MIS_MASK (REG_PCR_VLAN_MIS_RELMASK << REG_PCR_VLAN_MIS_OFFT) +#define REG_PCR_ACL_MIR_OFFT (7) +#define REG_PCR_ACL_MIR_LENG (1) +#define REG_PCR_ACL_MIR_RELMASK (0x00000001) +#define REG_PCR_ACL_MIR_MASK (REG_PCR_ACL_MIR_RELMASK << REG_PCR_ACL_MIR_OFFT) +#define REG_PORT_RX_MIR_OFFT (8) +#define REG_PORT_RX_MIR_LENG (1) +#define REG_PORT_RX_MIR_RELMASK (0x00000001) +#define REG_PORT_RX_MIR_MASK (REG_PORT_RX_MIR_RELMASK << REG_PORT_RX_MIR_OFFT) +#define REG_PORT_TX_MIR_OFFT (9) +#define REG_PORT_TX_MIR_LENG (1) +#define REG_PORT_TX_MIR_RELMASK (0x00000001) +#define REG_PORT_TX_MIR_MASK (REG_PORT_TX_MIR_RELMASK << REG_PORT_TX_MIR_OFFT) +#define REG_PORT_ACL_EN_OFFT (10) +#define REG_PORT_ACL_EN_LENG (1) +#define REG_PORT_ACL_EN_RELMASK (0x00000001) +#define REG_PORT_ACL_EN_MASK (REG_PORT_ACL_EN_RELMASK << REG_PORT_ACL_EN_OFFT) +#define REG_PCR_EG_TAG_OFFT (28) +#define REG_PCR_EG_TAG_LENG (2) +#define REG_PCR_EG_TAG_RELMASK (0x00000003) +#define REG_PCR_EG_TAG_MASK (REG_PCR_EG_TAG_RELMASK << REG_PCR_EG_TAG_OFFT) + +#define REG_PIC_P0_ADDR (0x2008) +#define REG_PIC_IGMP_MIR_OFFT (19) +#define REG_PIC_IGMP_MIR_LENG (1) +#define REG_PIC_IGMP_MIR_RELMASK (0x00000001) +#define REG_PIC_IGMP_MIR_MASK (REG_PIC_IGMP_MIR_RELMASK << REG_PIC_IGMP_MIR_OFFT) + +#define REG_PSC_P0_ADDR (0x200C) + +#define REG_PVC_P0_ADDR (0x2010) +#define REG_PVC_ACC_FRM_OFFT (0) +#define REG_PVC_ACC_FRM_LENG (2) +#define REG_PVC_ACC_FRM_RELMASK (0x00000003) +#define REG_PVC_ACC_FRM_MASK (REG_PVC_ACC_FRM_RELMASK << REG_PVC_ACC_FRM_OFFT) +#define REG_PVC_EG_TAG_OFFT (8) +#define REG_PVC_EG_TAG_LENG (3) +#define REG_PVC_EG_TAG_RELMASK (0x00000007) +#define REG_PVC_EG_TAG_MASK (REG_PVC_EG_TAG_RELMASK << REG_PVC_EG_TAG_OFFT) + +#define REG_PPBV1_P0_ADDR (0x2014) +#define REG_PPBV2_P0_ADDR (0x2018) +#define REG_BSR_P0_ADDR (0x201C) +#define REG_STAG01_P0_ADDR (0x2020) +#define REG_STAG23_P0_ADDR (0x2024) +#define REG_STAG45_P0_ADDR (0x2028) +#define REG_STAG67_P0_ADDR (0x202C) + +#define REG_CMACCR_ADDR (0x30E0) +#define REG_MTCC_LMT_OFFT (9) +#define REG_MTCC_LMT_LENG (4) +#define REG_MTCC_LMT_RELMASK (0x0000000F) +#define REG_MTCC_LMT_MASK (REG_MTCC_LMT_RELMASK << REG_MTCC_LMT_OFFT) + +#define ETHCMD_ENABLE "enable" +#define ETHCMD_DISABLE "disable" + +#define HELP_VLAN_PVID "vlan pvid " + +#if defined(EXTEND_SETVID_PARAM) || defined(SQA_VERIFY) +#define HELP_VLAN_VID "vlan vid \n" \ + " \n" +#else +#define HELP_VLAN_VID "vlan vid \n" +#endif //SQA_VERIFY + +//#if defined(SQA_VERIFY) + +#define MT7530_UPW_REG_UPDATE 1 + +#define HELP_QOS_TYPE "qos type \n" +#ifdef MT7530_UPW_REG_UPDATE +#define HELP_QOS_BASE "qos base \n" +#else +#define HELP_QOS_BASE "qos base \n" +#endif +#define HELP_QOS_PRIO_QMAP "qos prio-qmap \n" +#define HELP_QOS_PRIO_TAGMAP "qos prio-tagmap \n" +#define HELP_QOS_PRIO_DSCPMAP "qos prio-dscpmap \n" +//#define HELP_QOS_VPRI_QMAP "qos vprio-qmap \n" +#define HELP_QOS_PORT_PRIO "qos port-prio \n" +#define HELP_QOS_PORT_WEIGHT "qos port-weight \n" \ + " : the weight of queue n, range: 1~16\n" +#define HELP_QOS_DSCP_PRIO "qos dscp-prio : for ingress\n" + +#define HELP_ARL_L2LEN_CHK "arl l2len-chk \n" + +#define HELP_ARL_AGING "arl aging \n" + +#define HELP_ARL_MAC_TBL_ADD "arl mactbl-add \n"\ + " ** optional : \n" + +#define HELP_ARL_DIP_TBL_ADD "arl diptbl-add \n" + +#define HELP_ARL_SIP_TBL_ADD "arl siptbl-add \n" + +#define HELP_ACL_SETPORTEN "acl enable \n" +#define HELP_ACL_ACL_TBL_ADD "arl acltbl-add \n" +#define HELP_ACL_MASK_TBL_ADD "arl masktbl-add \n" +#define HELP_ACL_RULE_TBL_ADD "arl ruletbl-add \n" +#define HELP_ACL_RATE_TBL_ADD "arl ratetbl-add \n" +#define HELP_ACL_TRTCM_TBL_ADD "arl trTCMtbl-add \n" + + +#define HELP_VLAN_PORT_MODE "vlan port-mode \n" \ + ": 0: port matrix mode\n" \ + " 1: fallback mode\n" \ + " 2: check mode\n" \ + " 3: security mode\n"\ + +#define HELP_VLAN_PORT_ATTR "vlan port-attr \n" \ + ": 0: user port\n" \ + " 1: statck port\n" \ + " 2: translation port\n" \ + " 3: transparent port\n" + +#define HELP_VLAN_EGRESS_TAG_PVC "vlan eg-tag-pvc \n" \ + ": 0: disable\n" \ + " 1: consistent\n" \ + " 2: reserved\n" \ + " 3: reserved\n" \ + " 4: untagged\n" \ + " 5: swap\n" \ + " 6: tagged\n" \ + " 7: stack\n" + +#define HELP_VLAN_EGRESS_TAG_PCR "vlan eg-tag-pcr \n" \ + ": 0: untagged\n" \ + " 1: swap\n" \ + " 2: tagged\n" \ + " 3: stack\n" + +#define HELP_VLAN_ACC_FRM "vlan acc-frm \n" \ + ": 0: admit all frames\n" \ + " 1: admit only vlan-taged frames\n" \ + " 2: admit only untagged or priority-tagged frames\n" \ + " 3: reserved\n" + + +#define HELP_SWITCH_RESET "switch software reset\n" +#define HELP_MACCTL_FC "macctl fc \n" +#define HELP_MIRROR_EN "mirror enable \n" +#define HELP_MIRROR_PORTBASED "mirror port-based \n" + +#define HELP_PHY_AN_EN "phyctl an \n" +#define HELP_PHY_FC_EN "phyctl fc \n" + +#define HELP_STP "stp \n" \ + ": 0: Disable/Discarding\n" \ + " 1: Blocking/Listening/Discarding\n" \ + " 2: Learning\n" \ + " 3: Forwarding\n" +#define HELP_COLLISION_POOL_EN "collision-pool enable [enable 0|1] \n" +#define HELP_EEE_EN "eee [enable|disable] ([port|portMap]) \n" + +//#endif //SQA_VERIFY diff --git a/package/mtk/applications/switch/src/switch_fun.c b/package/mtk/applications/switch/src/switch_fun.c new file mode 100644 index 0000000000..ce9d2bb2c4 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_fun.c @@ -0,0 +1,3769 @@ +/* +* switch_fun.c: switch function sets +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "switch_extend.h" +#include "switch_netlink.h" +#include "switch_ioctl.h" +#include "switch_fun.h" + +#define leaky_bucket 0 + +static int getnext(char *src, int separator, char *dest) +{ + char *c; + int len; + + if ((src == NULL) || (dest == NULL)) + return -1; + + c = strchr(src, separator); + if (c == NULL) + return -1; + + len = c - src; + strncpy(dest, src, len); + dest[len] = '\0'; + return len + 1; +} + +static int str_to_ip(unsigned int *ip, char *str) +{ + int i; + int len; + char *ptr = str; + char buf[128]; + unsigned char c[4]; + + for (i = 0; i < 3; ++i) { + if ((len = getnext(ptr, '.', buf)) == -1) + return 1; + c[i] = atoi(buf); + ptr += len; + } + c[3] = atoi(ptr); + *ip = (c[0] << 24) + (c[1] << 16) + (c[2] << 8) + c[3]; + return 0; +} + +/*convert IP address from number to string */ +static void ip_to_str(char *str, unsigned int ip) +{ + unsigned char *ptr = (unsigned char *)&ip; + unsigned char c[4]; + + c[0] = *(ptr); + c[1] = *(ptr + 1); + c[2] = *(ptr + 2); + c[3] = *(ptr + 3); + /*sprintf(str, "%d.%d.%d.%d", c[0], c[1], c[2], c[3]);*/ + sprintf(str, "%d.%d.%d.%d", c[3], c[2], c[1], c[0]); +} + +int reg_read(unsigned int offset, unsigned int *value) +{ + int ret = -1; + + if (nl_init_flag == true) { + ret = reg_read_netlink(attres, offset, value); + } else { + if (attres->dev_id == -1) + ret = reg_read_ioctl(offset, value); + } + if (ret < 0) { + printf("Read fail\n"); + *value = 0; + return ret; + } + + return 0; +} + +int reg_write(unsigned int offset, unsigned int value) +{ + int ret = -1; + + if (nl_init_flag == true) { + ret = reg_write_netlink(attres, offset, value); + } else { + if (attres->dev_id == -1) + ret = reg_write_ioctl(offset, value); + } + if (ret < 0) { + printf("Write fail\n"); + exit_free(); + exit(0); + } + return 0; +} + +int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value) +{ + int ret; + + if (port_num > 31) { + printf("Invalid Port or PHY addr \n"); + return -1; + } + + if (nl_init_flag == true) + ret = phy_cl22_read_netlink(attres, port_num, reg, value); + else + ret = mii_mgr_cl22_read_ioctl(port_num, reg, value); + + if (ret < 0) { + printf("Phy cl22 read fail\n"); + exit_free(); + exit(0); + } + + return 0; +} + +int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value) +{ + int ret; + + if (port_num > 31) { + printf("Invalid Port or PHY addr \n"); + return -1; + } + + if (nl_init_flag == true) + ret = phy_cl22_write_netlink(attres, port_num, reg, value); + else + ret = mii_mgr_cl22_write_ioctl(port_num, reg, value); + + if (ret < 0) { + printf("Phy cl22 write fail\n"); + exit_free(); + exit(0); + } + + return 0; +} + +int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value) +{ + int ret; + + if (port_num > 31) { + printf("Invalid Port or PHY addr \n"); + return -1; + } + + if (nl_init_flag == true) + ret = phy_cl45_read_netlink(attres, port_num, dev, reg, value); + else + ret = mii_mgr_cl45_read_ioctl(port_num, dev, reg, value); + + if (ret < 0) { + printf("Phy cl45 read fail\n"); + exit_free(); + exit(0); + } + + return 0; +} + +int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value) +{ + int ret; + + if (port_num > 31) { + printf("Invalid Port or PHY addr \n"); + return -1; + } + + if (nl_init_flag == true) + ret = phy_cl45_write_netlink(attres, port_num, dev, reg, value); + else + ret = mii_mgr_cl45_write_ioctl(port_num, dev, reg, value); + + if (ret < 0) { + printf("Phy cl45 write fail\n"); + exit_free(); + exit(0); + } + + return 0; +} + + +int phy_dump(int phy_addr) +{ + int ret; + + if (nl_init_flag == true) + ret = phy_dump_netlink(attres, phy_addr); + else + ret = phy_dump_ioctl(phy_addr); + + if (ret < 0) { + printf("Phy dump fail\n"); + exit_free(); + exit(0); + } + + return 0; +} + +void phy_crossover(int argc, char *argv[]) +{ + unsigned int port_num = strtoul(argv[2], NULL, 10); + unsigned int value; + int ret; + + if (port_num > 4) { + printf("invaild value, port_name:0~4\n"); + return; + } + + if (nl_init_flag == true) + ret = phy_cl45_read_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value); + else + ret = mii_mgr_cl45_read_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, &value); + if (ret < 0) { + printf("phy_cl45 read fail\n"); + exit_free(); + exit(0); + } + + printf("mii_mgr_cl45:"); + printf("Read: port#=%d, device=0x%x, reg=0x%x, value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value); + + if (!strncmp(argv[3], "auto", 5)) + { + value &= (~(0x3 << 3)); + } else if (!strncmp(argv[3], "mdi", 4)) { + value &= (~(0x3 << 3)); + value |= (0x2 << 3); + } else if (!strncmp(argv[3], "mdix", 5)) { + value |= (0x3 << 3); + } else { + printf("invaild parameter\n"); + return; + } + printf("Write: port#=%d, device=0x%x, reg=0x%x. value=0x%x\n", port_num, 0x1E, MT7530_T10_TEST_CONTROL, value); + + if (nl_init_flag == true) + ret = phy_cl45_write_netlink(attres, port_num, 0x1E, MT7530_T10_TEST_CONTROL, value); + else + ret = mii_mgr_cl45_write_ioctl(port_num, 0x1E, MT7530_T10_TEST_CONTROL, value); + + if (ret < 0) { + printf("phy_cl45 write fail\n"); + exit_free(); + exit(0); + } +} + +int rw_phy_token_ring(int argc, char *argv[]) +{ + int ch_addr, node_addr, data_addr; + unsigned int tr_reg_control; + unsigned int val_l = 0; + unsigned int val_h = 0; + unsigned int port_num; + + if (argc < 4) + return -1; + + if (argv[2][0] == 'r') { + if (argc != 7) + return -1; + mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5 + port_num = strtoul(argv[3], NULL, 0); + if (port_num > MAX_PORT) { + printf("Illegal port index and port:0~6\n"); + return -1; + } + ch_addr = strtoul(argv[4], NULL, 0); + node_addr = strtoul(argv[5], NULL, 0); + data_addr = strtoul(argv[6], NULL, 0); + printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr); + tr_reg_control = (1 << 15) | (1 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1); + mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control + mii_mgr_read(port_num, 17, &val_l); + mii_mgr_read(port_num, 18, &val_h); + printf("switch trreg read tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l); + } else if (argv[2][0] == 'w') { + if (argc != 9) + return -1; + mii_mgr_write(0, 0x1f, 0x52b5); // r31 = 0x52b5 + port_num = strtoul(argv[3], NULL, 0); + if (port_num > MAX_PORT) { + printf("\n**Illegal port index and port:0~6\n"); + return -1; + } + ch_addr = strtoul(argv[4], NULL, 0); + node_addr = strtoul(argv[5], NULL, 0); + data_addr = strtoul(argv[6], NULL, 0); + val_h = strtoul(argv[7], NULL, 0); + val_l = strtoul(argv[8], NULL, 0); + printf("port = %x, ch_addr = %x, node_addr=%x, data_addr=%x\n", port_num, ch_addr, node_addr, data_addr); + tr_reg_control = (1 << 15) | (0 << 13) | (ch_addr << 11) | (node_addr << 7) | (data_addr << 1); + mii_mgr_write(port_num, 17, val_l); + mii_mgr_write(port_num, 18, val_h); + mii_mgr_write(port_num, 16, tr_reg_control); // r16 = tr_reg_control + printf("switch trreg Write tr_reg_control=%x, value_H=%x, value_L=%x\n", tr_reg_control, val_h, val_l); + } else + return -1; + return 0; +} + +void write_acl_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2) +{ + unsigned int value, reg; + unsigned int max_index; + + if (chip_name == 0x7531 || chip_name == 0x7988) + max_index = 256; + else + max_index = 64; + + printf("Pattern_acl_tbl_idx:%d\n", tbl_idx); + + if (tbl_idx >= max_index) { + printf(HELP_ACL_ACL_TBL_ADD); + return; + } + + reg = REG_VTCR_ADDR; + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) { + break; + } + } + reg_write(REG_VAWD1_ADDR, vawd1); + printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1); + reg_write(REG_VAWD2_ADDR, vawd2); + printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2); + reg = REG_VTCR_ADDR; + value = REG_VTCR_BUSY_MASK | (0x05 << REG_VTCR_FUNC_OFFT) | tbl_idx; + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } +} + +void acl_table_add(int argc, char *argv[]) +{ + unsigned int vawd1, vawd2; + unsigned char tbl_idx; + + tbl_idx = atoi(argv[3]); + vawd1 = strtoul(argv[4], (char **)NULL, 16); + vawd2 = strtoul(argv[5], (char **)NULL, 16); + write_acl_table(tbl_idx, vawd1, vawd2); +} + +void write_acl_mask_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2) +{ + unsigned int value, reg; + unsigned int max_index; + + if (chip_name == 0x7531 || chip_name == 0x7988) + max_index = 128; + else + max_index = 32; + + printf("Rule_mask_tbl_idx:%d\n", tbl_idx); + + if (tbl_idx >= max_index) { + printf(HELP_ACL_MASK_TBL_ADD); + return; + } + reg = REG_VTCR_ADDR; + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } + reg_write(REG_VAWD1_ADDR, vawd1); + printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1); + reg_write(REG_VAWD2_ADDR, vawd2); + printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2); + reg = REG_VTCR_ADDR; + value = REG_VTCR_BUSY_MASK | (0x09 << REG_VTCR_FUNC_OFFT) | tbl_idx; + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } +} + +void acl_mask_table_add(int argc, char *argv[]) +{ + unsigned int vawd1, vawd2; + unsigned char tbl_idx; + + tbl_idx = atoi(argv[3]); + vawd1 = strtoul(argv[4], (char **)NULL, 16); + vawd2 = strtoul(argv[5], (char **)NULL, 16); + write_acl_mask_table(tbl_idx, vawd1, vawd2); +} + +void write_acl_rule_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2) +{ + unsigned int value, reg; + unsigned int max_index; + + if (chip_name == 0x7531 || chip_name == 0x7988) + max_index = 128; + else + max_index = 32; + + printf("Rule_control_tbl_idx:%d\n", tbl_idx); + + if (tbl_idx >= max_index) { /*Check the input parameters is right or not.*/ + printf(HELP_ACL_RULE_TBL_ADD); + return; + } + reg = REG_VTCR_ADDR; + + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) { + break; + } + } + reg_write(REG_VAWD1_ADDR, vawd1); + printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1); + reg_write(REG_VAWD2_ADDR, vawd2); + printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2); + reg = REG_VTCR_ADDR; + value = REG_VTCR_BUSY_MASK | (0x0B << REG_VTCR_FUNC_OFFT) | tbl_idx; + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + + while (1) + { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) { + break; + } + } +} + +void acl_rule_table_add(int argc, char *argv[]) +{ + unsigned int vawd1, vawd2; + unsigned char tbl_idx; + + tbl_idx = atoi(argv[3]); + vawd1 = strtoul(argv[4], (char **)NULL, 16); + vawd2 = strtoul(argv[5], (char **)NULL, 16); + write_acl_rule_table(tbl_idx, vawd1, vawd2); +} + +void write_rate_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2) +{ + unsigned int value, reg; + unsigned int max_index = 32; + + printf("Rule_action_tbl_idx:%d\n", tbl_idx); + + if (tbl_idx >= max_index) { + printf(HELP_ACL_RATE_TBL_ADD); + return; + } + + reg = REG_VTCR_ADDR; + while (1) { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } + + reg_write(REG_VAWD1_ADDR, vawd1); + printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1); + reg_write(REG_VAWD2_ADDR, vawd2); + printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2); + reg = REG_VTCR_ADDR; + value = REG_VTCR_BUSY_MASK | (0x0D << REG_VTCR_FUNC_OFFT) | tbl_idx; + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + + while (1) { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } +} + +void acl_rate_table_add(int argc, char *argv[]) +{ + unsigned int vawd1, vawd2; + unsigned char tbl_idx; + + tbl_idx = atoi(argv[3]); + vawd1 = strtoul(argv[4], (char **)NULL, 16); + vawd2 = strtoul(argv[5], (char **)NULL, 16); + + write_rate_table(tbl_idx, vawd1, vawd2); +} + +void write_trTCM_table(unsigned char tbl_idx, unsigned int vawd1, unsigned int vawd2) +{ + unsigned int value, reg; + unsigned int max_index = 32; + + printf("trTCM_tbl_idx:%d\n", tbl_idx); + + if (tbl_idx >= max_index) { + printf(HELP_ACL_TRTCM_TBL_ADD); + return; + } + + reg = REG_VTCR_ADDR; + while (1) { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } + + reg_write(REG_VAWD1_ADDR, vawd1); + printf("write reg: %x, value: %x\n", REG_VAWD1_ADDR, vawd1); + reg_write(REG_VAWD2_ADDR, vawd2); + printf("write reg: %x, value: %x\n", REG_VAWD2_ADDR, vawd2); + reg = REG_VTCR_ADDR; + value = REG_VTCR_BUSY_MASK | (0x07 << REG_VTCR_FUNC_OFFT) | tbl_idx; + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + + while (1) { // wait until not busy + reg_read(reg, &value); + if ((value & REG_VTCR_BUSY_MASK) == 0) + break; + } +} + +int acl_parameters_pre_del(int len1, int len2, int argc, char *argv[], int *port) +{ + int i; + + *port = 0; + if (argc < len1) { + printf("insufficient arguments!\n"); + return -1; + } + + if (len2 == 12) + { + if (!argv[4] || strlen(argv[4]) != len2) { + printf("The [%s] format error, should be of length %d\n",argv[4], len2); + return -1; + } + } + + if (!argv[5] || strlen(argv[5]) != 8) { + printf("portsmap format error, should be of length 7\n"); + return -1; + } + + for (i = 0; i < 7; i++) { + if (argv[5][i] != '0' && argv[5][i] != '1') { + printf("portmap format error, should be of combination of 0 or 1\n"); + return -1; + } + *port += (argv[5][i] - '0') * (1 << i); + } + return 0; +} + +void acl_compare_pattern(int ports, int comparion, int base, int word, unsigned char table_index) +{ + unsigned int value; + + comparion |= 0xffff0000; //compare mask + + value = ports << 8; //w_port_map + value |= 0x1 << 19; //enable + value |= base << 16; //mac header + value |= word << 1; //word offset + + write_acl_table(table_index, comparion, value); +} + +void acl_mac_add(int argc, char *argv[]) +{ + unsigned int value; + int ports; + char tmpstr[5]; + int ret; + + ret = acl_parameters_pre_del(6, 12, argc, argv, &ports); + if (ret < 0) + return; + //set pattern + strncpy(tmpstr, argv[4], 4); + tmpstr[4] = '\0'; + value = strtoul(tmpstr, NULL, 16); + acl_compare_pattern(ports, value, 0x0, 0, 0); + + strncpy(tmpstr, argv[4] + 4, 4); + tmpstr[4] = '\0'; + value = strtoul(tmpstr, NULL, 16); + acl_compare_pattern(ports, value, 0x0, 1, 1); + + strncpy(tmpstr, argv[4] + 8, 4); + tmpstr[4] = '\0'; + value = strtoul(tmpstr, NULL, 16); + acl_compare_pattern(ports, value, 0x0, 2, 2); + + //set mask + write_acl_mask_table(0,0x7,0); + + //set action + value = 0x7; //drop + value |= 1 << 28; //acl intterupt enable + value |= 1 << 27; //acl hit count + value |= 2 << 24; //acl hit count group index (0~3) + write_acl_rule_table(0,value,0); +} + +void acl_dip_meter(int argc, char *argv[]) +{ + unsigned int value, ip_value, meter; + int ports; + int ret; + + ip_value = 0; + ret = acl_parameters_pre_del(7, -1, argc, argv, &ports); + if (ret < 0) + return; + + str_to_ip(&ip_value, argv[4]); + //set pattern + value = (ip_value >> 16); + acl_compare_pattern(ports, value, 0x2, 0x8, 0); + + //set pattern + value = (ip_value & 0xffff); + acl_compare_pattern(ports, value, 0x2, 0x9, 1); + + //set mask + write_acl_mask_table(0,0x3,0); + + //set action + meter = strtoul(argv[6], NULL, 0); + if (((chip_name == 0x7530) && (meter > 1000000)) || + ((chip_name == 0x7531) && (meter > 2500000)) || + ((chip_name == 0x7988) && (meter > 4000000))) { + printf("\n**Illegal meter input, and 7530: 0~1000000Kpbs, 7531: 0~2500000Kpbs, 7988: 0~4000000Kpbs**\n"); + return; + } + if (((chip_name == 0x7531 || chip_name == 0x7988) && (meter > 1000000))) { + reg_read(0xc,&value); + value |= 0x1 << 30; + reg_write(0xC,value); + printf("AGC: 0x%x\n",value); + value = meter / 1000; //uint is 1Mbps + } else { + reg_read(0xc,&value); + value &= ~(0x1 << 30); + reg_write(0xC,value); + printf("AGC: 0x%x\n",value); + value = meter >> 6; //uint is 64Kbps + } + value |= 0x1 << 15; //enable rate control + printf("Acl rate control:0x%x\n",value); + write_rate_table(0, value, 0); +} + +void acl_dip_trtcm(int argc, char *argv[]) +{ + unsigned int value, value2, ip_value; + unsigned int CIR, CBS, PIR, PBS; + int ports; + int ret; + + ip_value = 0; + ret = acl_parameters_pre_del(10, -1, argc, argv, &ports); + if (ret < 0) + return; + + str_to_ip(&ip_value, argv[4]); + //set pattern + value = (ip_value >> 16); + acl_compare_pattern(ports, value, 0x2, 0x8, 0); + + //set pattern + value = (ip_value & 0xffff); + acl_compare_pattern(ports, value, 0x2, 0x9, 1); + + //set CBS PBS + CIR = strtoul(argv[6], NULL, 0); + CBS = strtoul(argv[7], NULL, 0); + PIR = strtoul(argv[8], NULL, 0); + PBS = strtoul(argv[9], NULL, 0); + + if (CIR > 65535*64 || CBS > 65535 || PIR > 65535*64 || PBS > 65535) { + printf("\n**Illegal input parameters**\n"); + return; + } + + value = CBS << 16; //bit16~31 + value |= PBS; //bit0~15 + //value |= 1;//valid + CIR = CIR >> 6; + PIR = PIR >> 6; + + value2 = CIR << 16; //bit16~31 + value2 |= PIR; //bit0~15 + write_trTCM_table(0,value,value2); + + //set pattern + write_acl_mask_table(0,0x3,0); + + //set action + value = 0x1 << (11 + 1); //TrTCM green meter#0 Low drop + value |= 0x2 << (8 + 1); //TrTCM yellow meter#0 Med drop + value |= 0x3 << (5 + 1); //TrTCM red meter#0 Hig drop + value |= 0x1 << 0; //TrTCM drop pcd select + write_acl_rule_table(0,0,value); +} + +void acl_ethertype(int argc, char *argv[]) +{ + unsigned int value, ethertype; + int ports; + int ret; + + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + printf("ports:0x%x\n",ports); + ethertype = strtoul(argv[4], NULL, 16); + //set pattern + value = ethertype; + acl_compare_pattern(ports, value, 0x0, 0x6, 0); + + //set pattern + write_acl_mask_table(0,0x1,0); + + //set action(drop) + value = 0x7; //default. Nodrop + value |= 1 << 28; //acl intterupt enable + value |= 1 << 27; //acl hit count + + write_acl_rule_table(0,value,0); +} + +void acl_dip_modify(int argc, char *argv[]) +{ + unsigned int value, ip_value; + int ports; + int priority; + int ret; + + ip_value = 0; + priority = strtoul(argv[6], NULL, 16); + if (priority < 0 || priority > 7) { + printf("\n**Illegal priority value!**\n"); + return; + } + + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + + str_to_ip(&ip_value, argv[4]); + //set pattern + value = (ip_value >> 16); + acl_compare_pattern(ports, value, 0x2, 0x8, 0); + + //set pattern + value = (ip_value & 0xffff); + acl_compare_pattern(ports, value, 0x2, 0x9, 1); + + //set pattern + write_acl_mask_table(0,0x3,0); + + //set action + value = 0x0; //default. Nodrop + value |= 1 << 28; //acl intterupt enable + value |= 1 << 27; //acl hit count + value |= priority << 4; //acl UP + write_acl_rule_table(0,value,0); +} + +void acl_dip_pppoe(int argc, char *argv[]) +{ + unsigned int value, ip_value; + int ports; + int ret; + + ip_value = 0; + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + + str_to_ip(&ip_value, argv[4]); + //set pattern + value = (ip_value >> 16); + acl_compare_pattern(ports, value, 0x2, 0x8, 0); + + //set pattern + value = (ip_value & 0xffff); + acl_compare_pattern(ports, value, 0x2, 0x9, 1); + + //set pattern + write_acl_mask_table(0,0x3,0); + + //set action + value = 0x0; //default. Nodrop + value |= 1 << 28; //acl intterupt enable + value |= 1 << 27; //acl hit count + value |= 1 << 20; //pppoe header remove + value |= 1 << 21; //SA MAC SWAP + value |= 1 << 22; //DA MAC SWAP + write_acl_rule_table(0,value,7); +} + +void acl_dip_add(int argc, char *argv[]) +{ + unsigned int value, ip_value; + int ports; + int ret; + + ip_value = 0; + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + + str_to_ip(&ip_value, argv[4]); + //set pattern + value = (ip_value >> 16); + acl_compare_pattern(ports, value, 0x2, 0x8, 0); + + //set pattern + value = (ip_value & 0xffff); + acl_compare_pattern(ports, value, 0x2, 0x9, 1); + + //set pattern + write_acl_mask_table(0,0x3,0); + + //set action + //value = 0x0; //default + value = 0x7; //drop + value |= 1 << 28; //acl intterupt enable + value |= 1 << 27; //acl hit count + value |= 2 << 24; //acl hit count group index (0~3) + write_acl_rule_table(0,value,0); +} + +void acl_l4_add(int argc, char *argv[]) +{ + unsigned int value; + int ports; + int ret; + + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + + //set pattern + value = strtoul(argv[4], NULL, 16); + acl_compare_pattern(ports, value, 0x5, 0x0, 0); + + //set rue mask + write_acl_mask_table(0,0x1,0); + //set action + value = 0x7; //drop + //value |= 1;//valid + write_acl_rule_table(0,value,0); +} + +void acl_sp_add(int argc, char *argv[]) +{ + unsigned int value; + int ports; + int ret; + + ret = acl_parameters_pre_del(6, -1, argc, argv, &ports); + if (ret < 0) + return; + //set pattern + value = strtoul(argv[4], NULL, 0); + acl_compare_pattern(ports, value, 0x4, 0x0, 0); + + //set rue mask + write_acl_mask_table(0,0x1,0); + + //set action + value = 0x7; //drop + //value |= 1;//valid + write_acl_rule_table(0,value,0); +} + +void acl_port_enable(int argc, char *argv[]) +{ + unsigned int value, reg; + unsigned char acl_port, acl_en; + + acl_port = atoi(argv[3]); + acl_en = atoi(argv[4]); + + printf("acl_port:%d, acl_en:%d\n", acl_port, acl_en); + + /*Check the input parameters is right or not.*/ + if ((acl_port > SWITCH_MAX_PORT) || (acl_en > 1)) { + printf(HELP_ACL_SETPORTEN); + return; + } + + reg = REG_PCR_P0_ADDR + (0x100 * acl_port); // 0x2004[10] + reg_read(reg, &value); + value &= (~REG_PORT_ACL_EN_MASK); + value |= (acl_en << REG_PORT_ACL_EN_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} + +static void dip_dump_internal(int type) +{ + unsigned int i, j, value, mac, mac2, value2; + char tmpstr[16]; + int table_size = 0; + int hit_value1 = 0; + int hit_value2 = 0; + + if(type == GENERAL_TABLE) { + table_size = 0x800; + reg_write(REG_ATC_ADDR, 0x8104); //dip search command + } else { + table_size = 0x40; + reg_write(REG_ATC_ADDR, 0x811c); //dip search command + } + printf("hash port(0:6) rsp_cnt flag timer dip-address ATRD\n"); + for (i = 0; i < table_size; i++) { + while (1) + { + reg_read(REG_ATC_ADDR, &value); + if(type == GENERAL_TABLE) { + hit_value1 = value & (0x1 << 13); + hit_value2 = 1; + }else { + hit_value1 = value & (0x1 << 13); + hit_value2 = value & (0x1 << 28); + } + + if (hit_value1 && hit_value2 ) { //search_rdy + reg_read(REG_ATRD_ADDR, &value2); + //printf("REG_ATRD_ADDR=0x%x\n\r",value2); + + printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu + j = (value2 >> 4) & 0xff; //r_port_map + printf("%c", (j & 0x01) ? '1' : '-'); + printf("%c", (j & 0x02) ? '1' : '-'); + printf("%c", (j & 0x04) ? '1' : '-'); + printf("%c ", (j & 0x08) ? '1' : '-'); + printf("%c", (j & 0x10) ? '1' : '-'); + printf("%c", (j & 0x20) ? '1' : '-'); + printf("%c", (j & 0x40) ? '1' : '-'); + + reg_read(REG_TSRA2_ADDR, &mac2); + + printf(" 0x%4x", (mac2 & 0xffff)); //RESP_CNT + printf(" 0x%2x", ((mac2 >> 16) & 0xff)); //RESP_FLAG + printf(" %3d", ((mac2 >> 24) & 0xff)); //RESP_TIMER + //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field + reg_read(REG_TSRA1_ADDR, &mac); + ip_to_str(tmpstr, mac); + printf(" %s", tmpstr); + printf(" 0x%8x\n", value2); //ATRD + //printf("%04x", ((mac2 >> 16) & 0xffff)); + //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-'); + if (value & 0x4000) { + printf("end of table %d\n", i); + return; + } + break; + } + else if (value & 0x4000) { //at_table_end + printf("found the last entry %d (not ready)\n", i); + return; + } + usleep(5000); + } + + if(type == GENERAL_TABLE) + reg_write(REG_ATC_ADDR, 0x8105); //search for next dip address + else + reg_write(REG_ATC_ADDR, 0x811d); //search for next dip address + usleep(5000); + } +} + +void dip_dump(void) +{ + dip_dump_internal(GENERAL_TABLE); + +} + +void dip_add(int argc, char *argv[]) +{ + unsigned int value = 0; + unsigned int i, j; + + value = 0; + + str_to_ip(&value, argv[3]); + + reg_write(REG_ATA1_ADDR, value); + printf("REG_ATA1_ADDR is 0x%x\n\r", value); + +#if 0 + reg_write(REG_ATA2_ADDR, value); + printf("REG_ATA2_ADDR is 0x%x\n\r", value); +#endif + if (!argv[4] || strlen(argv[4]) != 8) { + printf("portmap format error, should be of length 7\n"); + return; + } + j = 0; + for (i = 0; i < 7; i++) { + if (argv[4][i] != '0' && argv[4][i] != '1') { + printf("portmap format error, should be of combination of 0 or 1\n"); + return; + } + j += (argv[4][i] - '0') * (1 << i); + } + value = j << 4; //w_port_map + value |= (0x3 << 2); //static + + reg_write(REG_ATWD_ADDR, value); + + usleep(5000); + reg_read(REG_ATWD_ADDR, &value); + printf("REG_ATWD_ADDR is 0x%x\n\r", value); + + value = 0x8011; //single w_dip_cmd + reg_write(REG_ATC_ADDR, value); + + usleep(1000); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void dip_del(int argc, char *argv[]) +{ + unsigned int i, value; + + value = 0; + str_to_ip(&value, argv[3]); + + reg_write(REG_ATA1_ADDR, value); + + value = 0; + reg_write(REG_ATA2_ADDR, value); + + value = 0; //STATUS=0, delete dip + reg_write(REG_ATWD_ADDR, value); + + value = 0x8011; //w_dip_cmd + reg_write(REG_ATC_ADDR, value); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + if (argv[1] != NULL) + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void dip_clear(void) +{ + + unsigned int value; + + reg_write(REG_ATC_ADDR, 0x8102); //clear all dip + usleep(5000); + reg_read(REG_ATC_ADDR, &value); + printf("REG_ATC_ADDR is 0x%x\n\r", value); +} + +static void sip_dump_internal(int type) +{ + unsigned int i, j, value, mac, mac2, value2; + int table_size = 0; + int hit_value1 = 0; + int hit_value2 = 0; + char tmpstr[16]; + + if (type == GENERAL_TABLE) { + table_size = 0x800; + reg_write(REG_ATC_ADDR, 0x8204); //sip search command + }else { + table_size = 0x40; + reg_write(REG_ATC_ADDR, 0x822c); //sip search command + } + printf("hash port(0:6) dip-address sip-address ATRD\n"); + for (i = 0; i < table_size; i++) { + while (1) + { + reg_read(REG_ATC_ADDR, &value); + if(type == GENERAL_TABLE) { + hit_value1 = value & (0x1 << 13); + hit_value2 = 1; + } else { + hit_value1 = value & (0x1 << 13); + hit_value2 = value & (0x1 << 28); + } + + if (hit_value1 && hit_value2) { //search_rdy + reg_read(REG_ATRD_ADDR, &value2); + //printf("REG_ATRD_ADDR=0x%x\n\r",value2); + + printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu + j = (value2 >> 4) & 0xff; //r_port_map + printf("%c", (j & 0x01) ? '1' : '-'); + printf("%c", (j & 0x02) ? '1' : '-'); + printf("%c", (j & 0x04) ? '1' : '-'); + printf("%c", (j & 0x08) ? '1' : '-'); + printf(" %c", (j & 0x10) ? '1' : '-'); + printf("%c", (j & 0x20) ? '1' : '-'); + printf("%c", (j & 0x40) ? '1' : '-'); + + reg_read(REG_TSRA2_ADDR, &mac2); + + ip_to_str(tmpstr, mac2); + printf(" %s", tmpstr); + + //printf(" %4d", (value2 >> 24) & 0xff); //r_age_field + reg_read(REG_TSRA1_ADDR, &mac); + ip_to_str(tmpstr, mac); + printf(" %s", tmpstr); + printf(" 0x%x\n", value2); + //printf("%04x", ((mac2 >> 16) & 0xffff)); + //printf(" %c\n", (((value2 >> 20) & 0x03)== 0x03)? 'y':'-'); + if (value & 0x4000) { + printf("end of table %d\n", i); + return; + } + break; + } else if (value & 0x4000) { //at_table_end + printf("found the last entry %d (not ready)\n", i); + return; + } + usleep(5000); + } + + if(type == GENERAL_TABLE) + reg_write(REG_ATC_ADDR, 0x8205); //search for next sip address + else + reg_write(REG_ATC_ADDR, 0x822d); //search for next sip address + usleep(5000); + } +} + +void sip_dump(void) +{ + + sip_dump_internal(GENERAL_TABLE); + +} + + +void sip_add(int argc, char *argv[]) +{ + unsigned int i, j, value; + + value = 0; + str_to_ip(&value, argv[3]); //SIP + + reg_write(REG_ATA2_ADDR, value); + printf("REG_ATA2_ADDR is 0x%x\n\r", value); + + value = 0; + + str_to_ip(&value, argv[4]); //DIP + reg_write(REG_ATA1_ADDR, value); + printf("REG_ATA1_ADDR is 0x%x\n\r", value); + + if (!argv[5] || strlen(argv[5]) != 8) { + printf("portmap format error, should be of length 7\n"); + return; + } + j = 0; + for (i = 0; i < 7; i++) { + if (argv[5][i] != '0' && argv[5][i] != '1') { + printf("portmap format error, should be of combination of 0 or 1\n"); + return; + } + j += (argv[5][i] - '0') * (1 << i); + } + value = j << 4; //w_port_map + value |= (0x3 << 2); //static + + reg_write(REG_ATWD_ADDR, value); + + usleep(5000); + reg_read(REG_ATWD_ADDR, &value); + printf("REG_ATWD_ADDR is 0x%x\n\r", value); + + value = 0x8021; //single w_sip_cmd + reg_write(REG_ATC_ADDR, value); + + usleep(1000); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void sip_del(int argc, char *argv[]) +{ + unsigned int i, value; + + value = 0; + str_to_ip(&value, argv[3]); + + reg_write(REG_ATA2_ADDR, value); //SIP + + str_to_ip(&value, argv[4]); + reg_write(REG_ATA1_ADDR, value); //DIP + + value = 0; //STATUS=0, delete sip + reg_write(REG_ATWD_ADDR, value); + + value = 0x8021; //w_sip_cmd + reg_write(REG_ATC_ADDR, value); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + if (argv[1] != NULL) + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void sip_clear(void) +{ + unsigned int value; + + reg_write(REG_ATC_ADDR, 0x8202); //clear all sip + usleep(5000); + reg_read(REG_ATC_ADDR, &value); + printf("REG_ATC_ADDR is 0x%x\n\r", value); +} + +static void table_dump_internal(int type) +{ + unsigned int i, j, value, mac, mac2, value2; + int table_size = 0; + int table_end = 0; + int hit_value1 = 0; + int hit_value2 = 0; + + if (type == GENERAL_TABLE){ + table_size = 0x800; + table_end = 0x7FF; + reg_write(REG_ATC_ADDR, 0x8004); + } else { + table_size = 0x40; + table_end = 0x3F; + reg_write(REG_ATC_ADDR, 0x800C); + } + printf("hash port(0:6) fid vid age(s) mac-address filter my_mac\n"); + for (i = 0; i < table_size; i++) { + while (1) + { + reg_read(REG_ATC_ADDR, &value); + //printf("ATC = 0x%x\n", value); + if(type == GENERAL_TABLE) { + hit_value1 = value & (0x1 << 13); + hit_value2 = 1; + } else { + hit_value1 = value & (0x1 << 13); + hit_value2 = value & (0x1 << 28); + } + + if (hit_value1 && hit_value2 && (((value >> 15) & 0x1) == 0)) { + printf("%03x: ", (value >> 16) & 0xfff); + reg_read(REG_ATRD_ADDR, &value2); + j = (value2 >> 4) & 0xff; //r_port_map + printf("%c", (j & 0x01) ? '1' : '-'); + printf("%c", (j & 0x02) ? '1' : '-'); + printf("%c", (j & 0x04) ? '1' : '-'); + printf("%c", (j & 0x08) ? '1' : '-'); + printf("%c", (j & 0x10) ? '1' : '-'); + printf("%c", (j & 0x20) ? '1' : '-'); + printf("%c", (j & 0x40) ? '1' : '-'); + printf("%c", (j & 0x80) ? '1' : '-'); + + reg_read(REG_TSRA2_ADDR, &mac2); + + printf(" %2d", (mac2 >> 12) & 0x7); //FID + printf(" %4d", (mac2 & 0xfff)); + if (((value2 >> 24) & 0xff) == 0xFF) + printf(" --- "); //r_age_field:static + else + printf(" %5d ", (((value2 >> 24) & 0xff)+1)*2); //r_age_field + reg_read(REG_TSRA1_ADDR, &mac); + printf(" %08x", mac); + printf("%04x", ((mac2 >> 16) & 0xffff)); + printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-'); + printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-'); + if ((value & 0x4000) && (((value >> 16) & 0xfff) == table_end)) { + printf("end of table %d\n", i); + return; + } + break; + } + else if ((value & 0x4000) && (((value >> 15) & 0x1) == 0) && (((value >> 16) & 0xfff) == table_end)) { //at_table_end + printf("found the last entry %d (not ready)\n", i); + return; + } + else + usleep(5); + } + + if(type == GENERAL_TABLE) + reg_write(REG_ATC_ADDR, 0x8005);//search for next address + else + reg_write(REG_ATC_ADDR, 0x800d);//search for next address + usleep(5); + } +} + +void table_dump(void) +{ + table_dump_internal(GENERAL_TABLE); + +} + + +void table_add(int argc, char *argv[]) +{ + unsigned int i, j, value, is_filter, is_mymac; + char tmpstr[9]; + + is_filter = (argv[1][0] == 'f') ? 1 : 0; + is_mymac = (argv[1][0] == 'm') ? 1 : 0; + if (!argv[2] || strlen(argv[2]) != 12) { + printf("MAC address format error, should be of length 12\n"); + return; + } + strncpy(tmpstr, argv[2], 8); + tmpstr[8] = '\0'; + value = strtoul(tmpstr, NULL, 16); + reg_write(REG_ATA1_ADDR, value); + printf("REG_ATA1_ADDR is 0x%x\n\r", value); + + strncpy(tmpstr, argv[2] + 8, 4); + tmpstr[4] = '\0'; + + value = strtoul(tmpstr, NULL, 16); + value = (value << 16); + value |= (1 << 15); //IVL=1 + + if (argc > 4) { + j = strtoul(argv[4], NULL, 0); + if (4095 < j) { + printf("wrong vid range, should be within 0~4095\n"); + return; + } + value |= j; //vid + } + + reg_write(REG_ATA2_ADDR, value); + printf("REG_ATA2_ADDR is 0x%x\n\r", value); + + if (!argv[3] || strlen(argv[3]) != 8) { + if (is_filter) + argv[3] = "11111111"; + else { + printf("portmap format error, should be of length 8\n"); + return; + } + } + j = 0; + for (i = 0; i < 7; i++) { + if (argv[3][i] != '0' && argv[3][i] != '1') { + printf("portmap format error, should be of combination of 0 or 1\n"); + return; + } + j += (argv[3][i] - '0') * (1 << i); + } + value = j << 4; //w_port_map + + if (argc > 5) { + j = strtoul(argv[5], NULL, 0); + if (j < 1 || 255 < j) { + printf("wrong age range, should be within 1~255\n"); + return; + } + value |= (j << 24); //w_age_field + value |= (0x1 << 2); //dynamic + } else { + value |= (0xff << 24); //w_age_field + value |= (0x3 << 2); //static + } + + if (argc > 6) { + j = strtoul(argv[6], NULL, 0); + if (7 < j) { + printf("wrong eg-tag range, should be within 0~7\n"); + return; + } + value |= (j << 13); //EG_TAG + } + + if (is_filter) + value |= (7 << 20); //sa_filter + + if (is_mymac) + value |= (1 << 23); + + reg_write(REG_ATWD_ADDR, value); + + usleep(5000); + reg_read(REG_ATWD_ADDR, &value); + printf("REG_ATWD_ADDR is 0x%x\n\r", value); + + value = 0x8001; //w_mac_cmd + reg_write(REG_ATC_ADDR, value); + + usleep(1000); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void table_search_mac_vid(int argc, char *argv[]) +{ + unsigned int i, j, value, mac, mac2, value2; + char tmpstr[9]; + + if (!argv[3] || strlen(argv[3]) != 12) { + printf("MAC address format error, should be of length 12\n"); + return; + } + strncpy(tmpstr, argv[3], 8); + tmpstr[8] = '\0'; + value = strtoul(tmpstr, NULL, 16); + reg_write(REG_ATA1_ADDR, value); + //printf("REG_ATA1_ADDR is 0x%x\n\r",value); + + strncpy(tmpstr, argv[3] + 8, 4); + tmpstr[4] = '\0'; + + value = strtoul(tmpstr, NULL, 16); + value = (value << 16); + value |= (1 << 15); //IVL=1 + + j = strtoul(argv[5], NULL, 0); + if (4095 < j) { + printf("wrong vid range, should be within 0~4095\n"); + return; + } + value |= j; //vid + + reg_write(REG_ATA2_ADDR, value); + //printf("REG_ATA2_ADDR is 0x%x\n\r",value); + + value = 0x8000; //w_mac_cmd + reg_write(REG_ATC_ADDR, value); + + usleep(1000); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + break; + } + usleep(1000); + } + if (i == 20) { + printf("search timeout.\n"); + return; + } + + if (value & 0x1000) { + printf("search no entry.\n"); + return; + } + + printf("search done.\n"); + printf("hash port(0:6) fid vid age mac-address filter my_mac\n"); + + printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu + reg_read(REG_ATRD_ADDR, &value2); + j = (value2 >> 4) & 0xff; //r_port_map + printf("%c", (j & 0x01) ? '1' : '-'); + printf("%c", (j & 0x02) ? '1' : '-'); + printf("%c", (j & 0x04) ? '1' : '-'); + printf("%c ", (j & 0x08) ? '1' : '-'); + printf("%c", (j & 0x10) ? '1' : '-'); + printf("%c", (j & 0x20) ? '1' : '-'); + printf("%c", (j & 0x40) ? '1' : '-'); + printf("%c", (j & 0x80) ? '1' : '-'); + + reg_read(REG_TSRA2_ADDR, &mac2); + + printf(" %2d", (mac2 >> 12) & 0x7); //FID + printf(" %4d", (mac2 & 0xfff)); + printf(" %4d", (value2 >> 24) & 0xff); //r_age_field + reg_read(REG_TSRA1_ADDR, &mac); + printf(" %08x", mac); + printf("%04x", ((mac2 >> 16) & 0xffff)); + printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-'); + printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-'); +} + +void table_search_mac_fid(int argc, char *argv[]) +{ + unsigned int i, j, value, mac, mac2, value2; + char tmpstr[9]; + + if (!argv[3] || strlen(argv[3]) != 12) { + printf("MAC address format error, should be of length 12\n"); + return; + } + strncpy(tmpstr, argv[3], 8); + tmpstr[8] = '\0'; + value = strtoul(tmpstr, NULL, 16); + reg_write(REG_ATA1_ADDR, value); + //printf("REG_ATA1_ADDR is 0x%x\n\r",value); + + strncpy(tmpstr, argv[3] + 8, 4); + tmpstr[4] = '\0'; + + value = strtoul(tmpstr, NULL, 16); + value = (value << 16); + value &= ~(1 << 15); //IVL=0 + + j = strtoul(argv[5], NULL, 0); + if (7 < j) { + printf("wrong fid range, should be within 0~7\n"); + return; + } + value |= (j << 12); //vid + + reg_write(REG_ATA2_ADDR, value); + //printf("REG_ATA2_ADDR is 0x%x\n\r",value); + + value = 0x8000; //w_mac_cmd + reg_write(REG_ATC_ADDR, value); + + usleep(1000); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + break; + } + usleep(1000); + } + if (i == 20) { + printf("search timeout.\n"); + return; + } + + if (value & 0x1000) { + printf("search no entry.\n"); + return; + } + + printf("search done.\n"); + printf("hash port(0:6) fid vid age mac-address filter my_mac\n"); + + printf("%03x: ", (value >> 16) & 0xfff); //hash_addr_lu + reg_read(REG_ATRD_ADDR, &value2); + j = (value2 >> 4) & 0xff; //r_port_map + printf("%c", (j & 0x01) ? '1' : '-'); + printf("%c", (j & 0x02) ? '1' : '-'); + printf("%c", (j & 0x04) ? '1' : '-'); + printf("%c ", (j & 0x08) ? '1' : '-'); + printf("%c", (j & 0x10) ? '1' : '-'); + printf("%c", (j & 0x20) ? '1' : '-'); + printf("%c", (j & 0x40) ? '1' : '-'); + printf("%c", (j & 0x80) ? '1' : '-'); + + reg_read(REG_TSRA2_ADDR, &mac2); + + printf(" %2d", (mac2 >> 12) & 0x7); //FID + printf(" %4d", (mac2 & 0xfff)); + printf(" %4d", (value2 >> 24) & 0xff); //r_age_field + reg_read(REG_TSRA1_ADDR, &mac); + printf(" %08x", mac); + printf("%04x", ((mac2 >> 16) & 0xffff)); + printf(" %c", (((value2 >> 20) & 0x03) == 0x03) ? 'y' : '-'); + printf(" %c\n", (((value2 >> 23) & 0x01) == 0x01) ? 'y' : '-'); +} + +void table_del_fid(int argc, char *argv[]) +{ + unsigned int i, j, value; + char tmpstr[9]; + + if (!argv[3] || strlen(argv[3]) != 12) { + printf("MAC address format error, should be of length 12\n"); + return; + } + strncpy(tmpstr, argv[3], 8); + tmpstr[8] = '\0'; + value = strtoul(tmpstr, NULL, 16); + reg_write(REG_ATA1_ADDR, value); + strncpy(tmpstr, argv[3] + 8, 4); + tmpstr[4] = '\0'; + value = strtoul(tmpstr, NULL, 16); + value = (value << 16); + + if (argc > 5) { + j = strtoul(argv[5], NULL, 0); + if (j > 7) { + printf("wrong fid range, should be within 0~7\n"); + return; + } + value |= (j << 12); //fid + } + + reg_write(REG_ATA2_ADDR, value); + + value = 0; //STATUS=0, delete mac + reg_write(REG_ATWD_ADDR, value); + + value = 0x8001; //w_mac_cmd + reg_write(REG_ATC_ADDR, value); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + if (argv[1] != NULL) + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void table_del_vid(int argc, char *argv[]) +{ + unsigned int i, j, value; + char tmpstr[9]; + + if (!argv[3] || strlen(argv[3]) != 12) { + printf("MAC address format error, should be of length 12\n"); + return; + } + strncpy(tmpstr, argv[3], 8); + tmpstr[8] = '\0'; + value = strtoul(tmpstr, NULL, 16); + reg_write(REG_ATA1_ADDR, value); + + strncpy(tmpstr, argv[3] + 8, 4); + tmpstr[4] = '\0'; + value = strtoul(tmpstr, NULL, 16); + value = (value << 16); + + j = strtoul(argv[5], NULL, 0); + if (j > 4095) { + printf("wrong fid range, should be within 0~4095\n"); + return; + } + value |= j; //vid + value |= 1 << 15; + reg_write(REG_ATA2_ADDR, value); + + value = 0; //STATUS=0, delete mac + reg_write(REG_ATWD_ADDR, value); + + value = 0x8001; //w_mac_cmd + reg_write(REG_ATC_ADDR, value); + + for (i = 0; i < 20; i++) { + reg_read(REG_ATC_ADDR, &value); + if ((value & 0x8000) == 0) { //mac address busy + if (argv[1] != NULL) + printf("done.\n"); + return; + } + usleep(1000); + } + if (i == 20) + printf("timeout.\n"); +} + +void table_clear(void) +{ + unsigned int value; + reg_write(REG_ATC_ADDR, 0x8002); + usleep(5000); + reg_read(REG_ATC_ADDR, &value); + + printf("REG_ATC_ADDR is 0x%x\n\r", value); +} + +void set_mirror_to(int argc, char *argv[]) +{ + unsigned int value; + int idx; + + idx = strtoul(argv[3], NULL, 0); + if (idx < 0 || MAX_PORT < idx) { + printf("wrong port member, should be within 0~%d\n", MAX_PORT); + return; + } + if (chip_name == 0x7530) { + + reg_read(REG_MFC_ADDR, &value); + value |= 0x1 << 3; + value &= 0xfffffff8; + value |= idx << 0; + + reg_write(REG_MFC_ADDR, value); + } else { + + reg_read(REG_CFC_ADDR, &value); + value &= (~REG_CFC_MIRROR_EN_MASK); + value |= (1 << REG_CFC_MIRROR_EN_OFFT); + value &= (~REG_CFC_MIRROR_PORT_MASK); + value |= (idx << REG_CFC_MIRROR_PORT_OFFT); + reg_write(REG_CFC_ADDR, value); + } +} + +void set_mirror_from(int argc, char *argv[]) +{ + unsigned int offset, value; + int idx, mirror; + + idx = strtoul(argv[3], NULL, 0); + mirror = strtoul(argv[4], NULL, 0); + + if (idx < 0 || MAX_PORT < idx) { + printf("wrong port member, should be within 0~%d\n", MAX_PORT); + return; + } + + if (mirror < 0 || 3 < mirror) { + printf("wrong mirror setting, should be within 0~3\n"); + return; + } + + offset = (0x2004 | (idx << 8)); + reg_read(offset, &value); + + value &= 0xfffffcff; + value |= mirror << 8; + + reg_write(offset, value); +} + +void vlan_dump(int argc, char *argv[]) +{ + unsigned int i, j, value, value2; + int eg_tag = 0; + + if (argc == 4) { + if (!strncmp(argv[3], "egtag", 6)) + eg_tag = 1; + } + + if (eg_tag) + printf(" vid fid portmap s-tag\teg_tag(0:untagged 2:tagged)\n"); + else + printf(" vid fid portmap s-tag\n"); + + for (i = 1; i < 4095; i++) { + value = (0x80000000 + i); //r_vid_cmd + reg_write(REG_VTCR_ADDR, value); + + for (j = 0; j < 20; j++) { + reg_read(REG_VTCR_ADDR, &value); + if ((value & 0x80000000) == 0) { //mac address busy + break; + } + usleep(1000); + } + if (j == 20) + printf("timeout.\n"); + + reg_read(REG_VAWD1_ADDR, &value); + reg_read(REG_VAWD2_ADDR, &value2); + //printf("REG_VAWD1_ADDR value%d is 0x%x\n\r", i, value); + //printf("REG_VAWD2_ADDR value%d is 0x%x\n\r", i, value2); + + if ((value & 0x01) != 0) { + printf(" %4d ", i); + printf(" %2d ", ((value & 0xe) >> 1)); + printf(" %c", (value & 0x00010000) ? '1' : '-'); + printf("%c", (value & 0x00020000) ? '1' : '-'); + printf("%c", (value & 0x00040000) ? '1' : '-'); + printf("%c", (value & 0x00080000) ? '1' : '-'); + printf("%c", (value & 0x00100000) ? '1' : '-'); + printf("%c", (value & 0x00200000) ? '1' : '-'); + printf("%c", (value & 0x00400000) ? '1' : '-'); + printf("%c", (value & 0x00800000) ? '1' : '-'); + printf(" %4d", ((value & 0xfff0) >> 4)); + if (eg_tag) { + printf("\t"); + if ((value & (0x3 << 28)) == (0x3 << 28)) { + /* VTAG_EN=1 and EG_CON=1 */ + printf("CONSISTENT"); + } else if (value & (0x1 << 28)) { + /* VTAG_EN=1 */ + printf("%d", (value2 & 0x0003) >> 0); + printf("%d", (value2 & 0x000c) >> 2); + printf("%d", (value2 & 0x0030) >> 4); + printf("%d", (value2 & 0x00c0) >> 6); + printf("%d", (value2 & 0x0300) >> 8); + printf("%d", (value2 & 0x0c00) >> 10); + printf("%d", (value2 & 0x3000) >> 12); + printf("%d", (value2 & 0xc000) >> 14); + } else { + /* VTAG_EN=0 */ + printf("DISABLED"); + } + } + printf("\n"); + } else { + /*print 16 vid for reference information*/ + if (i <= 16) { + printf(" %4d ", i); + printf(" %2d ", ((value & 0xe) >> 1)); + printf(" invalid\n"); + } + } + } +} + + +static long timespec_diff_us(struct timespec start, struct timespec end) +{ + struct timespec temp; + unsigned long duration = 0; + + if ((end.tv_nsec - start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + /* calculate second part*/ + duration += temp.tv_sec * 1000000; + /* calculate ns part*/ + duration += temp.tv_nsec >> 10; + + return duration; +} + + +void vlan_clear(int argc, char *argv[]) +{ + unsigned int value; + int vid; + unsigned long duration_us = 0; + struct timespec start, end; + + for (vid = 0; vid < 4096; vid++) { + clock_gettime(CLOCK_REALTIME, &start); + value = 0; //invalid + reg_write(REG_VAWD1_ADDR, value); + + value = (0x80001000 + vid); //w_vid_cmd + reg_write(REG_VTCR_ADDR, value); + while (duration_us <= 1000) { + reg_read(REG_VTCR_ADDR, &value); + if ((value & 0x80000000) == 0) { //table busy + break; + } + clock_gettime(CLOCK_REALTIME, &end); + duration_us = timespec_diff_us(start, end); + } + if (duration_us > 1000) + printf("config vlan timeout: %ld.\n", duration_us); + } +} + +void vlan_set(int argc, char *argv[]) +{ + unsigned int vlan_mem = 0; + unsigned int value = 0; + unsigned int value2 = 0; + int i, vid, fid; + int stag = 0; + unsigned long eg_con = 0; + unsigned int eg_tag = 0; + + if (argc < 5) { + printf("insufficient arguments!\n"); + return; + } + + fid = strtoul(argv[3], NULL, 0); + if (fid < 0 || fid > 7) { + printf("wrong filtering db id range, should be within 0~7\n"); + return; + } + value |= (fid << 1); + + vid = strtoul(argv[4], NULL, 0); + if (vid < 0 || 0xfff < vid) { + printf("wrong vlan id range, should be within 0~4095\n"); + return; + } + + if (strlen(argv[5]) != 8) { + printf("portmap format error, should be of length 7\n"); + return; + } + + vlan_mem = 0; + for (i = 0; i < 8; i++) { + if (argv[5][i] != '0' && argv[5][i] != '1') { + printf("portmap format error, should be of combination of 0 or 1\n"); + return; + } + vlan_mem += (argv[5][i] - '0') * (1 << i); + } + + /* VLAN stag */ + if (argc > 6) { + stag = strtoul(argv[6], NULL, 16); + if (stag < 0 || 0xfff < stag) { + printf("wrong stag id range, should be within 0~4095\n"); + return; + } + //printf("STAG is 0x%x\n", stag); + } + + /* set vlan member */ + value |= (vlan_mem << 16); + value |= (1 << 30); //IVL=1 + value |= ((stag & 0xfff) << 4); //stag + value |= 1; //valid + + if (argc > 7) { + eg_con = strtoul(argv[7], NULL, 2); + eg_con = !!eg_con; + value |= (eg_con << 29); //eg_con + value |= (1 << 28); //eg tag control enable + } + + if (argc > 8 && !eg_con) { + if (strlen(argv[8]) != 8) { + printf("egtag portmap format error, should be of length 7\n"); + return; + } + + for (i = 0; i < 8; i++) { + if (argv[8][i] < '0' || argv[8][i] > '3') { + printf("egtag portmap format error, should be of combination of 0 or 3\n"); + return; + } + //eg_tag += (argv[8][i] - '0') * (1 << i * 2); + eg_tag |= (argv[8][i] - '0') << (i * 2); + } + + value |= (1 << 28); //eg tag control enable + value2 &= ~(0xffff); + value2 |= eg_tag; + } + reg_write(REG_VAWD1_ADDR, value); + reg_write(REG_VAWD2_ADDR, value2); + //printf("VAWD1=0x%08x VAWD2=0x%08x ", value, value2); + + value = (0x80001000 + vid); //w_vid_cmd + reg_write(REG_VTCR_ADDR, value); + //printf("VTCR=0x%08x\n", value); + + for (i = 0; i < 300; i++) { + usleep(1000); + reg_read(REG_VTCR_ADDR, &value); + if ((value & 0x80000000) == 0) //table busy + break; + } + + if (i == 300) + printf("config vlan timeout.\n"); +} + +void igmp_on(int argc, char *argv[]) +{ + unsigned int leaky_en = 0; + unsigned int wan_num = 4; + unsigned int port, offset, value; + char cmd[80]; + int ret; + + if (argc > 3) + leaky_en = strtoul(argv[3], NULL, 10); + if (argc > 4) + wan_num = strtoul(argv[4], NULL, 10); + + if (leaky_en == 1) { + if (wan_num == 4) { + /* reg_write(0x2410, 0x810000c8); */ + reg_read(0x2410, &value); + reg_write(0x2410, value | (1 << 3)); + /* reg_write(0x2010, 0x810000c0); */ + reg_read(0x2010, &value); + reg_write(0x2010, value & (~(1 << 3))); + reg_write(REG_ISC_ADDR, 0x10027d10); + } else { + /* reg_write(0x2010, 0x810000c8); */ + reg_read(0x2010, &value); + reg_write(0x2010, value | (1 << 3)); + /* reg_write(0x2410, 0x810000c0); */ + reg_read(0x2410, &value); + reg_write(0x2410, value & (~(1 << 3))); + reg_write(REG_ISC_ADDR, 0x01027d01); + } + } + else + reg_write(REG_ISC_ADDR, 0x10027d60); + + reg_write(0x1c, 0x08100810); + reg_write(0x2008, 0xb3ff); + reg_write(0x2108, 0xb3ff); + reg_write(0x2208, 0xb3ff); + reg_write(0x2308, 0xb3ff); + reg_write(0x2408, 0xb3ff); + reg_write(0x2608, 0xb3ff); + /* Enable Port ACL + * reg_write(0x2P04, 0xff0403); + */ + for (port = 0; port <= 6; port++) { + offset = 0x2004 + port * 0x100; + reg_read(offset, &value); + reg_write(offset, value | (1 << 10)); + } + + /*IGMP query only p4 -> p5*/ + reg_write(0x94, 0x00ff0002); + if (wan_num == 4) + reg_write(0x98, 0x000a1008); + else + reg_write(0x98, 0x000a0108); + reg_write(0x90, 0x80005000); + reg_write(0x94, 0xff001100); + if (wan_num == 4) + reg_write(0x98, 0x000B1000); + else + reg_write(0x98, 0x000B0100); + reg_write(0x90, 0x80005001); + reg_write(0x94, 0x3); + reg_write(0x98, 0x0); + reg_write(0x90, 0x80009000); + reg_write(0x94, 0x1a002080); + reg_write(0x98, 0x0); + reg_write(0x90, 0x8000b000); + + /*IGMP p5 -> p4*/ + reg_write(0x94, 0x00ff0002); + reg_write(0x98, 0x000a2008); + reg_write(0x90, 0x80005002); + reg_write(0x94, 0x4); + reg_write(0x98, 0x0); + reg_write(0x90, 0x80009001); + if (wan_num == 4) + reg_write(0x94, 0x1a001080); + else + reg_write(0x94, 0x1a000180); + reg_write(0x98, 0x0); + reg_write(0x90, 0x8000b001); + + /*IGMP p0~p3 -> p6*/ + reg_write(0x94, 0x00ff0002); + if (wan_num == 4) + reg_write(0x98, 0x000a0f08); + else + reg_write(0x98, 0x000a1e08); + reg_write(0x90, 0x80005003); + reg_write(0x94, 0x8); + reg_write(0x98, 0x0); + reg_write(0x90, 0x80009002); + reg_write(0x94, 0x1a004080); + reg_write(0x98, 0x0); + reg_write(0x90, 0x8000b002); + + /*IGMP query only p6 -> p0~p3*/ + reg_write(0x94, 0x00ff0002); + reg_write(0x98, 0x000a4008); + reg_write(0x90, 0x80005004); + reg_write(0x94, 0xff001100); + reg_write(0x98, 0x000B4000); + reg_write(0x90, 0x80005005); + reg_write(0x94, 0x30); + reg_write(0x98, 0x0); + reg_write(0x90, 0x80009003); + if (wan_num == 4) + reg_write(0x94, 0x1a000f80); + else + reg_write(0x94, 0x1a001e80); + reg_write(0x98, 0x0); + reg_write(0x90, 0x8000b003); + + /*Force eth2 to receive all igmp packets*/ + snprintf(cmd, sizeof(cmd), "echo 2 > /sys/devices/virtual/net/%s/brif/%s/multicast_router", BR_DEVNAME, ETH_DEVNAME); + ret = system(cmd); + if (ret) + printf("Failed to set /sys/devices/virtual/net/%s/brif/%s/multicast_router\n", + BR_DEVNAME, ETH_DEVNAME); +} + +void igmp_disable(int argc, char *argv[]) +{ + unsigned int reg_offset, value; + int port_num; + + if (argc < 4) { + printf("insufficient arguments!\n"); + return; + } + port_num = strtoul(argv[3], NULL, 0); + if (port_num < 0 || 6 < port_num) { + printf("wrong port range, should be within 0~6\n"); + return; + } + + //set ISC: IGMP Snooping Control Register (offset: 0x0018) + reg_offset = 0x2008; + reg_offset |= (port_num << 8); + value = 0x8000; + + reg_write(reg_offset, value); +} + +void igmp_enable(int argc, char *argv[]) +{ + unsigned int reg_offset, value; + int port_num; + + if (argc < 4) { + printf("insufficient arguments!\n"); + return; + } + port_num = strtoul(argv[3], NULL, 0); + if (port_num < 0 || 6 < port_num) { + printf("wrong port range, should be within 0~6\n"); + return; + } + + //set ISC: IGMP Snooping Control Register (offset: 0x0018) + reg_offset = 0x2008; + reg_offset |= (port_num << 8); + value = 0x9755; + reg_write(reg_offset, value); +} + +void igmp_off() +{ + unsigned int value; + //set ISC: IGMP Snooping Control Register (offset: 0x0018) + reg_read(REG_ISC_ADDR, &value); + value &= ~(1 << 18); //disable + reg_write(REG_ISC_ADDR, value); + + /*restore wan port multicast leaky vlan function: default disabled*/ + reg_read(0x2010, &value); + reg_write(0x2010, value & (~(1 << 3))); + reg_read(0x2410, &value); + reg_write(0x2410, value & (~(1 << 3))); + + printf("config igmpsnoop off.\n"); +} + +int switch_reset(int argc, char *argv[]) +{ + if (chip_name == 0x7988) + return -1; + + unsigned int value = 0; + /*Software Register Reset and Software System Reset */ + reg_write(0x7000, 0x3); + reg_read(0x7000, &value); + printf("SYS_CTRL(0x7000) register value =0x%x \n", value); + if (chip_name == 0x7531) { + reg_write(0x7c0c, 0x11111111); + reg_read(0x7c0c, &value); + printf("GPIO Mode (0x7c0c) select value =0x%x \n", value); + } + printf("Switch Software Reset !!! \n"); + return 0; +} + +int phy_set_fc(int argc, char *argv[]) +{ + unsigned int port, pause_capable; + unsigned int phy_value; + + port = atoi(argv[3]); + pause_capable = atoi(argv[4]); + + /*Check the input parameters is right or not.*/ + if (port > MAX_PORT - 2 || pause_capable > 1) { + printf("Illegal parameter (port:0~4, full_duplex_pause_capable:0|1)\n"); + return -1; + } + printf("port=%d, full_duplex_pause_capable:%d\n", port, pause_capable); + mii_mgr_read(port, 4, &phy_value); + printf("read phy_value:0x%x\r\n", phy_value); + phy_value &= (~(0x1 << 10)); + phy_value &= (~(0x1 << 11)); + if (pause_capable == 1) { + phy_value |= (0x1 << 10); + phy_value |= (0x1 << 11); + } + mii_mgr_write(port, 4, phy_value); + printf("write phy_value:0x%x\r\n", phy_value); + return 0; +} /*end phy_set_fc*/ + +int phy_set_an(int argc, char *argv[]) +{ + unsigned int port, auto_negotiation_en; + unsigned int phy_value; + + port = atoi(argv[3]); + auto_negotiation_en = atoi(argv[4]); + + /*Check the input parameters is right or not.*/ + if (port > MAX_PORT - 2 || auto_negotiation_en > 1) { + printf("Illegal parameter (port:0~4, auto_negotiation_en:0|1)\n"); + return -1; + } + printf("port=%d, auto_negotiation_en:%d\n", port, auto_negotiation_en); + mii_mgr_read(port, 0, &phy_value); + printf("read phy_value:0x%x\r\n", phy_value); + phy_value &= (~(1 << 12)); + phy_value |= (auto_negotiation_en << 12); + mii_mgr_write(port, 0, phy_value); + printf("write phy_value:0x%x\r\n", phy_value); + return 0; +} /*end phy_set_an*/ + +int set_mac_pfc(int argc, char *argv[]) +{ + unsigned int value; + int port, enable = 0; + + port = atoi(argv[3]); + enable = atoi(argv[4]); + printf("enable: %d\n", enable); + if (port < 0 || port > 6 || enable < 0 || enable > 1) { + printf("Illegal parameter (port:0~6, enable|diable:0|1) \n"); + return -1; + } + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg_read(REG_PFC_CTRL_ADDR, &value); + value &= ~(1 << port); + value |= (enable << port); + printf("write reg: %x, value: %x\n", REG_PFC_CTRL_ADDR, value); + reg_write(REG_PFC_CTRL_ADDR, value); + } + else + printf("\nCommand not support by this chip.\n"); + return 0; +} + +int global_set_mac_fc(int argc, char *argv[]) +{ + unsigned char enable = 0; + unsigned int value, reg; + + if (chip_name == 0x7530) { + enable = atoi(argv[3]); + printf("enable: %d\n", enable); + + /*Check the input parameters is right or not.*/ + if (enable > 1) { + printf(HELP_MACCTL_FC); + return -1; + } + reg_write(0x7000, 0x3); + reg = REG_GFCCR0_ADDR; + reg_read(REG_GFCCR0_ADDR, &value); + value &= (~REG_FC_EN_MASK); + value |= (enable << REG_FC_EN_OFFT); + printf("write reg: %x, value: %x\n", reg, value); + reg_write(REG_GFCCR0_ADDR, value); + } else + printf("\r\nCommand not support by this chip.\n"); + return 0; +} /*end mac_set_fc*/ + +int qos_sch_select(int argc, char *argv[]) +{ + unsigned char port, queue; + unsigned char type = 0; + unsigned int value, reg; + + if (argc < 7) + return -1; + + port = atoi(argv[3]); + queue = atoi(argv[4]); + type = atoi(argv[6]); + + if (port > 6 || queue > 7) { + printf("\n Illegal input parameters\n"); + return -1; + } + + if ((type != 0 && type != 1 && type != 2)) { + printf(HELP_QOS_TYPE); + return -1; + } + + printf("\r\nswitch qos type: %d.\n",type); + + if (!strncmp(argv[5], "min", 4)) { + + if (type == 0) { + /*min sharper-->round roubin, disable min sharper rate limit*/ + reg = GSW_MMSCR0_Q(queue) + 0x100 * port; + reg_read(reg, &value); + value = 0x0; + reg_write(reg, value); + } else if (type == 1) { + /*min sharper-->sp, disable min sharper rate limit*/ + reg = GSW_MMSCR0_Q(queue) + 0x100 * port; + reg_read(reg, &value); + value = 0x0; + value |= (1 << 31); + reg_write(reg, value); + } else { + printf("min sharper only support: rr or sp\n"); + return -1; + } + } else if (!strncmp(argv[5], "max", 4)) { + if (type == 1) { + /*max sharper-->sp, disable max sharper rate limit*/ + reg = GSW_MMSCR1_Q(queue) + 0x100 * port; + reg_read(reg, &value); + value = 0x0; + value |= (1 << 31); + reg_write(reg, value); + } else if (type == 2) { + /*max sharper-->wfq, disable max sharper rate limit*/ + reg = GSW_MMSCR1_Q(queue) + 0x100 * port; + reg_read(reg, &value); + value = 0x0; + reg_write(reg, value); + } else { + printf("max sharper only support: wfq or sp\n"); + return -1; + } + } else { + printf("\r\nIllegal sharper:%s\n",argv[5]); + return -1; + } + printf("reg:0x%x--value:0x%x\n",reg,value); + + return 0; +} + +void get_upw(unsigned int *value, unsigned char base) +{ + *value &= (~((0x7 << 0) | (0x7 << 4) | (0x7 << 8) | (0x7 << 12) | + (0x7 << 16) | (0x7 << 20))); + switch (base) + { + case 0: /* port-based 0x2x40[18:16] */ + *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) | + (0x2 << 12) | (0x7 << 16) | (0x2 << 20)); + break; + case 1: /* tagged-based 0x2x40[10:8] */ + *value |= ((0x2 << 0) | (0x2 << 4) | (0x7 << 8) | + (0x2 << 12) | (0x2 << 16) | (0x2 << 20)); + break; + case 2: /* DSCP-based 0x2x40[14:12] */ + *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) | + (0x7 << 12) | (0x2 << 16) | (0x2 << 20)); + break; + case 3: /* acl-based 0x2x40[2:0] */ + *value |= ((0x7 << 0) | (0x2 << 4) | (0x2 << 8) | + (0x2 << 12) | (0x2 << 16) | (0x2 << 20)); + break; + case 4: /* arl-based 0x2x40[22:20] */ + *value |= ((0x2 << 0) | (0x2 << 4) | (0x2 << 8) | + (0x2 << 12) | (0x2 << 16) | (0x7 << 20)); + break; + case 5: /* stag-based 0x2x40[6:4] */ + *value |= ((0x2 << 0) | (0x7 << 4) | (0x2 << 8) | + (0x2 << 12) | (0x2 << 16) | (0x2 << 20)); + break; + default: + break; + } +} + +void qos_set_base(int argc, char *argv[]) +{ + unsigned char base = 0; + unsigned char port; + unsigned int value; + + if (argc < 5) + return; + + port = atoi(argv[3]); + base = atoi(argv[4]); + + if (base > 6) { + printf(HELP_QOS_BASE); + return; + } + + if (port > 6) { + printf("Illegal port index:%d\n",port); + return; + } + + printf("\r\nswitch qos base : %d. (port-based:0, tag-based:1,\ + dscp-based:2, acl-based:3, arl-based:4, stag-based:5)\n", + base); + if (chip_name == 0x7530) { + + reg_read(0x44, &value); + get_upw(&value, base); + reg_write(0x44, value); + printf("reg: 0x44, value: 0x%x\n", value); + + } else if (chip_name == 0x7531 || chip_name == 0x7988) { + + reg_read(GSW_UPW(port), &value); + get_upw(&value, base); + reg_write(GSW_UPW(port), value); + printf("reg:0x%x, value: 0x%x\n",GSW_UPW(port),value); + + } else { + printf("unknown switch device"); + return; + } +} + +void qos_wfq_set_weight(int argc, char *argv[]) +{ + int port, weight[8], i; + unsigned char queue; + unsigned int reg, value; + + port = atoi(argv[3]); + + for (i = 0; i < 8; i++) { + weight[i] = atoi(argv[i + 4]); + } + + /* MT7530 total 7 port */ + if (port < 0 || port > 6) { + printf(HELP_QOS_PORT_WEIGHT); + return; + } + + for (i = 0; i < 8; i++) { + if (weight[i] < 1 || weight[i] > 16) { + printf(HELP_QOS_PORT_WEIGHT); + return; + } + } + printf("port: %x, q0: %x, q1: %x, q2: %x, q3: %x, \ + q4: %x, q5: %x, q6: %x, q7: %x\n", + port, weight[0], weight[1], weight[2], weight[3], weight[4], + weight[5], weight[6], weight[7]); + + for (queue = 0; queue < 8; queue++) { + reg = GSW_MMSCR1_Q(queue) + 0x100 * port; + reg_read(reg, &value); + value &= (~(0xf << 24)); //bit24~27 + value |= (((weight[queue] - 1) & 0xf) << 24); + printf("reg: %x, value: %x\n", reg, value); + reg_write(reg, value); + } +} + +void qos_set_portpri(int argc, char *argv[]) +{ + unsigned char port, prio; + unsigned int value; + + port = atoi(argv[3]); + prio = atoi(argv[4]); + + if (port >= 7 || prio > 7) { + printf(HELP_QOS_PORT_PRIO); + return; + } + + reg_read(GSW_PCR(port), &value); + value &= (~(0x7 << 24)); + value |= (prio << 24); + reg_write(GSW_PCR(port), value); + printf("write reg: %x, value: %x\n", GSW_PCR(port), value); +} + +void qos_set_dscppri(int argc, char *argv[]) +{ + unsigned char prio, dscp, pim_n, pim_offset; + unsigned int reg, value; + + dscp = atoi(argv[3]); + prio = atoi(argv[4]); + + if (dscp > 63 || prio > 7) { + printf(HELP_QOS_DSCP_PRIO); + return; + } + + pim_n = dscp / 10; + pim_offset = (dscp - pim_n * 10) * 3; + reg = 0x0058 + pim_n * 4; + reg_read(reg, &value); + value &= (~(0x7 << pim_offset)); + value |= ((prio & 0x7) << pim_offset); + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); +} + +void qos_pri_mapping_queue(int argc, char *argv[]) +{ + unsigned char prio, queue, pem_n, port; + unsigned int reg, value; + + if (argc < 6) + return; + + port = atoi(argv[3]); + prio = atoi(argv[4]); + queue = atoi(argv[5]); + + if (prio > 7 || queue > 7) { + printf(HELP_QOS_PRIO_QMAP); + return; + } + if (chip_name == 0x7530) { + pem_n = prio / 2; + reg = pem_n * 0x4 + 0x48; + reg_read(reg, &value); + if (prio % 2) { + value &= (~(0x7 << 24)); + value |= ((queue & 0x7) << 24); + } else { + value &= (~(0x7 << 8)); + value |= ((queue & 0x7) << 8); + } + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + } else if (chip_name == 0x7531 || chip_name == 0x7988) { + pem_n = prio / 2; + reg = GSW_PEM(pem_n) + 0x100 * port; + reg_read(reg, &value); + if (prio % 2) { // 1 1 + value &= (~(0x7 << 25)); + value |= ((queue & 0x7) << 25); + } else { // 0 0 + value &= (~(0x7 << 9)); + value |= ((queue & 0x7) << 9); + } + reg_write(reg, value); + printf("write reg: %x, value: %x\n", reg, value); + } + else { + printf("unknown switch device"); + return; + } +} + +static int macMT753xVlanSetVid(unsigned char index, unsigned char active, + unsigned short vid, unsigned char portMap, unsigned char tagPortMap, + unsigned char ivl_en, unsigned char fid, unsigned short stag) +{ + unsigned int value = 0; + unsigned int value2 = 0; + unsigned int reg; + int i; + + printf("index: %x, active: %x, vid: %x, portMap: %x, \ + tagPortMap: %x, ivl_en: %x, fid: %x, stag: %x\n", + index, active, vid, portMap, tagPortMap, ivl_en, fid, stag); + + value = (portMap << 16); + value |= (stag << 4); + value |= (ivl_en << 30); + value |= (fid << 1); + value |= (active ? 1 : 0); + + // total 7 ports + for (i = 0; i < 7; i++) { + if (tagPortMap & (1 << i)) + value2 |= 0x2 << (i * 2); + } + + if (value2) + value |= (1 << 28); // eg_tag + + reg = 0x98; // VAWD2 + reg_write(reg, value2); + + reg = 0x94; // VAWD1 + reg_write(reg, value); + + reg = 0x90; // VTCR + value = (0x80001000 + vid); + reg_write(reg, value); + + reg = 0x90; // VTCR + while (1) { + reg_read(reg, &value); + if ((value & 0x80000000) == 0) //table busy + break; + } + + /* switch clear */ + reg = 0x80; + reg_write(reg, 0x8002); + usleep(5000); + reg_read(reg, &value); + + printf("SetVid: index:%d active:%d vid:%d portMap:%x tagPortMap:%x\r\n", + index, active, vid, portMap, tagPortMap); + return 0; + +} /*end macMT753xVlanSetVid*/ +/* +static int macMT753xVlanGetVtbl(unsigned short index) +{ + unsigned int reg, value, vawd1, vawd2; + + reg = 0x90; // VTCR + value = (0x80000000 + index); + + reg_write(reg, value); + + reg = 0x90; // VTCR + while (1) { + reg_read(reg, &value); + if ((value & 0x80000000) == 0) //table busy + break; + } + + reg = 0x94; // VAWD1 + reg_read(reg, &vawd1); + + reg = 0x98; // VAWD2 + reg_read(reg, &vawd2); + + if (vawd1 & 0x1) { + fprintf(stderr, "%d.%s vid:%d fid:%d portMap:0x%x \ + tagMap:0x%x stag:0x%x ivl_en:0x%x\r\n", + index, (vawd1 & 0x1) ? "on" : "off", index, ((vawd1 & 0xe) >> 1), + (vawd1 & 0xff0000) >> 16, vawd2, (vawd1 & 0xfff0) >> 0x4, (vawd1 >> 30) & 0x1); + } + return 0; +} */ /*end macMT753xVlanGetVtbl*/ + +static int macMT753xVlanSetPvid(unsigned char port, unsigned short pvid) +{ + unsigned int value; + unsigned int reg; + + /*Parameters is error*/ + if (port > 6) + return -1; + + reg = 0x2014 + (port * 0x100); + reg_read(reg, &value); + value &= ~0xfff; + value |= pvid; + reg_write(reg, value); + + /* switch clear */ + reg = 0x80; + reg_write(reg, 0x8002); + usleep(5000); + reg_read(reg, &value); + + printf("SetPVID: port:%d pvid:%d\r\n", port, pvid); + return 0; +} +/* +static int macMT753xVlanGetPvid(unsigned char port) +{ + unsigned int value; + unsigned int reg; + + if (port > 6) + return -1; + reg = 0x2014 + (port * 0x100); + reg_read(reg, &value); + return (value & 0xfff); +} */ +/* +static int macMT753xVlanDisp(void) +{ + unsigned int i = 0; + unsigned int reg, value; + + reg = 0x2604; + reg_read(reg, &value); + value &= 0x30000000; + + fprintf(stderr, "VLAN function is %s\n", value ? ETHCMD_ENABLE : ETHCMD_DISABLE); + fprintf(stderr, "PVID e0:%02d e1:%02d e2:%02d e3:%02d e4:%02d e5:%02d e6:%02d\n", + macMT753xVlanGetPvid(0), macMT753xVlanGetPvid(1), macMT753xVlanGetPvid(2), + macMT753xVlanGetPvid(3), macMT753xVlanGetPvid(4), macMT753xVlanGetPvid(5), macMT753xVlanGetPvid(6)); + + for (i = 0; i < MAX_VID_VALUE; i++) + macMT753xVlanGetVtbl(i); + + return 0; +}*/ /*end macMT753xVlanDisp*/ + +void doVlanSetPvid(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned short pvid = 0; + + port = atoi(argv[3]); + pvid = atoi(argv[4]); + /*Check the input parameters is right or not.*/ + if ((port >= SWITCH_MAX_PORT) || (pvid > MAX_VID_VALUE)) { + printf(HELP_VLAN_PVID); + return; + } + + macMT753xVlanSetPvid(port, pvid); + + printf("port:%d pvid:%d,vlancap: max_port:%d maxvid:%d\r\n", + port, pvid, SWITCH_MAX_PORT, MAX_VID_VALUE); +} /*end doVlanSetPvid*/ + +void doVlanSetVid(int argc, char *argv[]) +{ + unsigned char index = 0; + unsigned char active = 0; + unsigned char portMap = 0; + unsigned char tagPortMap = 0; + unsigned short vid = 0; + + unsigned char ivl_en = 0; + unsigned char fid = 0; + unsigned short stag = 0; + + index = atoi(argv[3]); + active = atoi(argv[4]); + vid = atoi(argv[5]); + + /*Check the input parameters is right or not.*/ + if ((index >= MAX_VLAN_RULE) || (vid >= 4096) || (active > ACTIVED)) { + printf(HELP_VLAN_VID); + return; + } + + /*CPU Port is always the membership*/ + portMap = atoi(argv[6]); + tagPortMap = atoi(argv[7]); + + printf("subcmd parameter argc = %d\r\n", argc); + if (argc >= 9) { + ivl_en = atoi(argv[8]); + if (argc >= 10) { + fid = atoi(argv[9]); + if (argc >= 11) + stag = atoi(argv[10]); + } + } + macMT753xVlanSetVid(index, active, vid, portMap, tagPortMap, + ivl_en, fid, stag); + printf("index:%d active:%d vid:%d\r\n", index, active, vid); +} /*end doVlanSetVid*/ + +void doVlanSetAccFrm(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char type = 0; + unsigned int value; + unsigned int reg; + + port = atoi(argv[3]); + type = atoi(argv[4]); + + printf("port: %d, type: %d\n", port, type); + + /*Check the input parameters is right or not.*/ + if ((port > SWITCH_MAX_PORT) || (type > REG_PVC_ACC_FRM_RELMASK)) { + printf(HELP_VLAN_ACC_FRM); + return; + } + + reg = REG_PVC_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= (~REG_PVC_ACC_FRM_MASK); + value |= ((unsigned int)type << REG_PVC_ACC_FRM_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} /*end doVlanSetAccFrm*/ + +void doVlanSetPortAttr(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char attr = 0; + unsigned int value; + unsigned int reg; + + port = atoi(argv[3]); + attr = atoi(argv[4]); + + printf("port: %x, attr: %x\n", port, attr); + + /*Check the input parameters is right or not.*/ + if (port > SWITCH_MAX_PORT || attr > 3) { + printf(HELP_VLAN_PORT_ATTR); + return; + } + + reg = 0x2010 + port * 0x100; + reg_read(reg, &value); + value &= (0xffffff3f); + value |= (attr << 6); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} + +void doVlanSetPortMode(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char mode = 0; + unsigned int value; + unsigned int reg; + port = atoi(argv[3]); + mode = atoi(argv[4]); + printf("port: %x, mode: %x\n", port, mode); + + /*Check the input parameters is right or not.*/ + if (port > SWITCH_MAX_PORT || mode > 3) { + printf(HELP_VLAN_PORT_MODE); + return; + } + + reg = 0x2004 + port * 0x100; + reg_read(reg, &value); + value &= (~((1 << 0) | (1 << 1))); + value |= (mode & 0x3); + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} + +void doVlanSetEgressTagPCR(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char eg_tag = 0; + unsigned int value; + unsigned int reg; + + port = atoi(argv[3]); + eg_tag = atoi(argv[4]); + + printf("port: %d, eg_tag: %d\n", port, eg_tag); + + /*Check the input parameters is right or not.*/ + if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PCR_EG_TAG_RELMASK)) { + printf(HELP_VLAN_EGRESS_TAG_PCR); + return; + } + + reg = REG_PCR_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= (~REG_PCR_EG_TAG_MASK); + value |= ((unsigned int)eg_tag << REG_PCR_EG_TAG_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); + +} /*end doVlanSetEgressTagPCR*/ + +void doVlanSetEgressTagPVC(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char eg_tag = 0; + unsigned int value; + unsigned int reg; + + port = atoi(argv[3]); + eg_tag = atoi(argv[4]); + + printf("port: %d, eg_tag: %d\n", port, eg_tag); + + /*Check the input parameters is right or not.*/ + if ((port > SWITCH_MAX_PORT) || (eg_tag > REG_PVC_EG_TAG_RELMASK)) { + printf(HELP_VLAN_EGRESS_TAG_PVC); + return; + } + + reg = REG_PVC_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= (~REG_PVC_EG_TAG_MASK); + value |= ((unsigned int)eg_tag << REG_PVC_EG_TAG_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} /*end doVlanSetEgressTagPVC*/ + +void doArlAging(int argc, char *argv[]) +{ + unsigned char aging_en = 0; + unsigned int time = 0, aging_cnt = 0, aging_unit = 0, value, reg; + ; + + aging_en = atoi(argv[3]); + time = atoi(argv[4]); + printf("aging_en: %x, aging time: %x\n", aging_en, time); + + /*Check the input parameters is right or not.*/ + if ((aging_en != 0 && aging_en != 1) || (time <= 0 || time > 65536)) { + printf(HELP_ARL_AGING); + return; + } + + reg = 0xa0; + reg_read(reg, &value); + value &= (~(1 << 20)); + if (!aging_en) { + value |= (1 << 20); + } + + aging_unit = (time / 0x100) + 1; + aging_cnt = (time / aging_unit); + aging_unit--; + aging_cnt--; + + value &= (0xfff00000); + value |= ((aging_cnt << 12) | aging_unit); + + printf("aging_unit: %x, aging_cnt: %x\n", aging_unit, aging_cnt); + printf("write reg: %x, value: %x\n", reg, value); + + reg_write(reg, value); +} + +void doMirrorEn(int argc, char *argv[]) +{ + unsigned char mirror_en; + unsigned char mirror_port; + unsigned int value, reg; + + mirror_en = atoi(argv[3]); + mirror_port = atoi(argv[4]); + + printf("mirror_en: %d, mirror_port: %d\n", mirror_en, mirror_port); + + /*Check the input parameters is right or not.*/ + if ((mirror_en > 1) || (mirror_port > REG_CFC_MIRROR_PORT_RELMASK)) { + printf(HELP_MIRROR_EN); + return; + } + + reg = REG_CFC_ADDR; + reg_read(reg, &value); + value &= (~REG_CFC_MIRROR_EN_MASK); + value |= (mirror_en << REG_CFC_MIRROR_EN_OFFT); + value &= (~REG_CFC_MIRROR_PORT_MASK); + value |= (mirror_port << REG_CFC_MIRROR_PORT_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); + +} /*end doMirrorEn*/ + +void doMirrorPortBased(int argc, char *argv[]) +{ + unsigned char port, port_tx_mir, port_rx_mir, vlan_mis, acl_mir, igmp_mir; + unsigned int value, reg; + + port = atoi(argv[3]); + port_tx_mir = atoi(argv[4]); + port_rx_mir = atoi(argv[5]); + acl_mir = atoi(argv[6]); + vlan_mis = atoi(argv[7]); + igmp_mir = atoi(argv[8]); + + printf("port:%d, port_tx_mir:%d, port_rx_mir:%d, acl_mir:%d, vlan_mis:%d, igmp_mir:%d\n", port, port_tx_mir, port_rx_mir, acl_mir, vlan_mis, igmp_mir); + + /*Check the input parameters is right or not.*/ + //if((port >= vlanCap->max_port_no) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)){ + if ((port >= 7) || (port_tx_mir > 1) || (port_rx_mir > 1) || (acl_mir > 1) || (vlan_mis > 1)) { // also allow CPU port (port6) + printf(HELP_MIRROR_PORTBASED); + return; + } + + reg = REG_PCR_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= ~(REG_PORT_TX_MIR_MASK | REG_PORT_RX_MIR_MASK | REG_PCR_ACL_MIR_MASK | REG_PCR_VLAN_MIS_MASK); + value |= (port_tx_mir << REG_PORT_TX_MIR_OFFT) + (port_rx_mir << REG_PORT_RX_MIR_OFFT); + value |= (acl_mir << REG_PCR_ACL_MIR_OFFT) + (vlan_mis << REG_PCR_VLAN_MIS_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); + + reg = REG_PIC_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= ~(REG_PIC_IGMP_MIR_MASK); + value |= (igmp_mir << REG_PIC_IGMP_MIR_OFFT); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); + +} /*end doMirrorPortBased*/ + +void doStp(int argc, char *argv[]) +{ + unsigned char port = 0; + unsigned char fid = 0; + unsigned char state = 0; + unsigned int value; + unsigned int reg; + + port = atoi(argv[2]); + fid = atoi(argv[3]); + state = atoi(argv[4]); + + printf("port: %d, fid: %d, state: %d\n", port, fid, state); + + /*Check the input parameters is right or not.*/ + if ((port > MAX_PORT + 1) || (fid > 7) || (state > 3)) { + printf(HELP_STP); + return; + } + + reg = REG_SSC_P0_ADDR + port * 0x100; + reg_read(reg, &value); + value &= (~(3 << (fid << 2))); + value |= ((unsigned int)state << (fid << 2)); + + printf("write reg: %x, value: %x\n", reg, value); + reg_write(reg, value); +} + +int ingress_rate_set(int on_off, unsigned int port, unsigned int bw) +{ + unsigned int reg, value; + + reg = 0x1800 + (0x100 * port); + value = 0; + /*token-bucket*/ + if (on_off == 1) { + if (chip_name == 0x7530) { + if (bw > 1000000) { + printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw); + return -1; + } + value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0x0f; + } else if (chip_name == 0x7531 || chip_name == 0x7988) { + if ((chip_name == 0x7531) && (bw > 2500000)) { + printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw); + return -1; + } + + if ((chip_name == 0x7988) && (bw > 4000000)) { + printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw); + return -1; + } + + if (bw/32 >= 65536) //supoort 2.5G case + value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf; + else + value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf; + } + else + printf("unknow chip\n"); + } + +#if leaky_bucket + reg_read(reg, &value); + value &= 0xffff0000; + if (on_off == 1) + { + value |= on_off << 15; + //7530 same as 7531 + if (bw < 100) { + value |= (0x0 << 8); + value |= bw; + } else if (bw < 1000) { + value |= (0x1 << 8); + value |= bw / 10; + } else if (bw < 10000) { + value |= (0x2 << 8); + value |= bw / 100; + } else if (bw < 100000) { + value |= (0x3 << 8); + value |= bw / 1000; + } else { + value |= (0x4 << 8); + value |= bw / 10000; + } + } +#endif + reg_write(reg, value); + reg = 0x1FFC; + reg_read(reg, &value); + value = 0x110104; + reg_write(reg, value); + return 0; +} + +int egress_rate_set(int on_off, int port, int bw) +{ + unsigned int reg, value; + + reg = 0x1040 + (0x100 * port); + value = 0; + /*token-bucket*/ + if (on_off == 1) { + if (chip_name == 0x7530) { + if (bw < 0 || bw > 1000000) { + printf("\n**Charge rate(%d) is larger than line rate(1000000kbps)**\n",bw); + return -1; + } + value = ((bw / 32) << 16) + (1 << 15) + (7 << 8) + (1 << 7) + 0xf; + } else if (chip_name == 0x7531 || chip_name == 0x7988) { + if ((chip_name == 0x7531) && (bw < 0 || bw > 2500000)) { + printf("\n**Charge rate(%d) is larger than line rate(2500000kbps)**\n",bw); + return -1; + } + if ((chip_name == 0x7988) && (bw < 0 || bw > 4000000)) { + printf("\n**Charge rate(%d) is larger than line rate(4000000kbps)**\n",bw); + return -1; + } + + if (bw/32 >= 65536) //support 2.5G cases + value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (1 << 12) + (7 << 8) + 0xf; + else + value = ((bw / 32) << 16) + (1 << 15) + (1 << 14) + (7 << 8) + 0xf; + } + else + printf("unknow chip\n"); + } + reg_write(reg, value); + reg = 0x10E0; + reg_read(reg, &value); + value &= 0x18; + reg_write(reg, value); + + return 0; +} + +void rate_control(int argc, char *argv[]) +{ + unsigned char dir = 0; + unsigned char port = 0; + unsigned int rate = 0; + + dir = atoi(argv[2]); + port = atoi(argv[3]); + rate = atoi(argv[4]); + + if (port > 6) + return; + + if (dir == 1) //ingress + ingress_rate_set(1, port, rate); + else if (dir == 0) //egress + egress_rate_set(1, port, rate); + else + return; +} + +int collision_pool_enable(int argc, char *argv[]) +{ + + unsigned char enable; + unsigned int value, reg; + + enable = atoi(argv[3]); + + + printf("collision pool enable: %d \n", enable); + + /*Check the input parameters is right or not.*/ + if (enable > 1) { + printf(HELP_COLLISION_POOL_EN); + return -1; + } + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg = REG_CPGC_ADDR; + if(enable == 1) { + /* active reset */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_RST_N_MASK); + reg_write(reg, value); + + /* enanble clock */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_CLK_EN_MASK); + value |= (1 << REG_CPCG_COL_CLK_EN_OFFT); + reg_write(reg, value); + + /* inactive reset */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_RST_N_MASK); + value |= (1 << REG_CPCG_COL_RST_N_OFFT); + reg_write(reg, value); + + /* enable collision pool */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_EN_MASK); + value |= (1 << REG_CPCG_COL_EN_OFFT); + reg_write(reg, value); + + reg_read(reg, &value); + printf("write reg: %x, value: %x\n", reg, value); + }else { + + /* disable collision pool */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_EN_MASK); + reg_write(reg, value); + + /* active reset */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_RST_N_MASK); + reg_write(reg, value); + + /* inactive reset */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_RST_N_MASK); + value |= (1 << REG_CPCG_COL_RST_N_OFFT); + reg_write(reg, value); + + /* disable clock */ + reg_read(reg, &value); + value &= (~REG_CPCG_COL_CLK_EN_MASK); + reg_write(reg, value); + + reg_read(reg, &value); + printf("write reg: %x, value: %x\n", reg, value); + + } + }else{ + printf("\nCommand not support by this chip.\n"); +} + + return 0; +} + +void collision_pool_mac_dump() +{ + unsigned int value, reg; + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg = REG_CPGC_ADDR; + reg_read(reg, &value); + if(value & REG_CPCG_COL_EN_MASK) + table_dump_internal(COLLISION_TABLE); + else + printf("\ncollision pool is disabled, please enable it before use this command.\n"); + }else { + printf("\nCommand not support by this chip.\n"); + } +} + +void collision_pool_dip_dump() +{ + unsigned int value, reg; + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg = REG_CPGC_ADDR; + reg_read(reg, &value); + if(value & REG_CPCG_COL_EN_MASK) + dip_dump_internal(COLLISION_TABLE); + else + printf("\ncollision pool is disabled, please enable it before use this command.\n"); + }else { + printf("\nCommand not support by this chip.\n"); + } + + +} + +void collision_pool_sip_dump() +{ + unsigned int value, reg; + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg = REG_CPGC_ADDR; + reg_read(reg, &value); + if(value & REG_CPCG_COL_EN_MASK) + sip_dump_internal(COLLISION_TABLE); + else + printf("\ncollision pool is disabled, please enable it before use this command.\n"); + }else { + printf("\nCommand not support by this chip.\n"); + } + + +} + +void pfc_get_rx_counter(int argc, char *argv[]) +{ + int port; + unsigned int value, reg; + unsigned int user_pri; + + port = strtoul(argv[3], NULL, 0); + if (port < 0 || 6 < port) { + printf("wrong port range, should be within 0~6\n"); + return; + } + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg= PFC_RX_COUNTER_L(port); + reg_read(reg, &value); + user_pri = value & 0xff; + printf("\n port %d rx pfc (up=0)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff00) >> 8; + printf("\n port %d rx pfc (up=1)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff0000) >> 16; + printf("\n port %d rx pfc (up=2)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff000000) >> 24; + printf("\n port %d rx pfc (up=3)pause on counter is %d.\n", port,user_pri); + + reg= PFC_RX_COUNTER_H(port); + reg_read(reg, &value); + user_pri = value & 0xff; + printf("\n port %d rx pfc (up=4)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff00) >> 8; + printf("\n port %d rx pfc (up=5)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff0000) >> 16; + printf("\n port %d rx pfc (up=6)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff000000) >> 24; + printf("\n port %d rx pfc (up=7)pause on counter is %d.\n", port,user_pri); + + /* for rx counter could be updated successfully */ + reg_read(PMSR_P(port), &value); + reg_read(PMSR_P(port), &value); + }else { + printf("\nCommand not support by this chip.\n"); + } + +} + +void pfc_get_tx_counter(int argc, char *argv[]) +{ + int port; + unsigned int value, reg; + unsigned int user_pri; + + port = strtoul(argv[3], NULL, 0); + if (port < 0 || 6 < port) { + printf("wrong port range, should be within 0~6\n"); + return; + } + + if (chip_name == 0x7531 || chip_name == 0x7988) { + reg= PFC_TX_COUNTER_L(port); + reg_read(reg, &value); + user_pri = value & 0xff; + printf("\n port %d tx pfc (up=0)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff00) >> 8; + printf("\n port %d tx pfc (up=1)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff0000) >> 16; + printf("\n port %d tx pfc (up=2)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff000000) >> 24; + printf("\n port %d tx pfc (up=3)pause on counter is %d.\n", port,user_pri); + + reg= PFC_TX_COUNTER_H(port); + reg_read(reg, &value); + user_pri = value & 0xff; + printf("\n port %d tx pfc (up=4)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff00) >> 8; + printf("\n port %d tx pfc (up=5)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff0000) >> 16; + printf("\n port %d tx pfc (up=6)pause on counter is %d.\n", port,user_pri); + user_pri = (value & 0xff000000) >> 24; + printf("\n port %d tx pfc (up=7)pause on counter is %d.\n", port,user_pri); + + /* for tx counter could be updated successfully */ + reg_read(PMSR_P(port), &value); + reg_read(PMSR_P(port), &value); + }else { + printf("\nCommand not support by this chip.\n"); + } +} + +void read_output_queue_counters() +{ + unsigned int port=0; + unsigned int value, output_queue; + unsigned int base=0x220; + + for (port = 0; port < 7; port++) { + reg_write(0x7038, base + (port *4)); + reg_read(0x7034, &value); + output_queue = value & 0xff; + printf("\n port %d output queue 0 counter is %d.\n", port,output_queue); + output_queue = (value & 0xff00) >> 8; + printf("\n port %d output queue 1 counter is %d.\n", port,output_queue); + + reg_write(0x7038, base + (port *4) + 1); + reg_read(0x7034, &value); + output_queue = value & 0xff; + printf("\n port %d output queue 2 counter is %d.\n", port,output_queue); + output_queue = (value & 0xff00) >> 8; + printf("\n port %d output queue 3 counter is %d.\n", port,output_queue); + + reg_write(0x7038, base + (port *4) + 2); + reg_read(0x7034, &value); + output_queue = value & 0xff; + printf("\n port %d output queue 4 counter is %d.\n", port,output_queue); + output_queue = (value & 0xff00) >> 8; + printf("\n port %d output queue 5 counter is %d.\n", port,output_queue); + + reg_write(0x7038, base + (port *4) + 3); + reg_read(0x7034, &value); + output_queue = value & 0xff; + printf("\n port %d output queue 6 counter is %d.\n", port,output_queue); + output_queue = (value & 0xff00) >> 8; + printf("\n port %d output queue 7 counter is %d.\n", port,output_queue); + } +} + +void read_free_page_counters() +{ + unsigned int value; + unsigned int free_page,free_page_last_read; + unsigned int fc_free_blk_lothd,fc_free_blk_hithd; + unsigned int fc_port_blk_thd,fc_port_blk_hi_thd; + unsigned int queue[8]={0}; + + if (chip_name == 0x7531 || chip_name == 0x7988) { + /* get system free page link counter*/ + reg_read(0x1fc0, &value); + free_page = value & 0xFFF; + free_page_last_read = (value & 0xFFF0000) >> 16; + + /* get system flow control waterwark */ + reg_read(0x1fe0, &value); + fc_free_blk_lothd = value & 0x3FF; + fc_free_blk_hithd = (value & 0x3FF0000) >> 16; + + /* get port flow control waterwark */ + reg_read(0x1fe4, &value); + fc_port_blk_thd = value & 0x3FF; + fc_port_blk_hi_thd = (value & 0x3FF0000) >> 16; + + /* get queue flow control waterwark */ + reg_read(0x1fe8, &value); + queue[0]= value & 0x3F; + queue[1]= (value & 0x3F00) >> 8; + queue[2]= (value & 0x3F0000) >> 16; + queue[3]= (value & 0x3F000000) >> 24; + reg_read(0x1fec, &value); + queue[4]= value & 0x3F; + queue[5]= (value & 0x3F00) >> 8; + queue[6]= (value & 0x3F0000) >> 16; + queue[7]= (value & 0x3F000000) >> 24; + } else { + /* get system free page link counter*/ + reg_read(0x1fc0, &value); + free_page = value & 0x3FF; + free_page_last_read = (value & 0x3FF0000) >> 16; + + /* get system flow control waterwark */ + reg_read(0x1fe0, &value); + fc_free_blk_lothd = value & 0xFF; + fc_free_blk_hithd = (value & 0xFF00) >> 8; + + /* get port flow control waterwark */ + reg_read(0x1fe0, &value); + fc_port_blk_thd = (value & 0xFF0000) >> 16; + reg_read(0x1ff4, &value); + fc_port_blk_hi_thd = (value & 0xFF00) >> 8; + + /* get queue flow control waterwark */ + reg_read(0x1fe4, &value); + queue[0]= value & 0xF; + queue[1]= (value & 0xF0) >> 4; + queue[2]= (value & 0xF00) >> 8; + queue[3]= (value & 0xF000) >>12; + queue[4]= (value & 0xF0000) >>16; + queue[5]= (value & 0xF00000) >> 20; + queue[6]= (value & 0xF000000) >> 24; + queue[7]= (value & 0xF0000000) >> 28; + } + + printf("<===Free Page=======Current=======Last Read access=====> \n "); + printf(" \n "); + printf(" page counter %u %u \n ",free_page,free_page_last_read); + printf(" \n "); + printf("========================================================= \n "); + printf("<===Type=======High threshold======Low threshold=========\n "); + printf(" \n "); + printf(" system: %u %u \n", fc_free_blk_hithd*2, fc_free_blk_lothd*2); + printf(" port: %u %u \n", fc_port_blk_hi_thd*2, fc_port_blk_thd*2); + printf(" queue 0: %u NA \n", queue[0]); + printf(" queue 1: %u NA \n", queue[1]); + printf(" queue 2: %u NA \n", queue[2]); + printf(" queue 3: %u NA \n", queue[3]); + printf(" queue 4: %u NA \n", queue[4]); + printf(" queue 5: %u NA \n", queue[5]); + printf(" queue 6: %u NA \n", queue[6]); + printf(" queue 7: %u NA \n", queue[7]); + printf("=========================================================\n "); +} + +void eee_enable(int argc, char *argv[]) +{ + unsigned long enable; + unsigned int value; + unsigned int eee_cap; + unsigned int eee_en_bitmap = 0; + unsigned long port_map; + long port_num = -1; + int p; + + if (argc < 3) + goto error; + + /*Check the input parameters is right or not.*/ + if (!strncmp(argv[2], "enable", 7)) + enable = 1; + else if (!strncmp(argv[2], "disable", 8)) + enable = 0; + else + goto error; + + if (argc > 3) { + if (strlen(argv[3]) == 1) { + port_num = strtol(argv[3], (char **)NULL, 10); + if (port_num < 0 || port_num > MAX_PHY_PORT - 1) { + printf("Illegal port index and port:0~4\n"); + goto error; + } + port_map = 1 << port_num; + } else if (strlen(argv[3]) == 5) { + port_map = 0; + for (p = 0; p < MAX_PHY_PORT; p++) { + if (argv[3][p] != '0' && argv[3][p] != '1') { + printf("portmap format error, should be combination of 0 or 1\n"); + goto error; + } + port_map |= ((argv[3][p] - '0') << p); + } + } else { + printf("port_no or portmap format error, should be length of 1 or 5\n"); + goto error; + } + } else { + port_map = 0x1f; + } + + eee_cap = (enable)? 6: 0; + for (p = 0; p < MAX_PHY_PORT; p++) { + /* port_map describe p0p1p2p3p4 from left to rignt */ + if(!!(port_map & (1 << p))) + mii_mgr_c45_write(p, 0x7, 0x3c, eee_cap); + + mii_mgr_c45_read(p, 0x7, 0x3c, &value); + /* mt7531: Always readback eee_cap = 0 when global EEE switch + * is turned off. + */ + if (value | eee_cap) + eee_en_bitmap |= (1 << (MAX_PHY_PORT - 1 - p)); + } + + /* Turn on/off global EEE switch */ + if (chip_name == 0x7531 || chip_name == 0x7988) { + mii_mgr_c45_read(0, 0x1f, 0x403, &value); + if (eee_en_bitmap) + value |= (1 << 6); + else + value &= ~(1 << 6); + mii_mgr_c45_write(0, 0x1f, 0x403, value); + } else { + printf("\nCommand not support by this chip.\n"); + } + + printf("EEE(802.3az) %s", (enable)? "enable": "disable"); + if (argc == 4) { + if (port_num >= 0) + printf(" port%ld", port_num); + else + printf(" port_map: %s", argv[3]); + } else { + printf(" all ports"); + } + printf("\n"); + + return; +error: + printf(HELP_EEE_EN); + return; +} + +void eee_dump(int argc, char *argv[]) +{ + unsigned int cap, lp_cap; + long port = -1; + int p; + + if (argc > 3) { + if (strlen(argv[3]) > 1) { + printf("port# format error, should be of length 1\n"); + return; + } + + port = strtol(argv[3], (char **)NULL, 0); + if (port < 0 || port > MAX_PHY_PORT) { + printf("port# format error, should be 0 to %d\n", + MAX_PHY_PORT); + return; + } + } + + for (p = 0; p < MAX_PHY_PORT; p++) { + if (port >= 0 && p != port) + continue; + + mii_mgr_c45_read(p, 0x7, 0x3c, &cap); + mii_mgr_c45_read(p, 0x7, 0x3d, &lp_cap); + printf("port%d EEE cap=0x%02x, link partner EEE cap=0x%02x", + p, cap, lp_cap); + + if (port >= 0 && p == port) { + mii_mgr_c45_read(p, 0x3, 0x1, &cap); + printf(", st=0x%03x", cap); + } + printf("\n"); + } +} + +void dump_each_port(unsigned int base) +{ + unsigned int pkt_cnt = 0; + int i = 0; + + for (i = 0; i < 7; i++) { + reg_read((base) + (i * 0x100), &pkt_cnt); + printf("%8u ", pkt_cnt); + } + printf("\n"); +} + +void read_mib_counters() +{ + printf("===================== %8s %8s %8s %8s %8s %8s %8s\n", + "Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6"); + printf("Tx Drop Packet :"); + dump_each_port(0x4000); + printf("Tx CRC Error :"); + dump_each_port(0x4004); + printf("Tx Unicast Packet :"); + dump_each_port(0x4008); + printf("Tx Multicast Packet :"); + dump_each_port(0x400C); + printf("Tx Broadcast Packet :"); + dump_each_port(0x4010); + printf("Tx Collision Event :"); + dump_each_port(0x4014); + printf("Tx Pause Packet :"); + dump_each_port(0x402C); + printf("Rx Drop Packet :"); + dump_each_port(0x4060); + printf("Rx Filtering Packet :"); + dump_each_port(0x4064); + printf("Rx Unicast Packet :"); + dump_each_port(0x4068); + printf("Rx Multicast Packet :"); + dump_each_port(0x406C); + printf("Rx Broadcast Packet :"); + dump_each_port(0x4070); + printf("Rx Alignment Error :"); + dump_each_port(0x4074); + printf("Rx CRC Error :"); + dump_each_port(0x4078); + printf("Rx Undersize Error :"); + dump_each_port(0x407C); + printf("Rx Fragment Error :"); + dump_each_port(0x4080); + printf("Rx Oversize Error :"); + dump_each_port(0x4084); + printf("Rx Jabber Error :"); + dump_each_port(0x4088); + printf("Rx Pause Packet :"); + dump_each_port(0x408C); +} + +void clear_mib_counters() +{ + reg_write(0x4fe0, 0xf0); + read_mib_counters(); + reg_write(0x4fe0, 0x800000f0); +} + + +void exit_free() +{ + free(attres); + attres = NULL; + switch_ioctl_fini(); + mt753x_netlink_free(); +} diff --git a/package/mtk/applications/switch/src/switch_fun.h b/package/mtk/applications/switch/src/switch_fun.h new file mode 100644 index 0000000000..70e4d1860b --- /dev/null +++ b/package/mtk/applications/switch/src/switch_fun.h @@ -0,0 +1,144 @@ +/* +* switch_fun.h: switch function sets +*/ +#ifndef SWITCH_FUN_H +#define SWITCH_FUN_H + +#include + +#define MT7530_T10_TEST_CONTROL 0x145 + +#define MAX_PORT 6 +#define MAX_PHY_PORT 5 +#define CONFIG_MTK_7531_DVT 1 + +extern int chip_name; +extern struct mt753x_attr *attres; +extern bool nl_init_flag; + +/*basic operation*/ +int reg_read(unsigned int offset, unsigned int *value); +int reg_write(unsigned int offset, unsigned int value); +int mii_mgr_read(unsigned int port_num, unsigned int reg, unsigned int *value); +int mii_mgr_write(unsigned int port_num, unsigned int reg, unsigned int value); +int mii_mgr_c45_read(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int *value); +int mii_mgr_c45_write(unsigned int port_num, unsigned int dev, unsigned int reg, unsigned int value); + +/*phy setting*/ +int phy_dump(int phy_addr); +void phy_crossover(int argc, char *argv[]); +int rw_phy_token_ring(int argc, char *argv[]); +/*arl setting*/ +void doArlAging(int argc, char *argv[]); + +/*acl setting*/ +void acl_mac_add(int argc, char *argv[]); +void acl_dip_meter(int argc, char *argv[]); +void acl_dip_trtcm(int argc, char *argv[]); +void acl_ethertype(int argc, char *argv[]); +void acl_ethertype(int argc, char *argv[]); +void acl_dip_modify(int argc, char *argv[]); +void acl_dip_pppoe(int argc, char *argv[]); +void acl_dip_add(int argc, char *argv[]); +void acl_l4_add(int argc, char *argv[]); +void acl_sp_add(int argc, char *argv[]); + +void acl_port_enable(int argc, char *argv[]); +void acl_table_add(int argc, char *argv[]); +void acl_mask_table_add(int argc, char *argv[]); +void acl_rule_table_add(int argc, char *argv[]); +void acl_rate_table_add(int argc, char *argv[]); + +/*dip table*/ +void dip_dump(void); +void dip_add(int argc, char *argv[]); +void dip_del(int argc, char *argv[]); +void dip_clear(void); + +/*sip table*/ +void sip_dump(void); +void sip_add(int argc, char *argv[]); +void sip_del(int argc, char *argv[]); +void sip_clear(void); + +/*stp*/ +void doStp(int argc, char *argv[]); + +/*mac table*/ +void table_dump(void); +void table_add(int argc, char *argv[]); +void table_search_mac_vid(int argc, char *argv[]); +void table_search_mac_fid(int argc, char *argv[]); +void table_del_fid(int argc, char *argv[]); +void table_del_vid(int argc, char *argv[]); +void table_clear(void); + +/*vlan table*/ +void vlan_dump(int argc, char *argv[]); +void vlan_clear(int argc, char *argv[]); +void vlan_set(int argc, char *argv[]); + +void doVlanSetPvid(int argc, char *argv[]); +void doVlanSetVid(int argc, char *argv[]); +void doVlanSetAccFrm(int argc, char *argv[]); +void doVlanSetPortAttr(int argc, char *argv[]); +void doVlanSetPortMode(int argc, char *argv[]); +void doVlanSetEgressTagPCR(int argc, char *argv[]); +void doVlanSetEgressTagPVC(int argc, char *argv[]); + +/*igmp function*/ +void igmp_on(int argc, char *argv[]); +void igmp_off(); +void igmp_disable(int argc, char *argv[]); +void igmp_enable(int argc, char *argv[]); + +/*mirror function*/ +void set_mirror_to(int argc, char *argv[]); +void set_mirror_from(int argc, char *argv[]); +void doMirrorPortBased(int argc, char *argv[]); +void doMirrorEn(int argc, char *argv[]); + +/*rate control*/ +void rate_control(int argc, char *argv[]); +int ingress_rate_set(int on_off, unsigned int port, unsigned int bw); +int egress_rate_set(int on_off, int port, int bw); + +/*QoS*/ +int qos_sch_select(int argc, char *argv[]); +void qos_set_base(int argc, char *argv[]); +void qos_wfq_set_weight(int argc, char *argv[]); +void qos_set_portpri(int argc, char *argv[]); +void qos_set_dscppri(int argc, char *argv[]); +void qos_pri_mapping_queue(int argc, char *argv[]); + +/*flow control*/ +int global_set_mac_fc(int argc, char *argv[]); +int phy_set_fc(int argc, char *argv[]); +int phy_set_an(int argc, char *argv[]); + +/* collision pool functions */ +int collision_pool_enable(int argc, char *argv[]); +void collision_pool_mac_dump(); +void collision_pool_dip_dump(); +void collision_pool_sip_dump(); + +/*pfc functions*/ +int set_mac_pfc(int argc, char *argv[]); +void pfc_get_rx_counter(int argc, char *argv[]); +void pfc_get_tx_counter(int argc, char *argv[]); + +/*switch reset*/ +int switch_reset(int argc, char *argv[]); + +/* EEE(802.3az) function */ +void eee_enable(int argc, char *argv[]); +void eee_dump(int argc, char *argv[]); + +void read_mib_counters(); +void clear_mib_counters(); +void read_output_queue_counters(); +void read_free_page_counters(); + +void phy_crossover(int argc, char *argv[]); +void exit_free(); +#endif diff --git a/package/mtk/applications/switch/src/switch_ioctl.c b/package/mtk/applications/switch/src/switch_ioctl.c new file mode 100644 index 0000000000..f6b97d4058 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_ioctl.c @@ -0,0 +1,478 @@ +/* + * switch_ioctl.c: switch(ioctl) set API + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "switch_fun.h" +#include "switch_ioctl.h" + +static int esw_fd; + +int switch_ioctl_init(void) +{ + esw_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (esw_fd < 0) { + perror("socket"); + return -EINVAL; + } + + return 0; +} + +void switch_ioctl_fini(void) +{ + close(esw_fd); +} + +int reg_read_ioctl(unsigned int offset, unsigned int *value) +{ + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + mii.phy_id = 0x1f; + mii.reg_num = offset; + + if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) { + perror("ioctl"); + close(esw_fd); + exit(0); + } + *value = mii.val_out; + return 0; +} + +int reg_read_tr(int offset, int *value) +{ + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + mii.phy_id = 0; + mii.reg_num = offset; + + if (-1 == ioctl(esw_fd, RAETH_MII_READ, &ifr)) { + perror("ioctl"); + close(esw_fd); + exit(0); + } + *value = mii.val_out; + return 0; +} + +int reg_write_ioctl(unsigned int offset, unsigned int value) +{ + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + mii.phy_id = 0x1f; + mii.reg_num = offset; + mii.val_in = value; + + if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) { + perror("ioctl"); + close(esw_fd); + exit(0); + } + return 0; +} + +int reg_write_tr(int offset, int value) +{ + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + mii.phy_id = 0; + mii.reg_num = offset; + mii.val_in = value; + + if (-1 == ioctl(esw_fd, RAETH_MII_WRITE, &ifr)) { + perror("ioctl"); + close(esw_fd); + exit(0); + } + return 0; +} + +int phy_dump_ioctl(unsigned int phy_addr) +{ + struct ifreq ifr; + struct esw_reg reg; + + reg.val = phy_addr; + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = ® + if (-1 == ioctl(esw_fd, RAETH_ESW_PHY_DUMP, &ifr)) { + perror("ioctl"); + close(esw_fd); + exit(0); + } + return 0; +} + +int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, unsigned int *value) +{ + unsigned int reg_value; + int loop_cnt; + int op_busy; + + loop_cnt = 0; + + /*Change to indirect access mode*/ + /*if you need to use direct access mode, please change back manually by reset bit5*/ + if (chip_name == 0x7530) { + reg_read(0x7804, ®_value); + if (((reg_value >> 5) & 0x1) == 0) { + reg_value |= 1 << 5; + reg_write(0x7804, reg_value); + printf("Change to indirect access mode:0x%x\n", + reg_value); + } + } + reg_value = 0x80090000 | (port_num << 20) | (reg << 25); + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) { + reg_value = reg_value & 0xFFFF; + break; + } else if (loop_cnt < 10) + loop_cnt++; + else { + printf("MDIO read opeartion timeout\n"); + reg_value = 0; + break; + } + } + //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value); + *value = reg_value; + + return 0; +} + +int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, unsigned int value) +{ + unsigned int reg_value; + int loop_cnt; + int op_busy; + + loop_cnt = 0; + /*Change to indirect access mode*/ + /*if you need to use direct access mode, please change back manually by reset bit5*/ + if (chip_name == 0x7530) { + reg_read(0x7804, ®_value); + if (((reg_value >> 5) & 0x1) == 0) { + reg_value |= 1 << 5; + reg_write(0x7804, reg_value); + printf("Change to indirect access mode:0x%x\n", + reg_value); + } + } + + reg_value = 0x80050000 | (port_num << 20) | (reg << 25) | value; + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) + break; + else if (loop_cnt < 10) + loop_cnt++; + else { + printf("MDIO write opeartion timeout\n"); + break; + } + } + + //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value); + + return 0; +} + +int mii_mgr_cl45_read_indirect(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int *value) +{ + int sk, method, ret; + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + if (!value) + return -1; + + sk = socket(AF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + printf("Open socket failed\n"); + + return -1; + } + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 13; + mii.val_in = dev; + ret = ioctl(sk, method, &ifr); + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 14; + mii.val_in = reg; + ret = ioctl(sk, method, &ifr); + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 13; + mii.val_in = (0x6000 | dev); + ret = ioctl(sk, method, &ifr); + + usleep(1000); + + method = RAETH_MII_READ; + mii.phy_id = port_num; + mii.reg_num = 14; + ret = ioctl(sk, method, &ifr); + + close(sk); + *value = mii.val_out; + + return ret; +} + +int mii_mgr_cl45_write_indirect(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int value) +{ + int sk, method, ret; + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + sk = socket(AF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + printf("Open socket failed\n"); + + return -1; + } + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 13; + mii.val_in = dev; + ret = ioctl(sk, method, &ifr); + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 14; + mii.val_in = reg; + ret = ioctl(sk, method, &ifr); + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 13; + mii.val_in = (0x6000 | dev); + ret = ioctl(sk, method, &ifr); + + usleep(1000); + + method = RAETH_MII_WRITE; + mii.phy_id = port_num; + mii.reg_num = 14; + mii.val_in = value; + ret = ioctl(sk, method, &ifr); + + close(sk); + + return ret; +} + +int mii_mgr_cl45_read(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int *value) +{ + unsigned int reg_value; + int loop_cnt; + int op_busy; + int ret = 0; + + loop_cnt = 0; + + reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg; + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) { + break; + } else if (loop_cnt < 10) { + loop_cnt++; + } else { + printf("MDIO cl45 set dev opeartion timeout\n"); + reg_value = 0; + ret = -1; + goto out; + } + } + + reg_value = 0x800c0000 | (port_num << 20) | (dev << 25); + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) { + reg_value = reg_value & 0xFFFF; + break; + } else if (loop_cnt < 10) { + loop_cnt++; + } else { + printf("MDIO cl45 read reg opeartion timeout\n"); + reg_value = 0; + ret = -1; + break; + } + } +out: + //printf(" PHY Indirect Access Control(0x701c) register read value =0x%x \n", reg_value); + *value = reg_value; + + return ret; +} + +int mii_mgr_cl45_write(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int value) +{ + unsigned int reg_value; + int loop_cnt; + int op_busy; + int ret = 0; + + loop_cnt = 0; + + reg_value = 0x80000000 | (port_num << 20) | (dev << 25) | reg; + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) + break; + else if (loop_cnt < 10) + loop_cnt++; + else { + printf("MDIO cl45 set dev opeartion timeout\n"); + ret = -1; + goto out; + } + } + + reg_value = 0x80040000 | (port_num << 20) | (dev << 25) | value; + reg_write(0x701c, reg_value); + while (1) + { + reg_read(0x701c, ®_value); + op_busy = reg_value & (1 << 31); + if (!op_busy) + break; + else if (loop_cnt < 10) + loop_cnt++; + else { + printf("MDIO cl45 write reg opeartion timeout\n"); + ret = -1; + break; + } + } +out: + //printf(" PHY Indirect Access Control(0x701c) register write value =0x%x \n", reg_value); + return ret; +} + +int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int *value) +{ + if (chip_name == 0x7531 || chip_name == 0x7988) + return mii_mgr_cl45_read(port_num, dev, reg, value); + else if (chip_name == 0x7530) + return mii_mgr_cl45_read_indirect(port_num, dev, reg, value); + else + return -1; +} + +int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int value) +{ + if (chip_name == 0x7531 || chip_name == 0x7988) + return mii_mgr_cl45_write(port_num, dev, reg, value); + else if (chip_name == 0x7530) + return mii_mgr_cl45_write_indirect(port_num, dev, reg, value); + else + return -1; +} + +int dump_gphy(void) +{ + int cl22_reg[6] = {0x00, 0x01, 0x04, 0x05, 0x09, 0x0A}; + int cl45_start_reg = 0x9B; + int cl45_end_reg = 0xA2; + unsigned int value; + int port_num = 5; + int i, j, ret; + + int sk, method; + struct ifreq ifr; + struct ra_mii_ioctl_data mii; + + sk = socket(AF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + printf("Open socket failed\n"); + return -1; + } + + strncpy(ifr.ifr_name, ETH_DEVNAME, 5); + ifr.ifr_data = &mii; + /* dump CL45 reg first*/ + for (i = 0; i < port_num; i++) { + printf("== Port %d ==\n", i); + for (j = cl45_start_reg; j < (cl45_end_reg + 1); j++) { + ret = mii_mgr_cl45_read_ioctl(i, 0x1E, j, &value); + if (ret) + continue; + printf("dev1Eh_reg%xh = 0x%x\n", j, value); + } + } + printf("== Global ==\n"); + for (i = 0; i < sizeof(cl22_reg) / sizeof(cl22_reg[0]); i++) { + method = RAETH_MII_READ; + mii.phy_id = 0; + mii.reg_num = cl22_reg[i]; + ret = ioctl(sk, method, &ifr); + printf("Reg%xh = 0x%x\n", cl22_reg[i], mii.val_out); + } + + close(sk); + + return ret; +} diff --git a/package/mtk/applications/switch/src/switch_ioctl.h b/package/mtk/applications/switch/src/switch_ioctl.h new file mode 100644 index 0000000000..dffe9c7f05 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_ioctl.h @@ -0,0 +1,70 @@ +/* + * switch_ioctl.h: switch(ioctl) set API + */ + +#ifndef SWITCH_IOCTL_H +#define SWITCH_IOCTL_H + +#define ETH_DEVNAME "eth0" +#define BR_DEVNAME "br-lan" + +#define RAETH_MII_READ 0x89F3 +#define RAETH_MII_WRITE 0x89F4 +#define RAETH_ESW_PHY_DUMP 0x89F7 + +struct esw_reg { + unsigned int off; + unsigned int val; +}; + +struct ra_mii_ioctl_data { + __u16 phy_id; + __u16 reg_num; + __u32 val_in; + __u32 val_out; +/* + __u32 port_num; + __u32 dev_addr; + __u32 reg_addr; +*/ +}; + +struct ra_switch_ioctl_data { + unsigned int cmd; + unsigned int on_off; + unsigned int port; + unsigned int bw; + unsigned int vid; + unsigned int fid; + unsigned int port_map; + unsigned int rx_port_map; + unsigned int tx_port_map; + unsigned int igmp_query_interval; + unsigned int reg_addr; + unsigned int reg_val; + unsigned int mode; + unsigned int qos_queue_num; + unsigned int qos_type; + unsigned int qos_pri; + unsigned int qos_dscp; + unsigned int qos_table_idx; + unsigned int qos_weight; + unsigned char mac[6]; +}; + +extern int chip_name; + +int switch_ioctl_init(void); +void switch_ioctl_fini(void); +int reg_read_ioctl(unsigned int offset, unsigned int *value); +int reg_write_ioctl(unsigned int offset, unsigned int value); +int phy_dump_ioctl(unsigned int phy_addr); +int mii_mgr_cl22_read_ioctl(unsigned int port_num, unsigned int reg, + unsigned int *value); +int mii_mgr_cl22_write_ioctl(unsigned int port_num, unsigned int reg, + unsigned int value); +int mii_mgr_cl45_read_ioctl(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int *value); +int mii_mgr_cl45_write_ioctl(unsigned int port_num, unsigned int dev, + unsigned int reg, unsigned int value); +#endif diff --git a/package/mtk/applications/switch/src/switch_netlink.c b/package/mtk/applications/switch/src/switch_netlink.c new file mode 100644 index 0000000000..90a4a19aa9 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_netlink.c @@ -0,0 +1,445 @@ +/* + * switch_netlink.c: switch(netlink) set API + * + * Author: Sirui Zhao + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "switch_netlink.h" + +static struct nl_sock *user_sock; +static struct nl_cache *cache; +static struct genl_family *family; +static struct nlattr *attrs[MT753X_ATTR_TYPE_MAX + 1]; + +static int wait_handler(struct nl_msg *msg, void *arg) +{ + int *finished = arg; + + *finished = 1; + return NL_STOP; +} + +static int list_swdevs(struct nl_msg *msg, void *arg) +{ + struct mt753x_attr *val = arg; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + if (nla_parse(attrs, MT753X_ATTR_TYPE_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL) < 0) + goto done; + + if (gnlh->cmd == MT753X_CMD_REPLY) { + if (attrs[MT753X_ATTR_TYPE_MESG]) { + val->dev_info = + nla_get_string(attrs[MT753X_ATTR_TYPE_MESG]); + printf("register switch dev:\n%s", val->dev_info); + } + else { + fprintf(stderr, "ERROR:No switch dev now\n"); + goto done; + } + } else + goto done; + return 0; +done: + return NL_SKIP; +} + +static int construct_attrs(struct nl_msg *msg, void *arg) +{ + struct mt753x_attr *val = arg; + int type = val->type; + + if (val->dev_id > -1) + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_DEV_ID, val->dev_id); + + if (val->op == 'r') { + if (val->phy_dev != -1) + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_PHY_DEV, val->phy_dev); + if (val->port_num >= 0) + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_PHY, val->port_num); + NLA_PUT_U32(msg, type, val->reg); + } else if (val->op == 'w') { + if (val->phy_dev != -1) + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_PHY_DEV, val->phy_dev); + if (val->port_num >= 0) + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_PHY, val->port_num); + NLA_PUT_U32(msg, type, val->reg); + NLA_PUT_U32(msg, MT753X_ATTR_TYPE_VAL, val->value); + } else { + printf("construct_attrs_message\n"); + NLA_PUT_STRING(msg, type, "hello"); + } + return 0; + +nla_put_failure: + return -1; +} + +static int spilt_attrs(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct mt753x_attr *val = arg; + char *str; + + if (nla_parse(attrs, MT753X_ATTR_TYPE_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL) < 0) + goto done; + + if ((gnlh->cmd == MT753X_CMD_WRITE) || (gnlh->cmd == MT753X_CMD_READ)) { + if (attrs[MT753X_ATTR_TYPE_MESG]) { + str = nla_get_string(attrs[MT753X_ATTR_TYPE_MESG]); + printf(" %s\n", str); + if (!strncmp(str, "No", 2)) + goto done; + } + if (attrs[MT753X_ATTR_TYPE_REG]) { + val->reg = + nla_get_u32(attrs[MT753X_ATTR_TYPE_REG]); + } + if (attrs[MT753X_ATTR_TYPE_VAL]) { + val->value = + nla_get_u32(attrs[MT753X_ATTR_TYPE_VAL]); + } + } + else + goto done; + + return 0; +done: + return NL_SKIP; +} + +static int mt753x_request_callback(int cmd, int (*spilt)(struct nl_msg *, void *), + int (*construct)(struct nl_msg *, void *), + void *arg) +{ + struct nl_msg *msg; + struct nl_cb *callback = NULL; + int finished; + int flags = 0; + int err; + + /*Allocate an netllink message buffer*/ + msg = nlmsg_alloc(); + if (!msg) { + fprintf(stderr, "Failed to allocate netlink message\n"); + exit(1); + } + if (!construct) { + if (cmd == MT753X_CMD_REQUEST) + flags |= NLM_F_REQUEST; + else + flags |= NLM_F_DUMP; + } + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, genl_family_get_id(family), + 0, flags, cmd, 0); + + /*Fill attaribute of netlink message by construct function*/ + if (construct) { + err = construct(msg, arg); + if (err < 0) { + fprintf(stderr, "attributes error\n"); + goto nal_put_failure; + } + } + + /*Allocate an new callback handler*/ + callback = nl_cb_alloc(NL_CB_CUSTOM); + if (!callback) { + fprintf(stderr, "Failed to allocate callback handler\n"); + exit(1); + } + + /*Send netlink message*/ + err = nl_send_auto_complete(user_sock, msg); + if (err < 0) { + fprintf(stderr, "nl_send_auto_complete failied:%d\n", err); + goto out; + } + finished = 0; + if (spilt) + nl_cb_set(callback, NL_CB_VALID, NL_CB_CUSTOM, spilt, arg); + + if (construct) + nl_cb_set(callback, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, + &finished); + else + nl_cb_set(callback, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, + &finished); + + /*receive message from kernel request*/ + err = nl_recvmsgs(user_sock, callback); + if (err < 0) + goto out; + + /*wait until an ACK is received for the latest not yet acknowledge*/ + if (!finished) + err = nl_wait_for_ack(user_sock); +out: + if (callback) + nl_cb_put(callback); + +nal_put_failure: + nlmsg_free(msg); + return err; +} + +void mt753x_netlink_free(void) +{ + if (family) + nl_object_put((struct nl_object *)family); + if (cache) + nl_cache_free(cache); + if (user_sock) + nl_socket_free(user_sock); + user_sock = NULL; + cache = NULL; + family = NULL; +} + +int mt753x_netlink_init(const char *name) +{ + int ret; + + user_sock = NULL; + cache = NULL; + family = NULL; + + /*Allocate an new netlink socket*/ + user_sock = nl_socket_alloc(); + if (!user_sock) { + fprintf(stderr, "Failed to create user socket\n"); + goto err; + } + /*Connetct the genl controller*/ + if (genl_connect(user_sock)) { + fprintf(stderr, "Failed to connetct to generic netlink\n"); + goto err; + } + /*Allocate an new nl_cache*/ + ret = genl_ctrl_alloc_cache(user_sock, &cache); + if (ret < 0) { + fprintf(stderr, "Failed to allocate netlink cache\n"); + goto err; + } + + if (name == NULL) + return -EINVAL; + + /*Look up generic netlik family by "mt753x" in the provided cache*/ + family = genl_ctrl_search_by_name(cache, name); + if (!family) { + //fprintf(stderr,"switch(mt753x) API not be prepared\n"); + goto err; + } + return 0; +err: + mt753x_netlink_free(); + return -EINVAL; +} + +void mt753x_list_swdev(struct mt753x_attr *arg, int cmd) +{ + int err; + + err = mt753x_request_callback(cmd, list_swdevs, NULL, arg); + if (err < 0) + fprintf(stderr, "mt753x list dev error\n"); +} + +static int mt753x_request(struct mt753x_attr *arg, int cmd) +{ + int err; + + err = mt753x_request_callback(cmd, spilt_attrs, construct_attrs, arg); + if (err < 0) { + fprintf(stderr, "mt753x deal request error\n"); + return err; + } + return 0; +} + +static int phy_operate_netlink(char op, struct mt753x_attr *arg, + unsigned int port_num, unsigned int phy_dev, + unsigned int offset, unsigned int *value) +{ + int ret = 0; + struct mt753x_attr *attr = arg; + + attr->port_num = port_num; + attr->phy_dev = phy_dev; + attr->reg = offset; + attr->value = -1; + attr->type = MT753X_ATTR_TYPE_REG; + + switch (op) + { + case 'r': + attr->op = 'r'; + ret = mt753x_request(attr, MT753X_CMD_READ); + *value = attr->value; + break; + case 'w': + attr->op = 'w'; + attr->value = *value; + ret = mt753x_request(attr, MT753X_CMD_WRITE); + break; + default: + break; + } + + return ret; +} + +int reg_read_netlink(struct mt753x_attr *arg, unsigned int offset, + unsigned int *value) +{ + int ret; + + ret = phy_operate_netlink('r', arg, -1, -1, offset, value); + return ret; +} + +int reg_write_netlink(struct mt753x_attr *arg, unsigned int offset, + unsigned int value) +{ + int ret; + + ret = phy_operate_netlink('w', arg, -1, -1, offset, &value); + return ret; +} + +int phy_cl22_read_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_addr, unsigned int *value) +{ + int ret; + + ret = phy_operate_netlink('r', arg, port_num, -1, phy_addr, value); + return ret; +} + +int phy_cl22_write_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_addr, unsigned int value) +{ + int ret; + + ret = phy_operate_netlink('w', arg, port_num, -1, phy_addr, &value); + return ret; +} + +int phy_cl45_read_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_dev, unsigned int phy_addr, + unsigned int *value) +{ + int ret; + + ret = phy_operate_netlink('r', arg, port_num, phy_dev, phy_addr, value); + return ret; +} + +int phy_cl45_write_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_dev, unsigned int phy_addr, + unsigned int value) +{ + int ret; + + ret = phy_operate_netlink('w', arg, port_num, phy_dev, phy_addr, &value); + return ret; +} + +void dump_extend_phy_reg(struct mt753x_attr *arg, int port_no, int from, + int to, int is_local, int page_no) +{ + unsigned int temp = 0; + int r31 = 0; + int i = 0; + + if (is_local == 0) { + printf("\n\nGlobal Register Page %d\n",page_no); + printf("==============="); + r31 |= 0 << 15; //global + r31 |= ((page_no&0x7) << 12); //page no + phy_cl22_write_netlink(arg, port_no, 31, r31); //select global page x + for (i = 16; i < 32; i++) { + if(i%8 == 0) + printf("\n"); + phy_cl22_read_netlink(arg, port_no, i, &temp); + printf("%02d: %04X ", i, temp); + } + } else { + printf("\n\nLocal Register Port %d Page %d\n",port_no, page_no); + printf("==============="); + r31 |= 1 << 15; //local + r31 |= ((page_no&0x7) << 12); //page no + phy_cl22_write_netlink(arg, port_no, 31, r31); //select global page x + for (i = 16; i < 32; i++) { + if (i%8 == 0) { + printf("\n"); + } + phy_cl22_read_netlink(arg, port_no, i, &temp); + printf("%02d: %04X ",i, temp); + } + } + printf("\n"); +} + +int phy_dump_netlink(struct mt753x_attr *arg, int phy_addr) +{ + int i; + int ret; + unsigned int offset, value; + + if (phy_addr == 32) { + /*dump all phy register*/ + for (i = 0; i < 5; i++) { + printf("\n[Port %d]=============", i); + for (offset = 0; offset < 16; offset++) { + if (offset % 8 == 0) + printf("\n"); + ret = phy_cl22_read_netlink(arg, i, offset, &value); + printf("%02d: %04X ", offset, value); + } + } + } else { + printf("\n[Port %d]=============", phy_addr); + for (offset = 0; offset < 16; offset++) { + if (offset % 8 == 0) + printf("\n"); + ret = phy_cl22_read_netlink(arg, phy_addr, offset, &value); + printf("%02d: %04X ", offset, value); + } + } + printf("\n"); + for (offset = 0; offset < 5; offset++) { //global register page 0~4 + if (phy_addr == 32) //dump all phy register + dump_extend_phy_reg(arg, 0, 16, 31, 0, offset); + else + dump_extend_phy_reg(arg, phy_addr, 16, 31, 0, offset); + } + + if (phy_addr == 32) { //dump all phy register + for (offset = 0; offset < 5; offset++) { //local register port 0-port4 + dump_extend_phy_reg(arg, offset, 16, 31, 1, 0); //dump local page 0 + dump_extend_phy_reg(arg, offset, 16, 31, 1, 1); //dump local page 1 + dump_extend_phy_reg(arg, offset, 16, 31, 1, 2); //dump local page 2 + dump_extend_phy_reg(arg, offset, 16, 31, 1, 3); //dump local page 3 + } + } else { + dump_extend_phy_reg(arg, phy_addr, 16, 31, 1, 0); //dump local page 0 + dump_extend_phy_reg(arg, phy_addr, 16, 31, 1, 1); //dump local page 1 + dump_extend_phy_reg(arg, phy_addr, 16, 31, 1, 2); //dump local page 2 + dump_extend_phy_reg(arg, phy_addr, 16, 31, 1, 3); //dump local page 3 + } + return ret; +} diff --git a/package/mtk/applications/switch/src/switch_netlink.h b/package/mtk/applications/switch/src/switch_netlink.h new file mode 100644 index 0000000000..b3f946efe8 --- /dev/null +++ b/package/mtk/applications/switch/src/switch_netlink.h @@ -0,0 +1,70 @@ +/* + * switch_netlink.h: switch(netlink) set API + * + * Author: Sirui Zhao + */ +#ifndef MT753X_NETLINK_H +#define MT753X_NETLINK_H + +#define MT753X_GENL_NAME "mt753x" +#define MT753X_DSA_GENL_NAME "mt753x_dsa" +#define MT753X_GENL_VERSION 0X1 + +/*add your cmd to here*/ +enum { + MT753X_CMD_UNSPEC = 0, /*Reserved*/ + MT753X_CMD_REQUEST, /*user->kernelrequest/get-response*/ + MT753X_CMD_REPLY, /*kernel->user event*/ + MT753X_CMD_READ, + MT753X_CMD_WRITE, + __MT753X_CMD_MAX, +}; +#define MT753X_CMD_MAX (__MT753X_CMD_MAX - 1) + +/*define attar types */ +enum +{ + MT753X_ATTR_TYPE_UNSPEC = 0, + MT753X_ATTR_TYPE_MESG, /*MT753X message*/ + MT753X_ATTR_TYPE_PHY, + MT753X_ATTR_TYPE_PHY_DEV, + MT753X_ATTR_TYPE_REG, + MT753X_ATTR_TYPE_VAL, + MT753X_ATTR_TYPE_DEV_NAME, + MT753X_ATTR_TYPE_DEV_ID, + __MT753X_ATTR_TYPE_MAX, +}; +#define MT753X_ATTR_TYPE_MAX (__MT753X_ATTR_TYPE_MAX - 1) + +struct mt753x_attr { + int port_num; + int phy_dev; + int reg; + int value; + int type; + char op; + char *dev_info; + int dev_name; + int dev_id; +}; + +int mt753x_netlink_init(const char *name); +void mt753x_netlink_free(void); +void mt753x_list_swdev(struct mt753x_attr *arg, int cmd); +int reg_read_netlink(struct mt753x_attr *arg, unsigned int offset, + unsigned int *value); +int reg_write_netlink(struct mt753x_attr *arg, unsigned int offset, + unsigned int value); +int phy_cl22_read_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_addr, unsigned int *value); +int phy_cl22_write_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_addr, unsigned int value); +int phy_cl45_read_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_dev, unsigned int phy_addr, + unsigned int *value); +int phy_cl45_write_netlink(struct mt753x_attr *arg, unsigned int port_num, + unsigned int phy_dev, unsigned int phy_addr, + unsigned int value); +int phy_dump_netlink(struct mt753x_attr *arg, int phy_addr); + +#endif diff --git a/package/mtk/drivers/connectivity/conninfra/Makefile b/package/mtk/drivers/connectivity/conninfra/Makefile new file mode 100644 index 0000000000..7973852753 --- /dev/null +++ b/package/mtk/drivers/connectivity/conninfra/Makefile @@ -0,0 +1,112 @@ +# +# Copyright (C) 2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=conninfra +PKG_VERSION:= +PKG_SOURCE:=mt7981_conninfra_20220425-bbf588-obj.tar.xz +PKG_SOURCE_URL:= +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME) +PKG_MAINTAINER:=Kun-Ze Syue + +PKG_KCONFIG:= \ + MTK_CONNINFRA_APSOC \ + MTK_CONNINFRA_APSOC_MT7986 \ + MTK_CONNINFRA_APSOC_MT7981 \ + CONNINFRA_EMI_SUPPORT \ + FPGA_EARLY_PORTING \ + CONNINFRA_AUTO_UP + +include $(INCLUDE_DIR)/package.mk + +# Specify package information for this program. +define KernelPackage/conninfra + CATEGORY:=MTK Properties + TITLE:= Conninfra driver + FILES:=$(PKG_BUILD_DIR)/conninfra.ko + AUTOLOAD:=$(call AutoLoad,10,conninfra,1) + SUBMENU:=Drivers + MENU:=1 +endef + +define KernelPackage/conninfra/description + Support for connectivity conninfra driver. +endef + +define KernelPackage/conninfra/config +if PACKAGE_kmod-conninfra + config MTK_CONNINFRA_APSOC + bool "Conninfra APSOC Only" + default n + +if MTK_CONNINFRA_APSOC +choice + prompt "Choose APSOC Chip" + config MTK_CONNINFRA_APSOC_MT7986 + bool "MT7986" + default n + + config MTK_CONNINFRA_APSOC_MT7981 + bool "MT7981" + default n + +endchoice + config CONNINFRA_EMI_SUPPORT + bool "EMI Support" + default n + + config FPGA_EARLY_PORTING + bool "Only for FPGA Stage" + default n + + config CONNINFRA_AUTO_UP + bool "Conninfra Up by Self" + default n +endif +endif +endef + +# Specify what needs to be done to prepare for building the package. + +# Specify where and how to install the program. +#define Package/kmod-conninfra/install +# true +#endef + +# Transfer local kernel config to compile option +KCONFIG_FLAGS:=$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_$c),CONFIG_$(c)=$(CONFIG_$(c)))) + +$(info $$KCONFIG_FLAGS is [${KCONFIG_FLAGS}]) + +# Transfer local kernel config to compile option +EXTRA_CFLAGS:= \ + $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(KCONFIG_FLAGS)))) \ + $(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(KCONFIG_FLAGS)))) \ + $(patsubst CONFIG_%, -DCONFIG_%=0, $(patsubst %=n,%,$(filter %=n,$(KCONFIG_FLAGS)))) \ + +EXTRA_CFLAGS+=-DEEPROM_NAME=${CONFIG_first_card_EEPROM_name} + +$(info EXTRA_CFLAGS=${EXTRA_CFLAGS}) + +MAKE_OPTS:= \ + $(KERNEL_MAKE_FLAGS) \ + SUBDIRS="$(PKG_BUILD_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + M="$(PKG_BUILD_DIR)" \ + EXTRA_CFLAGS="$(EXTRA_CFLAGS)" \ + $(KCONFIG_FLAGS) + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" \ + $(MAKE_OPTS) \ + modules +endef + +$(eval $(call KernelPackage,conninfra)) diff --git a/package/mtk/drivers/mt_wifi/Makefile b/package/mtk/drivers/mt_wifi/Makefile new file mode 100644 index 0000000000..2f466a821e --- /dev/null +++ b/package/mtk/drivers/mt_wifi/Makefile @@ -0,0 +1,332 @@ +# All rights reserved. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=mt_wifi +P4REV:= +PKG_VERSION:=7.6.4.1 +PKG_SOURCE:=mt7981_20220425-4c770b-obj.tar.xz +PKG_BUILD_PARALLEL:=1 +PKG_SOURCE_URL:= +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME) +PKG_KCONFIG:= \ + AP_SUPPORT \ + RT_FIRST_CARD \ + RT_SECOND_CARD \ + RT_FIRST_IF_RF_OFFSET \ + RT_SECOND_IF_RF_OFFSET \ + MT_WIFI \ + WIFI_BASIC_FUNC \ + MT_WIFI_PATH \ + FIRST_IF_NONE \ + FIRST_IF_EEPROM_FLASH \ + FIRST_IF_EEPROM_EFUSE \ + RT_FIRST_CARD_EEPROM \ + SECOND_IF_NONE \ + SECOND_IF_EEPROM_FLASH \ + SECOND_IF_EEPROM_PROM \ + SECOND_IF_EEPROM_EFUSE \ + RT_SECOND_CARD_EEPROM \ + MULTI_INF_SUPPORT \ + WIFI_BASIC_FUNC \ + WIRELESS_EXT \ + WEXT_SPY \ + WEXT_PRIV \ + DOT11_N_SUPPORT \ + DOT11_VHT_AC \ + DOT11_HE_AX \ + CFG_SUPPORT_FALCON_MURU \ + CFG_SUPPORT_FALCON_TXCMD_DBG \ + CFG_SUPPORT_FALCON_SR \ + CFG_SUPPORT_FALCON_PP \ + WIFI_DRIVER \ + G_BAND_256QAM_SUPPORT \ + BRCM_256QAM_SUPPORT \ + ICAP_SUPPORT \ + MT_AP_SUPPORT \ + BACKGROUND_SCAN_SUPPORT \ + SMART_CARRIER_SENSE_SUPPORT \ + SCS_FW_OFFLOAD \ + THERMAL_PROTECT_SUPPORT \ + MT_DFS_SUPPORT \ + HDR_TRANS_TX_SUPPORT \ + CHIP_MT7615E \ + HDR_TRANS_RX_SUPPORT \ + DBDC_MODE \ + MULTI_PROFILE_SUPPORT \ + DEFAULT_5G_PROFILE \ + SUPPORT_DYNAMIC_TXOP \ + WSC_INCLUDED \ + MT_STA_SUPPORT \ + WSC_V2_SUPPORT \ + DOT11W_PMF_SUPPORT \ + PASSPOINT_R2 \ + TXBF_SUPPORT \ + IGMP_SNOOP_SUPPORT \ + RATE_ADAPTION \ + RATE_ADAPT_AGBS_SUPPORT \ + RTMP_FLASH_SUPPORT \ + ATE_SUPPORT \ + WLAN_SERVICE \ + UAPSD \ + RLT_MAC \ + RLT_BBP \ + RLT_RF \ + RTMP_MAC \ + RTMP_BBP \ + RTMP_RF \ + RTMP_PCI_SUPPORT \ + RTMP_USB_SUPPORT \ + RTMP_RBUS_SUPPORT \ + WIFI_MODE_AP \ + WIFI_MODE_STA \ + WIRELESS_EXT \ + WEXT_SPY \ + WEXT_PRIV \ + WDS_SUPPORT \ + MBSS_SUPPORT \ + APCLI_SUPPORT \ + APCLI_CERT_SUPPORT \ + APCLI_CONNECTION_TRIAL \ + MAC_REPEATER_SUPPORT \ + RALINK_RT6352 \ + RALINK_MT7620 \ + RALINK_MT7603E \ + CON_WPS_SUPPORT \ + VOW_SUPPORT \ + BAND_STEERING \ + TXOP_ARBITER \ + CFG_SUPPORT_DYNAMIC_TXOP \ + WIFI_MODE_BOTH \ + WIFI_RLT_MAC \ + RLT_MAC \ + WIFI_RTMP_MAC \ + RTMP_MAC \ + WIFI_MT_MAC \ + CHIP_MT7603E \ + CHIP_MT7615E \ + MT_MAC \ + RATE_ADAPTION \ + SUPPORT_OPENWRT \ + SDK_USER_LIGHTY \ + MUMIMO_SUPPORT \ + MU_RA_SUPPORT \ + LED_CONTROL_SUPPORT \ + RA_HW_NAT \ + RA_HW_NAT_WIFI_NEW_ARCH \ + CFG80211_SUPPORT \ + SER_SUPPORT \ + GREENAP_SUPPORT \ + RADIUS_ACCOUNTING_SUPPORT \ + TPC_SUPPORT \ + RLM_CAL_CACHE_SUPPORT \ + CAL_BIN_FILE_SUPPORT \ + RF_LOCKDOWN_SUPPORT \ + PASSPOINT_R2 \ + RED_SUPPORT \ + FIRST_IF_EPAELNA \ + FIRST_IF_IPAILNA \ + FIRST_IF_IPAELNA \ + FIRST_IF_EPAILNA \ + SECOND_IF_EPAELNA \ + SECOND_IF_IPAILNA \ + SECOND_IF_IPAELNA \ + SECOND_IF_EPAILNA \ + THIRD_IF_EPAELNA \ + THIRD_IF_IPAILNA \ + THIRD_IF_IPAELNA \ + THIRD_IF_EPAILNA \ + WIFI_PKT_FWD \ + DOT11K_RRM_SUPPORT \ + DOT11R_FT_SUPPORT \ + ENTERPRISE_AP_SUPPORT \ + WIFI_EAP_FEATURE \ + TXRX_STAT_SUPPORT \ + ANTENNA_CONTROL_SUPPORT \ + MGMT_TXPWR_CTRL \ + TXD_MGMT_TXPWR_CTRL \ + CHUTIL_SUPPORT \ + NF_SUPPORT \ + RA_PHY_RATE_SUPPORT \ + MBSS_DTIM_SUPPORT \ + AMPDU_CONF_SUPPORT \ + ACK_CTS_TIMEOUT_SUPPORT \ + HIGHPRI_RATE_SPECIFIC \ + RADIUS_MAC_AUTH_SUPPORT \ + ZERO_LOSS_CSA_SUPPORT \ + VLAN_SUPPORT \ + DYNAMIC_VLAN_SUPPORT \ + CUSTOMISED_HOSTAPD_SUPPORT \ + HOSTAPD_WPA3_SUPPORT \ + HOSTAPD_WPA3R3_SUPPORT \ + DBDC_ONE_BAND_SUPPORT \ + APCLI_STA_SUPPORT \ + WDS_STA_SUPPORT \ + MBSS_AS_WDS_AP_SUPPORT \ + MBO_SUPPORT \ + MAP_SUPPORT \ + MAP_R2_VER_SUPPORT \ + MAP_R3_VER_SUPPORT \ + QOS_R1_SUPPORT \ + WPA3_SUPPORT \ + OWE_SUPPORT \ + WIFI_PKT_FWD_V1 \ + FIRST_IF_MT7615E \ + FIRST_IF_MT7622 \ + FIRST_IF_MT7626 \ + FIRST_IF_AXE \ + FIRST_IF_MT7915 \ + FIRST_IF_MT7916 \ + FIRST_IF_MT7986 \ + FIRST_IF_MT7981 \ + SECOND_IF_MT7915 \ + SECOND_IF_MT7916 \ + SECOND_IF_MT7615E \ + SECOND_IF_AXE \ + THIRD_IF_NONE \ + THIRD_IF_MT7615E \ + THIRD_IF_MT7916 \ + CHIP_AXE \ + CHIP_MT7915 \ + CHIP_MT7916 \ + CHIP_MT7986 \ + CHIP_MT7981 \ + RT_THIRD_CARD \ + RT_THIRD_IF_RF_OFFSET \ + THIRD_IF_EEPROM_FLASH \ + THIRD_IF_EEPROM_PROM \ + THIRD_IF_EEPROM_EFUSE \ + RT_THIRD_CARD_EEPROM \ + SPECTRUM_SUPPORT \ + PHY_ICS_SUPPORT \ + MULTI_PROFILE_SUPPORT \ + PRE_CAL_TRX_SET1_SUPPORT \ + MWDS \ + MCAST_RATE_SPECIFIC \ + WLAN_HOOK \ + COEX_SUPPORT \ + EASY_SETUP_SUPPORT \ + EVENT_NOTIFIER_SUPPORT \ + AIR_MONITOR \ + OFFCHANNEL_SCAN_FEATURE \ + WNM_SUPPORT \ + INTERWORKING \ + LINUX_NET_TXQ_SUPPORT \ + CHIP_MT7622 \ + CHIP_MT7626 \ + MEMORY_SHRINK \ + MEMORY_SHRINK_AGGRESS \ + RPS_EFFICIENCY \ + WHNAT_SUPPORT \ + FAST_NAT_SUPPORT \ + PRE_CAL_TRX_SET2_SUPPORT \ + LINK_TEST_SUPPORT \ + TCP_RACK_SUPPORT \ + FQ_SCH_SUPPORT \ + BRCM_256QAM_SUPPORT \ + VHT_TXBF_2G_EPIGRAM_IE_SUPPORT \ + DSCP_QOS_MAP_SUPPORT \ + DSCP_PRI_SUPPORT \ + PCIE_ASPM_DYM_CTRL_SUPPORT \ + MIN_PHY_RATE_SUPPORT \ + FAST_UP_RATE_SUPPORT \ + TXRX_STAT_SUPPORT \ + VENDOR_FEATURE11_SUPPORT \ + WIFI_TWT_SUPPORT \ + CTXD_MEM_CPY_SUPPORT \ + CTXD_SCATTER_AND_GATHER_SUPPORT \ + SINGLE_SKU \ + SNIFFER_SUPPORT \ + SNIFFER_RADIOTAP_SUPPORT \ + WF_RESET_SUPPORT \ + WIFI_SYSDVT \ + WARP_V2 \ + OCE_SUPPORT \ + 6G_SUPPORT \ + WIFI_FW_BIN_LOAD \ + CONNINFRA_APSOC \ + MLME_MULTI_QUEUE_SUPPORT \ + WIFI_SKU_TYPE \ + MAP_R2_6E_SUPPORT \ + WIFI_SKB_USES_SLAB \ + WIFI_CSI_CN_INFO_SUPPORT \ + +PKG_CONFIG_DEPENDS:=$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c))) + +include $(INCLUDE_DIR)/package.mk + + +TAR_CMD=$(HOST_TAR) -C $(1)/ $(TAR_OPTIONS) + +define KernelPackage/mt_wifi + CATEGORY:=MTK Properties + TITLE:=MTK wifi AP driver + DEPENDS:=+wifi-profile + DEPENDS+=+kmod-conninfra + DEPENDS+=+kmod-mediatek_hnat + FILES:=$(PKG_BUILD_DIR)/mt_wifi_ap/mt_wifi.ko \ + $(PKG_BUILD_DIR)/mt_wifi_ap/mtk_warp_proxy.ko + DEPENDS+=+kmod-warp + AUTOLOAD:=$(call AutoProbe,mt_wifi mtk_warp_proxy) + SUBMENU:=Drivers + MENU:=1 +endef + +define KernelPackage/mt_wifi/config + source "$(SOURCE)/config.in" +endef + + +define Build/Compile + +$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)/mt_wifi_ap" \ + LINUX_DIR="$(KERNEL_BUILD_DIR)" \ + $(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_MTK_$c),CONFIG_$(c)=$(CONFIG_MTK_$(c)))) \ + modules +endef + +define KernelPackage/mt_wifi/install +if [ "$$(CONFIG_MTK_WIFI_FW_BIN_LOAD)" = "y" ]; then \ + rm -rf $(1)/lib/firmware/; \ + $(INSTALL_DIR) $(1)/lib/firmware/; \ + if [ "$$(CONFIG_MTK_CHIP_MT7986)" = "y" ] ; then \ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/mt7986/rebb/WIFI_RAM_CODE_MT7986.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/WIFI_RAM_CODE_MT7986_TESTMODE.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/WIFI_RAM_CODE_MT7986_TESTMODE_MT7975.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/mt7986_patch_e1_hdr_testmode.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/mt7986_patch_e1_hdr_testmode_mt7975.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/WIFI_RAM_CODE_MT7986_MT7975.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/mt7986_patch_e1_hdr.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/mt7986_patch_e1_hdr_mt7975.bin \ + $(PKG_BUILD_DIR)/bin/mt7986/rebb/7986_WACPU_RAM_CODE_release.bin $(1)/lib/firmware/; \ + if [ "$$(CONFIG_MTK_WIFI_SKU_TYPE)" = "AX6000" -o "$$(CONFIG_MTK_WIFI_SKU_TYPE)" = "AX8400" ] ; then \ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/mt7986/rebb/MT7986_iPAiLNA_EEPROM_AX6000.bin $(PKG_BUILD_DIR)/bin/mt7986/rebb/MT7986_ePAeLNA_EEPROM_AX6000.bin \ + $(1)/lib/firmware/; \ + fi; \ + if [ "$$(CONFIG_MTK_WIFI_SKU_TYPE)" = "AX4200" ] ; then \ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/mt7986/rebb/MT7986_ePAeLNA_EEPROM_ONEADIE_DBDC.bin \ + $(1)/lib/firmware/; \ + fi; \ + fi; \ + if [ "$$(CONFIG_MTK_CHIP_MT7916)" = "y" ] ; then \ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/mt7916/rebb/* $(1)/lib/firmware/; \ + fi; \ + if [ "$$(CONFIG_MTK_CHIP_MT7981)" = "y" ] ; then \ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/bin/mt7981/rebb/WIFI_RAM_CODE_MT7981.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/7981_WACPU_RAM_CODE_release.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/mt7981_patch_e1_hdr.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/WIFI_RAM_CODE_MT7981_TESTMODE.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/mt7981_patch_e1_hdr_testmode.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/MT7981_iPAiLNA_EEPROM.bin \ + $(PKG_BUILD_DIR)/bin/mt7981/rebb/MT7981_ePAeLNA_EEPROM.bin \ + $(1)/lib/firmware/; \ + fi; \ +fi +endef + +$(eval $(call KernelPackage,mt_wifi)) diff --git a/package/mtk/drivers/mt_wifi/config.in b/package/mtk/drivers/mt_wifi/config.in new file mode 100644 index 0000000000..a9da602ae1 --- /dev/null +++ b/package/mtk/drivers/mt_wifi/config.in @@ -0,0 +1,1333 @@ +if PACKAGE_kmod-mt_wifi + +config MTK_SUPPORT_OPENWRT + bool + default y + depends on PACKAGE_kmod-mt_wifi + +config MTK_WIFI_DRIVER + bool + default y + depends on PACKAGE_kmod-mt_wifi + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + #select MTK_FIRST_IF_MT7615E + #select MTK_CHIP_MT7622 + #select MTK_CHIP_MT7626 + #select MTK_SECOND_IF_MT7615E + #select MTK_THIRD_IF_MT7615E + #select MTK_CHIP_MT7615E + +if MTK_WIFI_DRIVER + +choice + prompt "Choose First WiFi Interface" + config MTK_FIRST_IF_NONE + bool "None" + + config MTK_FIRST_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7615E + + config MTK_FIRST_IF_MT7622 + bool "MT7622" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7622 + + config MTK_FIRST_IF_MT7626 + bool "MT7626" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7626 + + config MTK_FIRST_IF_AXE + bool "MT6867" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_AXE + + config MTK_FIRST_IF_MT7915 + bool "MT7915" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7915 + + config MTK_FIRST_IF_MT7986 + bool "MT7986" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7986 + + config MTK_FIRST_IF_MT7916 + bool "MT7916" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7916 + + config MTK_FIRST_IF_MT7981 + bool "MT7981" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7981 + +endchoice + +choice + prompt "Choose Second WiFi Interface" + config MTK_SECOND_IF_NONE + bool "None" + + config MTK_SECOND_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_CHIP_MT7615E + select MTK_MULTI_INF_SUPPORT + + config MTK_SECOND_IF_AXE + bool "MT6867" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_AXE + + config MTK_SECOND_IF_MT7915 + bool "MT7915" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7915 + + config MTK_SECOND_IF_MT7916 + bool "MT7916" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7916 + +endchoice + +choice + prompt "Choose Third WiFi Interface" + config MTK_THIRD_IF_NONE + bool "None" + + config MTK_THIRD_IF_MT7615E + bool "MT7615E" + select MTK_WIFI_MT_MAC + select MTK_CHIP_MT7615E + select MTK_MULTI_INF_SUPPORT + + config MTK_THIRD_IF_MT7915 + bool "MT7915" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7915 + select MTK_MULTI_INF_SUPPORT + + config MTK_THIRD_IF_MT7916 + bool "MT7916" + select MTK_WIFI_MT_MAC + select MTK_MT_MAC + select MTK_CHIP_MT7916 + select MTK_MULTI_INF_SUPPORT + +endchoice + +config MTK_RT_FIRST_CARD + int + depends on ! MTK_FIRST_IF_NONE + default 7615 if MTK_FIRST_IF_MT7615E + default 7622 if MTK_FIRST_IF_MT7622 + default 7626 if MTK_FIRST_IF_MT7626 + default 6867 if MTK_FIRST_IF_AXE + +config MTK_RT_SECOND_CARD + int + depends on ! MTK_SECOND_IF_NONE + default 7615 if MTK_SECOND_IF_MT7615E + default 6867 if MTK_SECOND_IF_AXE + +config MTK_RT_THIRD_CARD + int + depends on ! MTK_THIRD_IF_NONE + default 7615 if MTK_THIRD_IF_MT7615E + +config MTK_RT_FIRST_IF_RF_OFFSET + hex + depends on ! MTK_FIRST_IF_NONE + default 0xc0000 + +config MTK_RT_SECOND_IF_RF_OFFSET + hex + depends on ! MTK_SECOND_IF_NONE + default 0xc8000 + +config MTK_RT_THIRD_IF_RF_OFFSET + hex + depends on ! MTK_THIRD_IF_NONE + default 0xd0000 + +config MTK_MT_WIFI + tristate "MT WIFI Driver" + select MTK_WIFI_BASIC_FUNC if MTK_MT_WIFI + +config MTK_MT_WIFI_PATH + string + depends on MTK_MT_WIFI + default "mt_wifi" + +if MTK_MT_WIFI +menu "WiFi Generic Feature Options" +choice + prompt "EEPROM Type of 1st Card" + depends on ! MTK_FIRST_IF_NONE + + config MTK_FIRST_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_FIRST_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_FIRST_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_FIRST_CARD_EEPROM + string + depends on ! MTK_FIRST_IF_NONE + default "prom" if MTK_FIRST_IF_EEPROM_PROM + default "efuse" if MTK_FIRST_IF_EEPROM_EFUSE + default "flash" if MTK_FIRST_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 2nd Card" + depends on ! MTK_SECOND_IF_NONE + + config MTK_SECOND_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_SECOND_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_SECOND_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_SECOND_CARD_EEPROM + string + depends on ! MTK_SECOND_IF_NONE + default "prom" if MTK_SECOND_IF_EEPROM_PROM + default "efuse" if MTK_SECOND_IF_EEPROM_EFUSE + default "flash" if MTK_SECOND_IF_EEPROM_FLASH + +choice + prompt "EEPROM Type of 3th Card" + depends on ! MTK_THIRD_IF_NONE + + config MTK_THIRD_IF_EEPROM_FLASH + bool "FLASH" + + config MTK_THIRD_IF_EEPROM_PROM + bool "EEPROM" + + config MTK_THIRD_IF_EEPROM_EFUSE + bool "EFUSE" + +endchoice + +config MTK_RT_THIRD_CARD_EEPROM + string + depends on ! MTK_THIRD_IF_NONE + default "prom" if MTK_THIRD_IF_EEPROM_PROM + default "efuse" if MTK_THIRD_IF_EEPROM_EFUSE + default "flash" if MTK_THIRD_IF_EEPROM_FLASH + +config MTK_MULTI_INF_SUPPORT + bool + default y if !MTK_FIRST_IF_NONE && !MTK_SECOND_IF_NONE + +config MTK_WIFI_BASIC_FUNC + bool "Basic Functions" + select MTK_WIRELESS_EXT + select MTK_WEXT_SPY + select MTK_WEXT_PRIV + +config MTK_DOT11_N_SUPPORT + bool "802.11n support" + default y + +config MTK_DOT11_VHT_AC + bool "802.11AC support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_N_SUPPORT + default y + +config MTK_DOT11_HE_AX + bool "802.11AX support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_VHT_AC + depends on MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_CFG_SUPPORT_FALCON_MURU + bool "MURU support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_VHT_AC + depends on MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_CFG_SUPPORT_FALCON_TXCMD_DBG + bool "TXCMD DBG support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_VHT_AC + depends on MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_CFG_SUPPORT_FALCON_SR + bool "SR(Spatial Reuse) support" + depends on MTK_WIFI_DRIVER + depends on MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_CFG_SUPPORT_FALCON_PP + bool "PP(Preamble Puncture) support" + depends on MTK_WIFI_DRIVER + depends on MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_WIFI_TWT_SUPPORT + bool "TWT(Target Wake Time) support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_HE_AX + depends on MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_G_BAND_256QAM_SUPPORT + bool "2.4G 256QAM support" + depends on MTK_WIFI_DRIVER + depends on MTK_DOT11_VHT_AC + default y + +config MTK_BRCM_256QAM_SUPPORT + bool "BRCM 2.4G 256QAM support" + depends on MTK_WIFI_DRIVER + depends on MTK_G_BAND_256QAM_SUPPORT + default n + +config MTK_VHT_TXBF_2G_EPIGRAM_IE_SUPPORT + bool "BRCM 2.4G VHT Sounding support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_TPC_SUPPORT + bool "802.11h TPC Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_ICAP_SUPPORT + bool "ICAP Support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_SPECTRUM_SUPPORT + bool "Wifi Spectrum Support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_PHY_ICS_SUPPORT + bool "PHY ICS Support" + depends on MTK_WIFI_DRIVER + depends on MTK_CHIP_MT7986 || MTK_CHIP_MT7916 + default y + +config MTK_BACKGROUND_SCAN_SUPPORT + bool "Background Scan Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_SMART_CARRIER_SENSE_SUPPORT + bool "Smart Carrier Sense Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_THERMAL_PROTECT_SUPPORT + bool "THERMAL PROTECT SUPPORT" + depends on MTK_WIFI_DRIVER && MTK_SMART_CARRIER_SENSE_SUPPORT + default n + +config MTK_SCS_FW_OFFLOAD + bool "SCS FW OFFLOAD Support" + depends on MTK_WIFI_DRIVER && MTK_SMART_CARRIER_SENSE_SUPPORT + default n + +config MTK_MT_DFS_SUPPORT + bool "Dynamic Frequency Selection Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_OFFCHANNEL_SCAN_FEATURE + bool "Channel Quality Monitor" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default n + +#config WFA_VHT_R2_PF +# bool "WFA VHT R2 Plugfest" +# depends on DOT11_VHT_AC +# default n + +config MTK_HDR_TRANS_TX_SUPPORT + bool "Tx Header Translation" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 || MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_HDR_TRANS_RX_SUPPORT + bool "Rx Header Translation" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 || MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + default y + +config MTK_DBDC_MODE + bool "dbdc mode support" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7626 || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + select MULTI_PROFILE_SUPPORT + select DEFAULT_5G_PROFILE + default y + +config MTK_MULTI_PROFILE_SUPPORT + bool "Multi Profile Support" + depends on MTK_DBDC_MODE + default y + +config MTK_DEFAULT_5G_PROFILE + bool "5G default profile for DBDC" + depends on MTK_DBDC_MODE +# depends on MTK_MULTI_PROFILE_SUPPORT + default y + +config MTK_WSC_INCLUDED + bool "WSC (WiFi Simple Config)" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_WSC_V2_SUPPORT + bool "WSC V2(WiFi Simple Config Version 2.0)" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_DOT11W_PMF_SUPPORT + bool "PMF" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_TXBF_SUPPORT + bool "Tx Bean Forming Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_FAST_NAT_SUPPORT + bool "Fast-NAT support" +# depends on RA_HW_NAT_WIFI + default n + +config MTK_WHNAT_SUPPORT + tristate "Wifi Hardware NAT support" + depends on MTK_CHIP_MT7615E || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + depends on MTK_WLAN_HOOK + depends on MTK_FAST_NAT_SUPPORT + depends on PACKAGE_kmod-hw_nat || PACKAGE_kmod-mediatek_hnat + default n + +config MTK_WARP_V2 + bool "Warp driver version 2 support" + depends on PACKAGE_kmod-warp && MTK_WHNAT_SUPPORT + default n + +config MTK_WIFI_SKB_USES_SLAB + bool "WiFi SKB allocation by SLAB" + depends on MTK_WIFI_DRIVER + default n + +#config LLTD_SUPPORT +# bool "LLTD (Link Layer Topology Discovery Protocol)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config QOS_DLS_SUPPORT +# bool "802.11e DLS ((Direct-Link Setup) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WAPI_SUPPORT +# bool "WAPI Support" +# depends on WIFI_DRIVER +# default n + +config MTK_FTM_SUPPORT + bool "FTM Support" + depends on MTK_WIFI_DRIVER + select MTK_PASSPOINT_R2 + default n + +#config CARRIER_DETECTION_SUPPORT +# bool "Carrier Detect" +# depends on WIFI_DRIVER +# default n + +config MTK_IGMP_SNOOP_SUPPORT + bool "IGMP snooping" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_MEMORY_SHRINK + bool "Memory Shrink" + depends on MTK_WIFI_DRIVER + default n + +config MTK_MEMORY_SHRINK_AGGRESS + bool "Memory Shrink Aggressive" + depends on MTK_MEMORY_SHRINK + default n + +config MTK_RPS_EFFICIENCY + bool "RPS Efficiency" + depends on MTK_WIFI_DRIVER && MTK_CHIP_MT7626 + default n + +#config BLOCK_NET_IF +# bool "NETIF Block" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n +# help +# Support Net interface block while Tx-Sw queue full + +#config RATE_ADAPTION +# bool "New Rate Adaptation support" +# depends on WIFI_DRIVER +# default y + +#config NEW_RATE_ADAPT_SUPPORT +# bool "Intelligent Rate Adaption" +# depends on WIFI_DRIVER && RATE_ADAPTION +# default y + +#config AGS_SUPPORT +# bool "Adaptive Group Switching" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default n + +#config RATE_ADAPT_AGBS_SUPPORT +# bool "Adaptive AGBS Mode" +# depends on WIFI_DRIVER && RATE_ADAPTION +# depends on MT_AP_SUPPORT || MT_STA_SUPPORT +# default y + +#config IDS_SUPPORT +# bool "IDS (Intrusion Detection System) Support" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +#config WIFI_WORK_QUEUE +# bool "Work Queue" +# depends on WIFI_DRIVER +# default n + +#config WIFI_SKB_RECYCLE +# bool "SKB Recycle(Linux)" +# depends on WIFI_DRIVER +# depends on MT_AP_SUPPORT +# default n + +config MTK_RTMP_FLASH_SUPPORT + bool "Flash Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_PRE_CAL_TRX_SET1_SUPPORT + bool "Calibration To Flash/BinFile Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_RLM_CAL_CACHE_SUPPORT + bool "RlmCalibrationCache Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_PRE_CAL_TRX_SET2_SUPPORT + bool "Pre-calibration to Flash Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_CAL_BIN_FILE_SUPPORT + bool "Calibration to BinFile Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_RF_LOCKDOWN_SUPPORT + bool "RF Lockdown Support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_LINK_TEST_SUPPORT + bool "Link Test Support" + depends on MTK_WIFI_DRIVER + default n + +#config MTK_LED_CONTROL_SUPPORT +# bool "LED Support" +# depends on MTK_WIFI_DRIVER +# depends on MTK_MT_AP_SUPPORT +# default n + +config MTK_ATE_SUPPORT + bool "ATE/QA Support" + depends on MTK_WIFI_DRIVER + default y + +config MTK_WLAN_SERVICE + bool "Wlan Service Library Support" + depends on MTK_WIFI_DRIVER + default n + +#config MTK_MEMORY_OPTIMIZATION +# bool "Memory Optimization" +# depends on MTK_WIFI_DRIVER +# default n + +config MTK_PASSPOINT_R2 + bool "Passpoint Release-2 Support" + depends on MTK_WIFI_DRIVER + select MTK_DOT11W_PMF_SUPPORT + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_MBO_SUPPORT + bool "MBO Support" + depends on MTK_WIFI_DRIVER + select MTK_INTERWORKING + select MTK_WNM_SUPPORT + select MTK_DOT11K_RRM_SUPPORT + select MTK_DOT11R_FT_SUPPORT + select MTK_DOT11W_PMF_SUPPORT + default n + +config MTK_OCE_SUPPORT + bool "Optimized Connectivity Experience Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_MBO_SUPPORT + depends on MTK_CHIP_MT7915 || MTK_CHIP_MT7986 + default y + +config MTK_MAP_SUPPORT + bool "MAP Support" + depends on MTK_WIFI_DRIVER + select MTK_INTERWORKING + select MTK_WNM_SUPPORT + select MTK_DOT11K_RRM_SUPPORT + select MTK_DOT11R_FT_SUPPORT + select MTK_DOT11W_PMF_SUPPORT + default n + +config MTK_MAP_R2_VER_SUPPORT + bool "Multi-AP R2 version support" + depends on MTK_MAP_SUPPORT + default n + +config MTK_MAP_R3_VER_SUPPORT + bool "Multi-AP R3 version support" + depends on MTK_MAP_SUPPORT + depends on MTK_MAP_R2_VER_SUPPORT + default n + +config MTK_MAP_R2_6E_SUPPORT + bool "Multi-AP R2 6E support" + depends on MTK_MAP_SUPPORT + default n + + +#config TRACE_TCP_PKT +# bool "TCP DATA/ACK packets trace log" +# depends on WIFI_DRIVER +# default n + +config MTK_UAPSD + bool "UAPSD support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_TCP_RACK_SUPPORT + bool "TCP Reduced ACK support" + depends on MTK_WIFI_DRIVER + default n + +#### PA_LNA_Type choice + +config MTK_RED_SUPPORT + bool "RED(Random Early Drop) support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT || MTK_MT_STA_SUPPORT + default y + +config MTK_FQ_SCH_SUPPORT + bool "Fair Queueing support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT && MTK_VOW_SUPPORT + depends on MTK_CHIP_MT7622 + default y + +config MTK_CTXD_MEM_CPY_SUPPORT + bool "CTXD(sw mode) support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_CTXD_SCATTER_AND_GATHER_SUPPORT + bool "CTXD(hw mode) support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_FDB_SUPPORT + bool "FW Debug Port" + depends on MTK_WIFI_DRIVER + default n + +choice + prompt "PA LNA Type of 1st Card" + depends on ! MTK_FIRST_IF_NONE + + config MTK_FIRST_IF_EPAELNA + bool "ePAeLNA" + config MTK_FIRST_IF_IPAILNA + bool "iPAiLNA" + config MTK_FIRST_IF_IPAELNA + bool "iPAeLNA" +# config MTK_FIRST_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 2nd Card" + depends on ! MTK_SECOND_IF_NONE + + config MTK_SECOND_IF_EPAELNA + bool "ePAeLNA" + config MTK_SECOND_IF_IPAILNA + bool "iPAiLNA" + config MTK_SECOND_IF_IPAELNA + bool "iPAeLNA" +# config MTK_SECOND_IF_EPAILNA +# bool "ePAiLNA" +endchoice +choice + prompt "PA LNA Type of 3rd Card" + depends on ! MTK_THIRD_IF_NONE + + config MTK_THIRD_IF_EPAELNA + bool "ePAeLNA" + config MTK_THIRD_IF_IPAILNA + bool "iPAiLNA" + config MTK_THIRD_IF_IPAELNA + bool "iPAeLNA" +# config MTK_THIRD_IF_EPAILNA +# bool "ePAiLNA" +endchoice +#### PA_LNA_Type choice END + +config MTK_WIFI_FW_BIN_LOAD + depends on MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + bool "load wifi fw with bin file" + default n + +config MTK_WIFI_SKU_TYPE + depends on MTK_CHIP_MT7986 + string "Panther SKU Type : AX6000 or AX7800 or SADBDC" + default "AX6000" + +config MTK_WIFI_ADIE_TYPE + depends on MTK_CHIP_MT7986 + string "Panther ADIE Type : mt7975 or mt7976" + default "mt7976" + +# +# Section for chip architectures +# +# "RLT MAC Support" +config MTK_RLT_MAC + bool + depends on MTK_WIFI_DRIVER + default n + +config MTK_RLT_BBP + bool + +config MTK_RLT_RF + bool + +# "RTMP MAC Support" +config MTK_RTMP_MAC + bool + depends on MTK_WIFI_DRIVER + default n + +config MTK_RTMP_BBP + bool + +config MTK_RTMP_RF + bool + +# +# Section for interfaces +# +config MTK_RTMP_PCI_SUPPORT + bool + +config MTK_RTMP_USB_SUPPORT + bool + +config MTK_RTMP_RBUS_SUPPORT + bool + +endmenu + +menu "WiFi Operation Modes" +choice + prompt "Main Mode" + default MTK_WIFI_MODE_AP + + config MTK_WIFI_MODE_AP + tristate "AP" + select MTK_MT_AP_SUPPORT + + config MTK_WIFI_MODE_STA + tristate "STA" + select MTK_MT_STA_SUPPORT + + config MTK_WIFI_MODE_BOTH + tristate "APSTA" + select MTK_MT_AP_SUPPORT + select MTK_MT_STA_SUPPORT +endchoice + + +config MTK_MT_AP_SUPPORT + tristate "Ralink RT2860 802.11n AP support" +# depends on NET_RADIO + select MTK_WIRELESS_EXT + select MTK_WEXT_SPY + select MTK_WEXT_PRIV + +config MTK_WDS_SUPPORT + bool "WDS" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_MBSS_SUPPORT + bool "MBSSID" + depends on MTK_MT_AP_SUPPORT + default y + +#config NEW_MBSSID_MODE +# bool "New MBSSID MODE" +# depends on MT_AP_SUPPORT && MBSS_SUPPORT +# depends on RALINK_RT3883 || RALINK_RT3352 || RALINK_RT5350 || RALINK_RT6352 || RALINK_MT7620 +# default y + +#config ENHANCE_NEW_MBSSID_MODE +# bool "Enhanced MBSSID mode" +# depends on NEW_MBSSID_MODE +# default y + +config MTK_APCLI_SUPPORT + bool "AP-Client Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_APCLI_CERT_SUPPORT + bool "AP-Client TGn Cert Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + default n + +config MTK_MAC_REPEATER_SUPPORT + bool "MAC Repeater Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + depends on MTK_RALINK_RT6352 || MTK_RALINK_MT7620 || MTK_RALINK_MT7603E || MTK_MT_AP_SUPPORT + default y + +config MTK_APCLI_CONNECTION_TRIAL + bool "Trial Connection" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + default n + +config MTK_MWDS + bool "Mixed WDS(MWDS)" + depends on MTK_MT_AP_SUPPORT + select MTK_APCLI_SUPPORT + default n + +config MTK_WIFI_SYSDVT + bool "Wifi System DVT tool Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_MUMIMO_SUPPORT + bool "MU-MIMO Support" + depends on MTK_WIFI_DRIVER + select MTK_MU_RA_SUPPORT + default y + +config MTK_MU_RA_SUPPORT + bool "MU-RGA Support" + depends on MTK_MUMIMO_SUPPORT + +config MTK_DOT11R_FT_SUPPORT + bool "802.11r Fast BSS Transition" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_DOT11K_RRM_SUPPORT + bool "802.11k Radio Resource Management" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_ENTERPRISE_AP_SUPPORT + bool "Enterprise AP Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_MLME_MULTI_QUEUE_SUPPORT + bool "Mlme MultiQueue Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_WIFI_EAP_FEATURE + bool "EAP Feature" + depends on MTK_WIFI_DRIVER + default y + +#VLAN +config MTK_VLAN_SUPPORT + bool "VLAN Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_WIFI_EAP_FEATURE + default n + +#Sniffer +config MTK_SNIFFER_SUPPORT + bool "SNIFFER" + depends on MTK_MT_AP_SUPPORT + depends on MTK_WIFI_EAP_FEATURE + default n + +#Highpriority frame rate specific +config MTK_HIGHPRI_RATE_SPECIFIC + bool "Highpriority frame rate specific" + depends on MTK_MT_AP_SUPPORT + depends on MTK_WIFI_EAP_FEATURE + default n + +config MTK_SNIFFER_RADIOTAP_SUPPORT + bool "SNIFFER_RADIOTAP" + default y + +config MTK_WF_RESET_SUPPORT + bool "WIFI RESET" + default n + +#TxRx Statistic +config MTK_TXRX_STAT_SUPPORT + bool "TxRx Stats Support" + depends on MTK_WIFI_DRIVER && MTK_WIFI_EAP_FEATURE + default n + +#Antenna control +config MTK_ANTENNA_CONTROL_SUPPORT + bool "Antenna Control" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#Mgmt Tx Power +config MTK_MGMT_TXPWR_CTRL + bool "Mgmt TxPower Control" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#TxD based Mgmt Tx Power +config MTK_TXD_MGMT_TXPWR_CTRL + bool "TxD based Mgmt TxPower Control" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#Channel Utilization +config MTK_CHUTIL_SUPPORT + bool "Channel Utilization Support" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#Noise Floor +config MTK_NF_SUPPORT + bool "Noise Floor Support" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#RA_PHY_RATE +config MTK_RA_PHY_RATE_SUPPORT + bool "RA PHY RATE Support" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#AMPDU Config +config MTK_AMPDU_CONF_SUPPORT + bool "AMPDU Config retry & agglimitSupport" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#ACK CTS Timeout +config MTK_ACK_CTS_TIMEOUT_SUPPORT + bool "ACK CTS Timeout cck & ofdm Support" + depends on MTK_MT_AP_SUPPORT && MTK_WIFI_EAP_FEATURE + default n + +#MBSS_DTIM_SUPPORT +config MTK_MBSS_DTIM_SUPPORT + bool "MBSS DTIM SUPPORT" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_RADIUS_MAC_AUTH_SUPPORT + bool "RADIUS MAC Auth Support" + depends on MTK_ENTERPRISE_AP_SUPPORT + depends on MTK_CFG80211_SUPPORT + default n + +config ZERO_LOSS_CSA_SUPPORT + bool "Zero Loss CSA Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_DYNAMIC_VLAN_SUPPORT + bool "Dynamic VLAN Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_ENTERPRISE_AP_SUPPORT + default n + +config MTK_CFG80211_SUPPORT + bool "CFG80211" + depends on MTK_MT_AP_SUPPORT + default n + +#CUSTOMISED HOSTAPD +config MTK_CUSTOMISED_HOSTAPD_SUPPORT + bool "Customised Hostapd Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_CFG80211_SUPPORT + default n +#HOSTAPD_WPA3_SUPPORT +config MTK_HOSTAPD_WPA3_SUPPORT + bool "Hostapd WPA3 Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_CFG80211_SUPPORT + default n + +#HOSTAPD_WPA3R3_SUPPORT +config MTK_HOSTAPD_WPA3R3_SUPPORT + bool "Hostapd WPA3R3 Support" + depends on MTK_HOSTAPD_WPA3_SUPPORT + default n + +#DBDC_ONE_BAND_SUPPORT +config MTK_DBDC_ONE_BAND_SUPPORT + bool "Single Band DBDC Support" + depends on MTK_MT_AP_SUPPORT + default n + +#APCLI STA +config MTK_APCLI_STA_SUPPORT + bool "APCLI STA Support" + depends on MTK_APCLI_SUPPORT + depends on MTK_CFG80211_SUPPORT + default n + +#WDS STA +config MTK_WDS_STA_SUPPORT + bool "WDS STA Support" + depends on MTK_APCLI_SUPPORT + depends on MTK_CFG80211_SUPPORT + default n + +#WDS AP +config MTK_MBSS_AS_WDS_AP_SUPPORT + bool "MBSS AS WDS AP Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_MBSS_SUPPORT + default n + +config MTK_DSCP_QOS_MAP_SUPPORT + bool "Dscp Qos Mapping Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_QOS_R1_SUPPORT + bool "MTK QoS R1 support" + default n + +config MTK_DSCP_PRI_SUPPORT + bool "Dscp Priority Mapping Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_MIN_PHY_RATE_SUPPORT + bool "Minimum PHY rate support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_FAST_UP_RATE_SUPPORT + bool "Fast UP rate support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_CON_WPS_SUPPORT + bool "Concurrent WPS Support" + depends on MTK_MT_AP_SUPPORT + depends on MTK_APCLI_SUPPORT + depends on MTK_WSC_INCLUDED + depends on MTK_WSC_V2_SUPPORT +# depends on MTK_MULTI_INF_SUPPORT + default n + +#config LLTD_SUPPORT +# bool "LLTD (Link Layer Topology Discovery Protocol)" +# depends on MT_AP_SUPPORT + +#config COC_SUPPORT +# bool "CoC Support" +# depends on MT_AP_SUPPORT +# default n + +#config RT2860V2_SNMP +# bool "Net-SNMP Support" +# depends on MT_AP_SUPPORT + +config MTK_MCAST_RATE_SPECIFIC + bool "User specific tx rate of mcast pkt" + depends on MTK_MT_AP_SUPPORT + default y + +#config EXT_BUILD_CHANNEL_LIST +# bool "Extension Channel List" +# depends on MT_AP_SUPPORT + +#config AUTO_CH_SELECT_ENHANCE +# bool "Auto Channel Selection Enhancement" +# depends on MT_AP_SUPPORT + +config MTK_VOW_SUPPORT + bool "MediaAir(VOW) support" + depends on MTK_MT_AP_SUPPORT + default y + +#config AIRPLAY_SUPPORT +# bool "AIRPLAY Support" +# depends on MT_AP_SUPPORT +# default n + +config MTK_BAND_STEERING + bool "Band Steering" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_LED_CONTROL_SUPPORT + bool "LED Control Support" + default n + +config MTK_WLAN_HOOK + bool "WLAN hook Support" + depends on MTK_WIFI_DRIVER + default n + +config MTK_RADIUS_ACCOUNTING_SUPPORT + bool "Radius Accounting Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_GREENAP_SUPPORT + bool "GreenAP Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_WIFI_CSI_CN_INFO_SUPPORT + bool "CSI CN Info Support" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_VENDOR_FEATURE11_SUPPORT + bool "Vendor11 Feature Enable" + depends on MTK_WIFI_DRIVER + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_PCIE_ASPM_DYM_CTRL_SUPPORT + bool "Pcie Aspm Dynamic Control Support" + depends on MTK_MT_AP_SUPPORT + default y + +config MTK_COEX_SUPPORT + bool "Coex Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_EASY_SETUP_SUPPORT + bool "Whole Home Coverage - Easy Setup" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_EVENT_NOTIFIER_SUPPORT + bool "Whole Home Coverage - Event Notifier" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_AIR_MONITOR + bool "Air Monitor" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_WNM_SUPPORT + bool "802.11v WNM Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_INTERWORKING + bool "802.11u Interworking" + depends on MTK_MT_AP_SUPPORT + default n + +#config ROAMING_ENHANCE_SUPPORT +# bool "Roaming Enhance Support" +# depends on MT_AP_SUPPORT +# depends on APCLI_SUPPORT +# default n + +config MTK_LINUX_NET_TXQ_SUPPORT + bool "NET TX Queue Support" + default n + +#config WIFI_FWD_SUPPORT +# bool "WiFi Forwarding Support" +# default n + +config MTK_WPA3_SUPPORT + bool "WPA3 Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_OWE_SUPPORT + bool "Enhanced Open Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_SINGLE_SKU + bool "Single SKU Support" + depends on MTK_MT_AP_SUPPORT + default n + +config MTK_PROFILING_SUPPORT + bool "WIFI Profiling Support" + default n + +config MTK_6G_SUPPORT + bool "WIFI 6G Support" + default n + help + Supporting 6GHz Wi-Fi + +endmenu + +endif + +config MTK_WIFI_MT_MAC + bool + default y + depends on MTK_MT_WIFI + +if MTK_WIFI_RLT_MAC + config MTK_RLT_MAC + bool + default y +endif + +if MTK_WIFI_RTMP_MAC + config MTK_RTMP_MAC + bool + default y +endif + +if MTK_WIFI_MT_MAC + config MTK_MT_MAC + bool + default y + + config MTK_CHIP_MT7603E + bool + default n + + config MTK_CHIP_MT7615E + bool + default n + + config MTK_CHIP_MT7622 + bool + default n + + config MTK_CHIP_MT7663E + bool + default n + + config MTK_CHIP_MT7626 + bool + default n + config MTK_CHIP_AXE + bool + default n + config MTK_CHIP_MT7915 + bool + default n + config MTK_CHIP_MT7986 + bool + default n + config MTK_CHIP_MT7916 + bool + default n + config MTK_CHIP_MT7981 + bool + default n +endif + +if MTK_CHIP_MT7615E || MTK_CHIP_MT7622 || MTK_CHIP_MT7626 || MTK_CHIP_AXE || MTK_CHIP_MT7915 || MTK_CHIP_MT7986 || MTK_CHIP_MT7916 || MTK_CHIP_MT7981 + config MTK_MT_MAC + bool + default y + select MTK_RATE_ADAPTION + select MTK_RATE_ADAPT_AGBS_SUPPORT + select MTK_DOT11_N_SUPPORT + select MTK_DOT11_VHT_AC + select MTK_HDR_TRANS_TX_SUPPORT + select MTK_HDR_TRANS_RX_SUPPORT +endif + +endif #MTK_WIFI_DRIVER# +endif #PACKAGE_kmod-mt_wifi# + diff --git a/package/mtk/drivers/warp/Makefile b/package/mtk/drivers/warp/Makefile new file mode 100644 index 0000000000..8e21aacb30 --- /dev/null +++ b/package/mtk/drivers/warp/Makefile @@ -0,0 +1,74 @@ +# All rights reserved. +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=warp +P4REV:= +PKG_VERSION:= +PKG_SOURCE:=warp_20220425-d15d0a-obj.tar.xz +PKG_SOURCE_URL:= +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME) +PKG_KCONFIG:= \ + WARP_VERSION \ + WARP_ATC_SUPPORT \ + WARP_DBG_SUPPORT \ + WARP_WDMA_RECYCLE_SUPPORT \ + WED_HW_RRO_SUPPORT \ + MTK_MEMORY_SHRINK \ + WARP_CHIPSET \ + WARP_WO_EMBEDDED_LOAD \ + WARP_MEMORY_LEAK_DBG + +PKG_CONFIG_DEPENDS:=$(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_$c),CONFIG_$(c))) + +include $(INCLUDE_DIR)/package.mk + +TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS) + +define KernelPackage/warp + CATEGORY:=MTK Properties + TITLE:=MTK warp driver + DEPENDS:= +kmod-mediatek_hnat + FILES:=$(PKG_BUILD_DIR)/mtk_warp.ko + AUTOLOAD:=$(call AutoLoad,60,mtk_warp,1) + SUBMENU:=Drivers + MENU:=1 +endef + +define KernelPackage/warp/config + source "$(SOURCE)/config.in" +endef + + +MTK_WIFI_DIR:=$(TOPDIR)/../ko_module/wlan_driver/jedi +USE_BIN_DIR:=$(MTK_WIFI_DIR)/warp_driver/bin + +define Build/Compile + $(MAKE) -C "$(LINUX_DIR)" V=1 \ + $(KERNEL_MAKE_FLAGS) \ + M="$(PKG_BUILD_DIR)" \ + $(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_$c),CONFIG_$(c)=$(CONFIG_$(c)))) \ + modules +endef + +TARGET_CFLAGS += \ + $(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_$c),-DCONFIG_$(c)=$(CONFIG_$c))) + +MAKE_FLAGS += \ + $(foreach c, $(PKG_KCONFIG),$(if $(CONFIG_$c),CONFIG_$(c)=$(CONFIG_$c))) + +TARGET_CFLAGS += -DCONFIG_SUPPORT_OPENWRT +MAKE_FLAGS += CONFIG_SUPPORT_OPENWRT=y + +define KernelPackage/warp/install + $(INSTALL_DIR) $(1)/lib/firmware + cp $(PKG_BUILD_DIR)/bin/*WOCPU*_RAM_CODE_release.bin $(1)/lib/firmware/; +endef + +$(eval $(call KernelPackage,warp)) + + diff --git a/package/mtk/drivers/warp/config.in b/package/mtk/drivers/warp/config.in new file mode 100644 index 0000000000..772fc18d9f --- /dev/null +++ b/package/mtk/drivers/warp/config.in @@ -0,0 +1,47 @@ +if PACKAGE_kmod-warp + +config WARP_VERSION + int "WARP Driver HW Version Support" + range 1 2 + default 1 if TARGET_mediatek_mt7622 + default 2 if TARGET_mediatek_mt7627 + +config WARP_ATC_SUPPORT + bool "WARP Driver Address Translate Support for CR mirror" + default y + +config WARP_DBG_SUPPORT + bool "WARP Driver Debug Info Support" + default y + +config WARP_WDMA_RECYCLE_SUPPORT + bool "WARP WDMA Recycle Support" + default n + +config WED_HW_RRO_SUPPORT + bool "WED HW RRO Support" + default n + +config MTK_MEMORY_SHRINK + bool "Memory Shrink" + default n + +config WARP_MEMORY_LEAK_DBG + bool "Memory leak debug" + depends on !MTK_MEMORY_SHRINK && WARP_DBG_SUPPORT + default y + +config WARP_CHIPSET + string "WARP target chipset" + default colgin + help + For colgin: colgin, for panther: mt7986 + +config WARP_WO_EMBEDDED_LOAD + bool "Emebedded MCU firmware support" + default n + help + Once enabled, firmware download flow try embedded version once externel version being invalid. + +endif + diff --git a/package/mtk/drivers/wifi-profile/Config.in b/package/mtk/drivers/wifi-profile/Config.in new file mode 100644 index 0000000000..5ddb06ee1f --- /dev/null +++ b/package/mtk/drivers/wifi-profile/Config.in @@ -0,0 +1,47 @@ +menuconfig first_card + bool "1st card" + default y + +if first_card + +config first_card_name + string "1st card name" + default "MT7622" +endif + +menuconfig second_card + bool "2nd card" + default n + +if second_card + +config second_card_name + string "2nd card name" + default "MT7615" +endif + +menuconfig third_card + bool "3rd card" + default n + +if third_card + +config third_card_name + string "3rd card name" + default "MT7615" +endif + +choice + prompt "WiFi Setting" + default WIFI_NORMAL_SETTING + config WIFI_NORMAL_SETTING + bool "normal setting" + + config WIFI_QUICK_SETTING + bool "quick setting" + + help + This is a way to configure wifi after wifi reload(Save & Apply from UI). + Normal setting means reloading dat file which will execute "wifi down; wifi up" + Quick setting means executing iwpriv commands corresponding to your operation on UI. +endchoice diff --git a/package/mtk/drivers/wifi-profile/Makefile b/package/mtk/drivers/wifi-profile/Makefile new file mode 100644 index 0000000000..6b30408522 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/Makefile @@ -0,0 +1,65 @@ +# +# Copyright (C) 2016 MediaTek +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/version.mk + +PKG_NAME:=wifi-profile +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define Package/wifi-profile + SECTION:=MTK Properties + CATEGORY:=MTK Properties + SUBMENU:=Drivers + DEPENDS:= + TITLE:=WiFi l1 & l2 profile + VERSION:=$(PKG_RELEASE) + MENU:=1 +endef + +define Package/wifi-profile/description + This package install wifi l1 and l2 profile. +endef + +define Package/wifi-profile/config + if PACKAGE_wifi-profile + source "$(SOURCE)/Config.in" + endif +endef + +define Build/Compile +endef + +define Package/wifi-profile/install + $(INSTALL_DIR) $(1)/etc/wireless/ + $(INSTALL_DIR) $(1)/lib/wifi/ + $(INSTALL_DIR) $(1)/etc/wireless/mediatek/ + $(INSTALL_DIR) $(1)/sbin/ + $(INSTALL_BIN) ./files/common/wifi_jedi $(1)/sbin/wifi + $(INSTALL_BIN) ./files/common/mtwifi.lua $(1)/lib/wifi/ + + if [ "$$(CONFIG_WIFI_QUICK_SETTING)" = "y" ] ; then \ + $(INSTALL_BIN) ./files/common/quick_setting.lua $(1)/lib/wifi/; \ + fi + + if [ "$$(CONFIG_first_card_name)" = "MT7986" -o "$$(CONFIG_second_card_name)" = "MT7986" ] ; then \ + $(INSTALL_DATA) ./files/mt7986/* $(1)/etc/wireless/mediatek/; \ + fi + + if [ "$$(CONFIG_first_card_name)" = "MT7981" -o "$$(CONFIG_second_card_name)" = "MT7981" ] ; then \ + $(INSTALL_DATA) ./files/mt7981/* $(1)/etc/wireless/mediatek/; \ + fi + + if [ -f "$(1)/etc/wireless/mediatek/l1profile.dat" ]; then \ + mv $(1)/etc/wireless/mediatek/l1profile.dat $(1)/etc/wireless/l1profile.dat ; \ + fi +endef + +$(eval $(call BuildPackage,wifi-profile)) diff --git a/package/mtk/drivers/wifi-profile/files/common/mtwifi.lua b/package/mtk/drivers/wifi-profile/files/common/mtwifi.lua new file mode 100755 index 0000000000..7c89ae4e6c --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/common/mtwifi.lua @@ -0,0 +1,331 @@ +#!/usr/bin/lua +-- Alternative for OpenWrt's /sbin/wifi. +-- Copyright Not Reserved. +-- Hua Shao + +package.path = '/lib/wifi/?.lua;'..package.path + +local function esc(x) + return (x:gsub('%%', '%%%%') + :gsub('^%^', '%%^') + :gsub('%$$', '%%$') + :gsub('%(', '%%(') + :gsub('%)', '%%)') + :gsub('%.', '%%.') + :gsub('%[', '%%[') + :gsub('%]', '%%]') + :gsub('%*', '%%*') + :gsub('%+', '%%+') + :gsub('%-', '%%-') + :gsub('%?', '%%?')) +end + +function add_vif_into_lan(vif) + local mtkwifi = require("mtkwifi") + local brvifs = mtkwifi.__trim( mtkwifi.read_pipe("uci get network.lan.ifname")) + + if not string.match(brvifs, esc(vif)) then + nixio.syslog("debug", "add "..vif.." into lan") + brvifs = brvifs.." "..vif + --os.execute("uci set network.lan.ifname=\""..brvifs.."\"") --netifd will down vif form /etc/config/network + --os.execute("uci commit") + --os.execute("ubus call network.interface.lan add_device \"{\\\"name\\\":\\\""..vif.."\\\"}\"") + os.execute("brctl addif br-lan "..vif) -- double insurance for rare failure + if mtkwifi.exists("/proc/sys/net/ipv6/conf/"..vif.."/disable_ipv6") then + os.execute("echo 1 > /proc/sys/net/ipv6/conf/"..vif.."/disable_ipv6") + end + else + nixio.syslog("debug", vif.." is already added into lan") + end + brvifs = string.split(mtkwifi.__trim((mtkwifi.read_pipe("ls /sys/class/net/br-lan/brif/")))) + for _,vif in ipairs(brvifs) do + nixio.syslog("debug", "brvif = "..vif) + end +end + +function del_vif_from_lan(vif) + local mtkwifi = require("mtkwifi") + local brvifs = mtkwifi.__trim(mtkwifi.read_pipe("uci get network.lan.ifname")) + if string.match(brvifs, esc(vif)) then + brvifs = mtkwifi.__trim(string.gsub(brvifs, esc(vif), "")) + nixio.syslog("debug", "del "..vif.." from lan") + --os.execute("uci set network.lan.ifname=\""..brvifs.."\"") + --os.execute("uci commit") + --os.execute("ubus call network.interface.lan remove_device \"{\\\"name\\\":\\\""..vif.."\\\"}\"") + if mtkwifi.exists("/proc/sys/net/ipv6/conf/"..vif.."/disable_ipv6") then + os.execute("echo 0 > /proc/sys/net/ipv6/conf/"..vif.."/disable_ipv6") + end + os.execute("brctl delif br-lan "..vif) + end +end + +function mtwifi_up(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + + nixio.syslog("debug", "mtwifi called!") + + local devs, l1parser = mtkwifi.__get_l1dat() + -- l1 profile present, good! + if l1parser and devs then + dev = devs.devname_ridx[devname] + if not dev then + nixio.syslog("err", "mtwifi: dev "..devname.." not found!") + return + end + local profile = mtkwifi.search_dev_and_profile()[devname] + local cfgs = mtkwifi.load_profile(profile) + -- we have to bring up main_ifname first, main_ifname will create all other vifs. + if mtkwifi.exists("/sys/class/net/"..dev.main_ifname) then + nixio.syslog("debug", "mtwifi_up: ifconfig "..dev.main_ifname.." up") + os.execute("ifconfig "..dev.main_ifname.." up") + add_vif_into_lan(dev.main_ifname) + else + nixio.syslog("err", "mtwifi_up: main_ifname "..dev.main_ifname.." missing, quit!") + return + end + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if vif ~= dev.main_ifname and + ( string.match(vif, esc(dev.ext_ifname).."[0-9]+") + or (string.match(vif, esc(dev.apcli_ifname).."[0-9]+") and + cfgs.ApCliEnable ~= "0" and cfgs.ApCliEnable ~= "") + or (string.match(vif, esc(dev.wds_ifname).."[0-9]+") and + cfgs.WdsEnable ~= "0" and cfgs.WdsEnable ~= "") + or string.match(vif, esc(dev.mesh_ifname).."[0-9]+")) + then + nixio.syslog("debug", "mtwifi_up: ifconfig "..vif.." up") + os.execute("ifconfig "..vif.." up") + add_vif_into_lan(vif) + -- else nixio.syslog("debug", "mtwifi_up: skip "..vif..", prefix not match "..pre) + end + end + + else nixio.syslog("debug", "mtwifi_up: skip "..devname..", config(l1profile) not exist") + end + + os.execute(" rm -rf /tmp/mtk/wifi/mtwifi*.need_reload") +end + +function mtwifi_down(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + + nixio.syslog("debug", "mtwifi_down called!") + + -- M.A.N service + if mtkwifi.exists("/etc/init.d/man") then + os.execute("/etc/init.d/man stop") + end + + local devs, l1parser = mtkwifi.__get_l1dat() + -- l1 profile present, good! + if l1parser and devs then + dev = devs.devname_ridx[devname] + if not dev then + nixio.syslog("err", "mtwifi_down: dev "..devname.." not found!") + return + end + if not mtkwifi.exists("/sys/class/net/"..dev.main_ifname) then + nixio.syslog("err", "mtwifi_down: main_ifname "..dev.main_ifname.." missing, quit!") + return + end + os.execute("iwpriv "..dev.main_ifname.." set hw_nat_register=0") + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if vif == dev.main_ifname + or string.match(vif, esc(dev.ext_ifname).."[0-9]+") + or string.match(vif, esc(dev.apcli_ifname).."[0-9]+") + or string.match(vif, esc(dev.wds_ifname).."[0-9]+") + or string.match(vif, esc(dev.mesh_ifname).."[0-9]+") + then + nixio.syslog("debug", "mtwifi_down: ifconfig "..vif.." down") + os.execute("ifconfig "..vif.." down") + del_vif_from_lan(vif) + -- else nixio.syslog("debug", "mtwifi_down: skip "..vif..", prefix not match "..pre) + end + end + else nixio.syslog("debug", "mtwifi_down: skip "..devname..", config not exist") + end + + os.execute(" rm -rf /tmp/mtk/wifi/mtwifi*.need_reload") +end + +function mtwifi_reload(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + local normal_reload = true + local qsetting = false + local path, profiles + local devs, l1parser = mtkwifi.__get_l1dat() + nixio.syslog("debug", "mtwifi_reload called!") + + if mtkwifi.exists("/lib/wifi/quick_setting.lua") then + qsetting = true + profiles = mtkwifi.search_dev_and_profile() + end + + -- For one card , all interface should be down, then up + if not devname then + for devname, dev in pairs(devs.devname_ridx) do + mtwifi_down(devname) + end + for devname, dev in mtkwifi.__spairs(devs.devname_ridx) do + if qsetting then + -- Create devname.last for quick setting + path = profiles[devname] + if not mtkwifi.exists("/tmp/mtk/wifi/"..string.match(path, "([^/]+)\.dat")..".applied") then + os.execute("cp -f "..path.." "..mtkwifi.__profile_previous_settings_path(path)) + else + os.execute("cp -f "..mtkwifi.__profile_applied_settings_path(path).. + " "..mtkwifi.__profile_previous_settings_path(path)) + end + end + mtwifi_up(devname) + end + else + if qsetting then + path = profiles[devname] + normal_reload = quick_settings(devname, path) + end + + if normal_reload then + local dev = devs.devname_ridx[devname] + assert(mtkwifi.exists(dev.init_script)) + local compatname = dev.init_compatible + -- Different cards do not affect each other + if not string.find(dev.profile_path, "dbdc") then + if dev.init_compatible == compatname then + mtwifi_down(devname) + mtwifi_up(devname) + end + --If the reloaded device belongs to dbdc, then another device on dbdc also need to be reloaded + else + for devname, dev in pairs(devs.devname_ridx) do + if dev.init_compatible == compatname then + mtwifi_down(devname) + end + end + for devname, dev in mtkwifi.__spairs(devs.devname_ridx) do + if dev.init_compatible == compatname then + mtwifi_up(devname) + end + end + end + else mtwifi_up(devname) end + end + -- for ax7800 project, close the ra0. + if string.find(dev.profile_path, "ax7800") then + os.execute("ifconfig ra0 down") + end +end + +function mtwifi_restart(devname) + local nixio = require("nixio") + local uci = require "luci.model.uci".cursor() + local mtkwifi = require("mtkwifi") + local devs, l1parser = mtkwifi.__get_l1dat() + + nixio.syslog("debug", "mtwifi_restart called!") + + -- if wifi driver is built-in, it's necessary action to reboot the device + if mtkwifi.exists("/sys/module/mt_wifi") == false then + os.execute("echo reboot_required > /tmp/mtk/wifi/reboot_required") + return + end + + if devname then + local dev = devs.devname_ridx[devname] + assert(mtkwifi.exists(dev.init_script)) + local compatname = dev.init_compatible + for devname, dev in pairs(devs.devname_ridx) do + if dev.init_compatible == compatname then + mtwifi_down(devname) + end + end + else + for devname, dev in pairs(devs.devname_ridx) do + mtwifi_down(devname) + end + end + os.execute("rmmod mt_whnat") + if mtkwifi.exists("/etc/init.d/fwdd") then + os.execute("/etc/init.d/fwdd stop") + end + os.execute("rmmod mtfwd") + os.execute("rmmod mtk_warp_proxy") + os.execute("rmmod mtk_warp") + -- mt7915_mt_wifi is for dual ko only + os.execute("rmmod mt7915_mt_wifi") + os.execute("rmmod mt_wifi") + + os.execute("modprobe mt_wifi") + os.execute("modprobe mt7915_mt_wifi") + os.execute("modprobe mtk_warp") + os.execute("modprobe mtk_warp_proxy") + os.execute("modprobe mtfwd") + if mtkwifi.exists("/etc/init.d/fwdd") then + os.execute("/etc/init.d/fwdd start") + end + os.execute("modprobe mt_whnat") + if devname then + local dev = devs.devname_ridx[devname] + assert(mtkwifi.exists(dev.init_script)) + local compatname = dev.init_compatible + for devname, dev in pairs(devs.devname_ridx) do + if dev.init_compatible == compatname then + mtwifi_up(devname) + end + end + else + for devname, dev in pairs(devs.devname_ridx) do + mtwifi_up(devname) + end + end +end + +function mtwifi_reset(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + nixio.syslog("debug", "mtwifi_reset called!") + if mtkwifi.exists("/rom/etc/wireless/mediatek/") then + os.execute("rm -rf /etc/wireless/mediatek/") + os.execute("cp -rf /rom/etc/wireless/mediatek/ /etc/wireless/") + mtwifi_reload(devname) + else + nixio.syslog("debug", "mtwifi_reset: /rom"..profile.." missing, unable to reset!") + end +end + +function mtwifi_status(devname) + return wifi_common_status() +end + +function mtwifi_hello(devname) + os.execute("echo mtwifi_hello: "..devname) +end + + +function mtwifi_detect(devname) + local nixio = require("nixio") + local mtkwifi = require("mtkwifi") + nixio.syslog("debug", "mtwifi_detect called!") + + for _,dev in ipairs(mtkwifi.get_all_devs()) do + local relname = string.format("%s%d%d",dev.maindev,dev.mainidx,dev.subidx) + print([[ +config wifi-device ]]..relname.."\n"..[[ + option type mtwifi + option vendor ralink +]]) + for _,vif in ipairs(dev.vifs) do + print([[ +config wifi-iface + option device ]]..relname.."\n"..[[ + option ifname ]]..vif.vifname.."\n"..[[ + option network lan + option mode ap + option ssid ]]..vif.__ssid.."\n") + end + end +end diff --git a/package/mtk/drivers/wifi-profile/files/common/quick_setting.lua b/package/mtk/drivers/wifi-profile/files/common/quick_setting.lua new file mode 100755 index 0000000000..ab12904b2e --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/common/quick_setting.lua @@ -0,0 +1,1030 @@ + +function debug_info_write(devname,content) + local filename = "/tmp/mtk/wifi/"..devname.."_quick_setting_cmd.sh" + local ff = io.open(filename, "a") + ff:write(content) + ff:write("\n") + ff:close() +end + +function token(str, n, default) + local i = 1 + local list = {} + for k in string.gmatch(str, "([^;]+)") do + list[i] = k + i = i + 1 + end + return list[tonumber(n)] or default +end + +function GetFileSize( filename ) + local fp = io.open( filename ) + if fp == nil then + return nil + end + local filesize = fp:seek( "end" ) + fp:close() + return filesize +end + +function vifs_cfg_parm(parm) + local vifs_cfg_parms = {"AuthMode", "EncrypType", "Key", "WPAPSK", "Access", "^WPS", "^wps", "^Wsc", "PIN", "^WEP", ";", "_"} + for _, pat in ipairs(vifs_cfg_parms) do + if string.find(parm, pat) then + return false + end + end + return true +end + +function __set_wifi_apcli_security(cfgs, diff, device, devname) + -- to keep it simple, we always reconf the security if anything related is changed. + -- do optimization only if there's significant performance defect. + --if not diff[ApCliEnable][2] == "1" and cfgs[ApCliEnable] ~= "1" then return end + local vifs = {} -- changed vifs + + -- figure out which vif is changed + -- since multi-bssid is possible, both AuthMode and EncrypType can be a group + local auth_old = cfgs.ApCliAuthMode:split() or {} + local encr_old = cfgs.ApCliEncrypType and cfgs.ApCliEncrypType:split() or {} + local keyid_old = cfgs.ApCliDefaultKeyID:split() or {} + local auth_old_i = (auth_old[1] or ''):split(";") + local encr_old_i = (encr_old[1] or ''):split(";") + local keyid_old_i = (keyid_old[1] or ''):split(";") + local auth_new = diff.ApCliAuthMode and diff.ApCliAuthMode[2]:split() or auth_old + local auth_new_i = (auth_new[1] or ''):split(";") + local encr_new = diff.ApCliEncrypType and diff.ApCliEncrypType[2]:split() or encr_old + local encr_new_i = (encr_new[1] or ''):split(";") + local keyid_new = diff.ApCliDefaultKeyID and diff.ApCliDefaultKeyID[2]:split() or keyid_old + local keyid_new_i = (keyid_new[1] or ''):split(";") + + + --print("encry ="..encr_new[1],auth_new[1], keyid_new[1],keyid_new_i[1]) + --print("encry_old ="..encr_old[1],auth_old[1], keyid_old[1]) + local num = math.max(#encr_old_i, #encr_new_i) + for i = 1, num do + local changed = false + if next(auth_new) and auth_old_i[i] ~= auth_new_i[i] then + changed = true + elseif next(encr_new) and encr_old_i[i] ~= encr_new_i[i] then + changed = true + elseif next(keyid_new) and keyid_old_i[i] ~= keyid_new_i[i] then + changed = true + elseif diff["ApCliWPAPSK"] then + changed = true + else + -- just support apcli0/apclii0/apclix0 + for j = 1, 4 do + if diff["ApCliKey"..tostring(j).."Str"] then + changed = true + break + end + end + end + + if changed then + local vif = {} + vif.idx = i + vif.vifname = device.apcli_ifname..tostring(i-1) + vif.AuthMode = auth_new_i and auth_new_i[i] or auth_old_i[i] + vif.EncrypType = encr_new_i and encr_new_i[i] or encr_old_i[i] + vif.KeyID = keyid_new_i and keyid_new_i[i] or keyid_old_i[i] + vif.DefaultKeyID_idx = "ApCliKey"..tostring(vif.KeyID) + vif.DefaultKey = diff["ApCliKey"..tostring(vif.KeyID).."Str"] + and diff["ApCliKey"..tostring(vif.KeyID).."Str"][2] or cfgs["ApCliKey"..tostring(vif.KeyID).."Str"] + --vif.WEPType = "WEP"..tostring(vif.KeyID).."Type" + --vif.WEPTypeVal = diff["WEP"..tostring(vif.KeyID).."Type"..tostring(i)] and + --diff["WEP"..tostring(vif.KeyID).."Type"..tostring(i)][2] or cfgs["WEP"..tostring(vif.KeyID).."Type"..tostring(i)] + vif.WPAPSK = diff["ApCliWPAPSK"] and diff["ApCliWPAPSK"][2] or cfgs["ApCliWPAPSK"] + vif.SSID = diff["ApCliSsid"] and diff["ApCliSsid"][2] or cfgs["ApCliSsid"] + table.insert(vifs, vif) + end + end + + -- iwpriv here + for i, vif in ipairs(vifs) do + if vif.AuthMode == "OPEN" then + if vif.EncrypType == "WEP" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=OPEN; + iwpriv %s set ApCliEncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set ApCliDefaultKeyID=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, + vif.DefaultKey, vif.vifname, vif.KeyID, vif.vifname) + else + commands = string.format([[ + iwpriv %s set ApCliAuthMode=OPEN; + iwpriv %s set ApCliEncrypType=NONE; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname) + end + elseif vif.AuthMode == "WEPAUTO" and vif.EncrypType == "WEP" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=OPEN; + iwpriv %s set ApCliEncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set ApCliDefaultKeyID=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, + vif.DefaultKey, vif.vifname, vif.KeyID, vif.vifname) + elseif vif.AuthMode == "OWE" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=OWE; + iwpriv %s set ApCliEncrypType=AES; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname) + elseif vif.AuthMode == "SHARED" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=SHARED; + iwpriv %s set ApCliEncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set ApCliDefaultKeyID=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, + vif.DefaultKey, vif.vifname, vif.KeyID, vif.vifname) + elseif vif.AuthMode == "WPA2PSK" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=WPA2PSK; + iwpriv %s set ApCliEncrypType=%s; + iwpriv %s set ApCliWPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA3PSK" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=WPA3PSK; + iwpriv %s set ApCliEncrypType=%s; + iwpriv %s set ApCliWPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPAPSKWPA2PSK" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=WPAPSKWPA2PSK; + iwpriv %s set ApCliEncrypType=%s; + iwpriv %s set ApCliWpaMixPairCipher=WPA_TKIP_WPA2_AES; + iwpriv %s set ApCliWPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA2PSKWPA3PSK" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=WPA2PSKWPA3PSK; + iwpriv %s set ApCliEncrypType=%s; + iwpriv %s set ApCliRekeyMethod=TIME; + iwpriv %s set ApCliWPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPAPSK" then + commands = string.format([[ + iwpriv %s set ApCliAuthMode=WPAPSK; + iwpriv %s set ApCliEncrypType=%s; + iwpriv %s set ApCliWPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA1WPA2" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA1WPA2; + iwpriv %s set EncrypType=%s; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.RADIUS_Server, + vif.vifname,vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + else + error(string.format("invalid AuthMode \"%s\"", vif.AuthMode)) + end + + -- must append extra SSID command to make changes take effect + commands = commands .."\n".. string.format([[ + iwpriv %s set ApCliSSID="%s";]], vif.vifname, vif.SSID) + debug_info_write(devname, commands) + end +end + +function __set_wifi_security(cfgs, diff, device, devname) + -- to keep it simple, we always reconf the security if anything related is changed. + -- do optimization only if there's significant performance defect. + + local vifs = {} -- changed vifs + + -- figure out which vif is changed + -- since multi-bssid is possible, both AuthMode and EncrypType can be a group + local auth_old = cfgs.AuthMode:split() + local encr_old = cfgs.EncrypType:split() + local IEEE8021X_old = cfgs.IEEE8021X:split() + local keyid_old = cfgs.DefaultKeyID:split() + local auth_new = {} + local auth_new1 = {} + local encr_new = {} + local encr_new1 = {} + local IEEE8021X_new ={} + local IEEE8021X_new1 ={} + local keyid_new = {} + local keyid_new1 = {} + + if diff.EncrypType then + encr_new = diff.EncrypType[2]:split() + encr_new1 = encr_new[1]:split(";") + end + if diff.AuthMode then + auth_new = diff.AuthMode[2]:split() + auth_new1 = auth_new[1]:split(";") + end + if diff.IEEE8021X then + IEEE8021X_new = diff.IEEE8021X[2]:split() + IEEE8021X_new1 = IEEE8021X_new[1]:split(";") + end + if diff.DefaultKeyID then + keyid_new = diff.DefaultKeyID[2]:split() + keyid_new1 = keyid_new[1]:split(";") + end + + -- For WPA/WPA2 + local RadiusS_old = cfgs.RADIUS_Server:split() or {} + local RadiusP_old = cfgs.RADIUS_Port:split() or {} + local RadiusS_old_i = (RadiusS_old[1] or ''):split(";") + local RadiusP_old_i = (RadiusP_old[1] or ''):split(";") + local RadiusS_new = diff.RADIUS_Server and diff.RADIUS_Server[2]:split() or RadiusS_old + local RadiusP_new = diff.RADIUS_Port and diff.RADIUS_Port[2]:split() or RadiusP_old + local RadiusS_new_i = (RadiusS_new[1] or ''):split(";") --split by ";" + local RadiusP_new_i = (RadiusP_new[1] or ''):split(";") + + local auth_old1 = auth_old[1]:split(";") --auth_old1[1]=OPEN,auth_old1[2]=WPA2PSK + local encr_old1 = encr_old[1]:split(";") + local IEEE8021X_old1 =IEEE8021X_old[1]:split(";") + local keyid_old1 =keyid_old[1]:split(";") + + for i = 1, #encr_old1 do + local changed = false + if next(auth_new) and auth_old1[i] ~= auth_new1[i] then + changed = true + elseif next(encr_new) and encr_old1[i] ~= encr_new1[i] then + changed = true + elseif next(IEEE8021X_new) and IEEE8021X_old1[i] ~= IEEE8021X_new1[i] then + changed = true + elseif next(keyid_new) and keyid_old1[i] ~= keyid_new1[i] then + changed = true + elseif diff["WPAPSK"..tostring(i)] then + changed = true + elseif next(RadiusS_new) and RadiusS_old_i[i] ~= RadiusS_new_i[i] then + changed = true + elseif next(RadiusP_new) and RadiusP_old_i[i] ~= RadiusP_new_i[i] then + changed = true + elseif diff["RADIUS_Key"..tostring(i)] then + changed = true + else + for j = 1, 4 do + if diff["Key"..tostring(j).."Str"..tostring(i)] then + changed = true + break + end + end + end + + if changed then + local vif = {} + vif.idx = i + vif.vifname = device.ext_ifname..tostring(i-1) + vif.AuthMode = auth_new1 and auth_new1[i] or auth_old1[i] + vif.EncrypType = encr_new1 and encr_new1[i] or encr_old1[i] + vif.KeyID = keyid_new1 and keyid_new1[i] or keyid_old1[i] + vif.DefaultKeyID_idx = "Key"..tostring(vif.KeyID) + vif.DefaultKey = diff["Key"..tostring(vif.KeyID).."Str"..tostring(i)] and + diff["Key"..tostring(vif.KeyID).."Str"..tostring(i)][2] or cfgs["Key"..tostring(vif.KeyID).."Str"..tostring(i)] + vif.WEPType = "WEP"..tostring(vif.KeyID).."Type" + vif.WEPTypeVal = diff["WEP"..tostring(vif.KeyID).."Type"..tostring(i)] and + diff["WEP"..tostring(vif.KeyID).."Type"..tostring(i)][2] or cfgs["WEP"..tostring(vif.KeyID).."Type"..tostring(i)] + vif.WPAPSK = diff["WPAPSK"..tostring(i)] and diff["WPAPSK"..tostring(i)][2] or cfgs["WPAPSK"..tostring(i)] + vif.SSID = diff["SSID"..tostring(i)] and diff["SSID"..tostring(i)][2] or cfgs["SSID"..tostring(i)] + vif.IEEE8021X = IEEE8021X_new1 and IEEE8021X_new1[i] or IEEE8021X_old1[i] + vif.RADIUS_Server = RadiusS_new_i and RadiusS_new_i[i] or RadiusS_old_i[i] + vif.RADIUS_Port = RadiusP_new_i and RadiusP_new_i[i] or RadiusP_old_i[i] + vif.RADIUS_Key = diff["RADIUS_Key"..tostring(i)] and diff["RADIUS_Key"..tostring(i)][2] or cfgs["RADIUS_Key"..tostring(i)] + table.insert(vifs, vif) + end + end + + -- iwpriv here + for i, vif in ipairs(vifs) do + if vif.AuthMode == "OPEN" then + if vif.EncrypType == "WEP" then + commands = string.format([[ + iwpriv %s set AuthMode=OPEN; + iwpriv %s set EncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set DefaultKeyID=%s; + iwpriv %s set %s=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, vif.DefaultKey, + vif.vifname, vif.KeyID, vif.vifname, vif.WEPType,vif.WEPTypeVal, vif.vifname) + elseif vif.EncrypType == "NONE" and vif.IEEE8021X == "1" then + commands = string.format([[ + iwpriv %s set AuthMode=OPEN; + iwpriv %s set EncrypType=NONE; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=1;]], + vif.vifname, vif.vifname, vif.vifname, vif.RADIUS_Server, + vif.vifname, vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + else + commands = string.format([[ + iwpriv %s set AuthMode=OPEN; + iwpriv %s set EncrypType=NONE; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname) + end + elseif vif.AuthMode == "WEPAUTO" and vif.EncrypType == "WEP" then + commands = string.format([[ + iwpriv %s set AuthMode=WEPAUTO; + iwpriv %s set EncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set DefaultKeyID=%s; + iwpriv %s set %s=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, vif.DefaultKey, + vif.vifname, vif.KeyID, vif.vifname, vif.WEPType, vif.WEPTypeVal, vif.vifname) + elseif vif.AuthMode == "OWE" then + commands = string.format([[ + iwpriv %s set AuthMode=OWE; + iwpriv %s set EncrypType=AES; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname) + elseif vif.AuthMode == "SHARED" then + commands = string.format([[ + iwpriv %s set AuthMode=SHARED; + iwpriv %s set EncrypType=WEP; + iwpriv %s set %s="%s"; + iwpriv %s set DefaultKeyID=%s; + iwpriv %s set %s=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.DefaultKeyID_idx, vif.DefaultKey, + vif.vifname, vif.KeyID, vif.vifname, vif.WEPType,vif.WEPTypeVal, vif.vifname) + elseif vif.AuthMode == "WPA2PSK" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA2PSK; + iwpriv %s set EncrypType=%s; + iwpriv %s set WPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA3PSK" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA3PSK; + iwpriv %s set EncrypType=%s; + iwpriv %s set WPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPAPSKWPA2PSK" then + commands = string.format([[ + iwpriv %s set AuthMode=WPAPSKWPA2PSK; + iwpriv %s set EncrypType=%s; + iwpriv %s set WpaMixPairCipher=WPA_TKIP_WPA2_AES; + iwpriv %s set WPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA2PSKWPA3PSK" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA2PSKWPA3PSK; + iwpriv %s set EncrypType=%s; + iwpriv %s set RekeyMethod=TIME; + iwpriv %s set WPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPAPSK" then + commands = string.format([[ + iwpriv %s set AuthMode=WPAPSK; + iwpriv %s set EncrypType=%s; + iwpriv %s set WPAPSK="%s";]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.WPAPSK) + elseif vif.AuthMode == "WPA" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA; + iwpriv %s set EncrypType=%s; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.RADIUS_Server, + vif.vifname, vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + elseif vif.AuthMode == "WPA2" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA2; + iwpriv %s set EncrypType=%s; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.RADIUS_Server, + vif.vifname,vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + elseif vif.AuthMode == "WPA3" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA3; + iwpriv %s set EncrypType=%s; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.RADIUS_Server, + vif.vifname,vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + elseif vif.AuthMode == "WPA1WPA2" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA1WPA2; + iwpriv %s set EncrypType=%s; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.EncrypType, vif.vifname, vif.RADIUS_Server, + vif.vifname,vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + elseif vif.AuthMode == "WPA3-192" then + commands = string.format([[ + iwpriv %s set AuthMode=WPA3-192; + iwpriv %s set EncrypType=GCMP256; + iwpriv %s set RADIUS_Server=%s; + iwpriv %s set RADIUS_Port=%s; + iwpriv %s set RADIUS_Key=%s; + iwpriv %s set IEEE8021X=0;]], + vif.vifname, vif.vifname, vif.vifname, vif.RADIUS_Server, + vif.vifname,vif.RADIUS_Port, vif.vifname, vif.RADIUS_Key, vif.vifname) + else + error(string.format("invalid AuthMode \"%s\"", vif.AuthMode)) + end + + -- must append extra SSID command to make changes take effect + commands = commands .."\n".. string.format([[ + iwpriv %s set SSID="%s";]], vif.vifname, vif.SSID) + debug_info_write(devname, commands) + end +end + +function __set_he_mu(cfgs, diff, device, devname) + local vifs = {} -- changed vifs + + local mu_of_maDl_old = cfgs.MuOfdmaDlEnable:split() + local mu_of_maUl_old = cfgs.MuOfdmaUlEnable:split() + local mu_mi_moDl_old = cfgs.MuMimoDlEnable:split() + local mu_mi_moUl_old = cfgs.MuMimoUlEnable:split() + local mu_of_maDl_new = {} + local mu_of_maDl_new1 = {} + local mu_of_maUl_new = {} + local mu_of_maUl_new1 = {} + local mu_mi_moDl_new = {} + local mu_mi_moDl_new1 = {} + local mu_mi_moUl_new = {} + local mu_mi_moUl_new1 = {} + + if diff.MuOfdmaDlEnable then + mu_of_maDl_new = diff.MuOfdmaDlEnable[2]:split() + mu_of_maDl_new1 = mu_of_maDl_new[1]:split(";") + end + if diff.MuOfdmaUlEnable then + mu_of_maUl_new = diff.MuOfdmaUlEnable[2]:split() + mu_of_maUl_new1 = mu_of_maUl_new[1]:split(";") + end + if diff.MuMimoDlEnable then + mu_mi_moDl_new = diff.MuMimoDlEnable[2]:split() + mu_mi_moDl_new1 = mu_mi_moDl_new[1]:split(";") + end + if diff.MuMimoUlEnable then + mu_mi_moUl_new = diff.MuMimoUlEnable[2]:split() + mu_mi_moUl_new1 = mu_mi_moUl_new[1]:split(";") + end + + local mu_of_maDl_old1 = mu_of_maDl_old[1]:split(";") + local mu_of_maUl_old1 = mu_of_maUl_old[1]:split(";") + local mu_mi_moDl_old1 = mu_mi_moDl_old[1]:split(";") + local mu_mi_moUl_old1 = mu_mi_moUl_old[1]:split(";") + + for i = 1, #mu_of_maDl_old1 do + local changed = false + if next(mu_of_maDl_new) and mu_of_maDl_old1[i] ~= mu_of_maDl_new1[i] then + changed = true + elseif next(mu_of_maUl_new) and mu_of_maUl_old1[i] ~= mu_of_maUl_new1[i] then + changed = true + elseif next(mu_mi_moDl_new) and mu_mi_moDl_old1[i] ~= mu_mi_moDl_new1[i] then + changed = true + elseif next(mu_mi_moUl_new) and mu_mi_moUl_old1[i] ~= mu_mi_moUl_new1[i] then + changed = true + end + + if changed then + local vif = {} + vif.idx = i + vif.vifname = device.ext_ifname..tostring(i-1) + vif.MuOfdmaDlEnable = mu_of_maDl_new1 and mu_of_maDl_new1[i] or mu_of_maDl_old1[i] + vif.MuOfdmaUlEnable = mu_of_maUl_new1 and mu_of_maUl_new1[i] or mu_of_maUl_old1[i] + vif.MuMimoDlEnable = mu_mi_moDl_new1 and mu_mi_moDl_new1[i] or mu_mi_moDl_old1[i] + vif.MuMimoUlEnable = mu_mi_moUl_new1 and mu_mi_moUl_new1[i] or mu_mi_moUl_old1[i] + vif.SSID = diff["SSID"..tostring(i)] and diff["SSID"..tostring(i)][2] or cfgs["SSID"..tostring(i)] + table.insert(vifs, vif) + end + + end + + -- iwpriv here + for i, vif in ipairs(vifs) do + if vif.MuOfdmaDlEnable == "0" then + commands1 = string.format([[ + iwpriv %s set muru_dl_enable=0;]], + vif.vifname) + elseif vif.MuOfdmaDlEnable == "1" then + commands1 = string.format([[ + iwpriv %s set muru_dl_enable=1;]], + vif.vifname) + else + error(string.format("invalid MuOfdmaDlEnable \"%s\"", vif.MuOfdmaDlEnable)) + end + + if vif.MuOfdmaUlEnable == "0" then + commands2 = string.format([[ + iwpriv %s set muru_ul_enable=0;]], + vif.vifname) + elseif vif.MuOfdmaUlEnable == "1" then + commands2 = string.format([[ + iwpriv %s set muru_ul_enable=1;]], + vif.vifname) + else + error(string.format("invalid MuOfdmaUlEnable \"%s\"", vif.MuOfdmaUlEnable)) + end + + if vif.MuMimoDlEnable == "0" then + commands3 = string.format([[ + iwpriv %s set mu_dl_enable=0;]], + vif.vifname) + elseif vif.MuMimoDlEnable == "1" then + commands3 = string.format([[ + iwpriv %s set mu_dl_enable=1;]], + vif.vifname) + else + error(string.format("invalid MuMimoDlEnable \"%s\"", vif.MuMimoDlEnable)) + end + + if vif.MuMimoUlEnable == "0" then + commands4 = string.format([[ + iwpriv %s set mu_ul_enable=0;]], + vif.vifname) + elseif vif.MuMimoUlEnable == "1" then + commands4 = string.format([[ + iwpriv %s set mu_ul_enable=1;]], + vif.vifname) + else + error(string.format("invalid MuMimoUlEnable \"%s\"", vif.MuMimoUlEnable)) + end + + commands = commands1.."\n"..commands2.."\n" ..commands3.."\n"..commands4.."\n".. string.format([[ + iwpriv %s set SSID="%s";]], vif.vifname, vif.SSID) + debug_info_write(devname, commands) + end +end + +--dev cfg, key is dat parm, value is for iwpriv cmd. +function match_dev_parm(key) + local dat_iw_table = { + CountryCode = "CountryCode", + CountryRegion = "CountryRegion", + CountryRegionABand = "CountryRegionABand", + BGProtection = "BGProtection", + ShortSlot = "ShortSlot", + PktAggregate = "PktAggregate", + HT_BADecline = "BADecline", + HT_DisallowTKIP = "HtDisallowTKIP", + TxPreamble = "TxPreamble", + TxBurst = "TxBurst", + HT_MCS = "HtMcs", + HT_EXTCHA = "HtExtCha", + HT_MpduDensity = "HtMpduDensity", + HT_RDG = "HtRdg", + VOW_Airtime_Fairness_En = "vow_airtime_fairness_en", + HT_TxStream = "HtTxStream", + HT_RxStream = "HtRxStream", + DtimPeriod = "DtimPeriod", + IEEE80211H = "IEEE80211H", + HT_BAWinSize = "HtBaWinSize" + } + + return dat_iw_table[key] +end + +function match_dev_parm_no_ssid(key) + local dat_iw_table = { + BeaconPeriod = "BeaconPeriod", + TxPower = "TxPower", + } + + return dat_iw_table[key] +end + +function match_vif_parm(key) + local dat_iw_table = { + APSDCapable = "UAPSDCapable", + FragThreshold = "FragThreshold", + HT_AMSDU = "HtAmsdu", + HT_AutoBA = "HtAutoBa", + HT_GI = "HtGi", + HT_OpMode = "HtOpMode", + HT_PROTECT = "HtProcect", + HT_STBC = "HtStbc", + IgmpSnEnable = "IgmpSnEnable", + NoForwarding = "NoForwarding", + HideSSID = "HideSSID", + WmmCapable = "WmmCapable", + PMKCachePeriod = "PMKCachePeriod", + PreAuth = "PreAuth", + PMFMFPC = "PMFMFPC", + PMFMFPR = "PMFMFPR", + PMFSHA256 = "PMFSHA256", + VHT_STBC = "VhtStbc", + WirelessMode = "WirelessMode", + WscConfMode = "WscConfMode", + WscConfStatus = "WscConfStatus", + VHT_BW_SIGNAL = "VhtBwSignal", + } + + return dat_iw_table[key] +end + +function match_vif_parm_no_ssid(key) + local dat_iw_table = { + RTSThreshold = "RTSThreshold", + } + + return dat_iw_table[key] +end + +function __set_wifi_misc(cfgs, diff, device,devname) + local vifname = device.main_ifname + local vifext = device.ext_ifname + local vifapcli = device.apcli_ifname + local last_command = string.format([[ + iwpriv %s set SSID="%s";]], vifname, cfgs.SSID1) + + local vifidx = cfgs.AuthMode:split(";") + local commands_vifs_ssid = false + local commands_dev = false -- flag for setting ssid + local commands_ssid = {} + local commands_access_1 = {} + local commands_access_2 = {} -- for black list + local commands_bw = false -- for BW, to prevent exexute cmd twice + + for k,v in pairs(diff) do + local commands, commands_1, commands_2, commandns + local commands_vifs, val + if k:find("^SSID") then + local _,_,i = string.find(k, "^SSID([%d]+)") + if i == "1" then + last_command = string.format([[ + iwpriv %s set SSID="%s";]], vifname, tostring(v[2])) + commands_dev = true + else + commands_ssid[tonumber(i)] = string.format([[ + iwpriv %s set SSID="%s";]], vifext..tostring(tonumber(i)-1), tostring(v[2])) + end + ---------------------------------------------------------------------------------------------------- + -----------------------------device config ---------------------------- + elseif k == "Channel" or k == "channel" then + if v[2] == "0" then + cmdchann = string.format([[ + iwpriv %s set AutoChannelSel=3;]], vifname) + else + cmdchann = string.format([[ + iwpriv %s set Channel=%s;]], vifname, tostring(v[2])) + end + debug_info_write(devname, cmdchann) + elseif k == "AutoChannelSelect" then + -- do nothing + elseif k == "PowerUpCckOfdm" or k == "powerupcckOfdm" then + val = "0:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpHT20" or k == "powerupht20" then + val = "1:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpHT40" or k == "powerupht40" then + val = "2:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpVHT20" or k == "powerupvht20" then + val = "3:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpVHT40" or k == "powerupvht40" then + local val = "4:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpVHT80" or k == "powerupvht80" then + val = "5:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + elseif k == "PowerUpVHT160" or k == "powerupvht160" then + val = "6:"..v[2] + commands = string.format([[ + iwpriv %s set TxPowerBoostCtrl=%s;]], vifname, tostring(val)) + + -- Find k in dat_iw_table and return the iwkey for iwpriv. + elseif match_dev_parm(k) then + commands = string.format([[ + iwpriv %s set %s=%s;]], vifname, tostring(match_dev_parm(k)), tostring(v[2])) + + -- Don't need to set SSID + elseif match_dev_parm_no_ssid(k) then + commandns = string.format([[ + iwpriv %s set %s=%s;]], vifname, tostring(match_dev_parm_no_ssid(k)), tostring(v[2])) + + --Wps need double check + --elseif k == "PINCode" or k == "pincode" then + --commands = string.format([[ + --iwpriv %s set WscVendorPinCode=%s;]], vifname, tostring(v[2])) + --elseif k == "PINPBCRadio" or k == "pinpbcradio" then + --commands = string.format([[ + --iwpriv %s set WscMode=%s;]], vifname, tostring(v[2])) + --elseif k == "PIN" or k == "pin" then + --commands = string.format([[ + --iwpriv %s set WscPinCode=%s;]], vifname, tostring(v[2])) + + -- For apcli + elseif k == "MACRepeaterEn" or k == "maprepeateren" then + commands = string.format([[ + iwpriv %s set MACRepeaterEn=%s;]], vifapcli..tostring(0), tostring(v[2])) + + ---------------------------------------------------------------------------------------------------- + -----------------------------interface config ---------------------------- + -- Common case, set vif parameter and it's ssid + elseif match_vif_parm(k) then + for i=1, #vifidx do + if token(cfgs[k], i) ~= token(diff[k][2], i) then + commands_vifs = string.format([[ + iwpriv %s set %s=%s;]], vifext..tostring(tonumber(i)-1), tostring(match_vif_parm(k)), token(diff[k][2], i)) + commands_ssid[i] = string.format([[ + iwpriv %s set SSID=%s;]], vifext..tostring(tonumber(i)-1), diff["SSID"..tostring(i)] and + tostring(diff["SSID"..tostring(i)][2]) or cfgs["SSID"..tostring(i)]) + debug_info_write(devname, commands_vifs) + end + end + + -- Don't need to set SSID, it will take effect immediately after iwpriv + elseif match_vif_parm_no_ssid(k) then + for i=1, #vifidx do + if token(cfgs[k], i) ~= token(diff[k][2], i) then + commands_vifs = string.format([[ + iwpriv %s set %s=%s;]], vifext..tostring(tonumber(i)-1), tostring(match_vif_parm_no_ssid(k)), token(diff[k][2], i)) + debug_info_write(devname, commands_vifs) + end + end + + -- Special case : need to set multiple parameters at the same time when one parameter changed + elseif k == "RekeyInterval" or k == "rekeyinterval" then + for i=1, #vifidx do + if token(cfgs.RekeyInterval, i) ~= token(diff.RekeyInterval[2], i) then + commands_vifs = string.format([[ + iwpriv %s set RekeyInterval=%s;]], vifext..tostring(tonumber(i)-1), token(diff.RekeyInterval[2], i)) + local commands_time = string.format([[ + iwpriv %s set RekeyMethod=TIME;]], vifext..tostring(tonumber(i)-1)) + commands_ssid[i] = string.format([[ + iwpriv %s set SSID=%s;]], vifext..tostring(tonumber(i)-1), diff["SSID"..tostring(i)] and + tostring(diff["SSID"..tostring(i)][2]) or cfgs["SSID"..tostring(i)]) + debug_info_write(devname, commands_vifs) + debug_info_write(devname, commands_time) + end + end + + -- Special case : need to set multiple parameters at the same time when one parameter changed + elseif not commands_bw and k == "HT_BSSCoexistence" then + for i=1, #vifidx do + commands_vifs = string.format([[ + iwpriv %s set HtBssCoex=%s;]], vifext..tostring(tonumber(i)-1), tostring(v[2])) + commands_1 = string.format([[ + iwpriv %s set HtBw=%s;]], vifext..tostring(tonumber(i)-1), diff["HT_BW"] and tostring(diff["HT_BW"][2]) + or tostring(cfgs["HT_BW"])) + commands_2 = string.format([[ + iwpriv %s set VhtBw=%s;]], vifext..tostring(tonumber(i)-1), diff["VHT_BW"] and tostring(diff["VHT_BW"][2]) + or tostring(cfgs["VHT_BW"])) + if commands_vifs then + debug_info_write(devname, commands_1) + debug_info_write(devname, commands_2) + debug_info_write(devname, commands_vifs) + end + end + commands_vifs_ssid = true + commands_bw = true + elseif not commands_bw and k == "HT_BW" then + local htbw = v[2] + local vhtbw = diff["VHT_BW"] and tostring(diff["VHT_BW"][2]) or tostring(cfgs["VHT_BW"]) + for i=1, #vifidx do + commands_vifs = string.format([[ + iwpriv %s set HtBw=%s;]], vifext..tostring(tonumber(i)-1), tostring(v[2])) + commands_1 = string.format([[ + iwpriv %s set VhtBw=%s;]], vifext..tostring(tonumber(i)-1), tostring(vhtbw)) + -- workaround + if htbw == "1" and vhtbw == "0" then + commands_2 = string.format([[ + iwpriv %s set HtBssCoex=%s;]], vifext..tostring(tonumber(i)-1), diff["HT_BSSCoexistence"] + and tostring(diff["HT_BSSCoexistence"][2]) or tostring(cfgs["HT_BSSCoexistence"])) + else + commands_2 = string.format([[ + iwpriv %s set HtBssCoex=0;]], vifext..tostring(tonumber(i)-1)) + end + if commands_vifs then + debug_info_write(devname, commands_vifs) + debug_info_write(devname, commands_1) + debug_info_write(devname, commands_2) + end + end + commands_vifs_ssid = true + commands_bw = true + elseif not commands_bw and k == "VHT_BW" then + local vhtbw = v[2] + local htbw = diff["HT_BW"] and tostring(diff["HT_BW"][2]) or tostring(cfgs["HT_BW"]) + for i=1, #vifidx do + commands_vifs = string.format([[ + iwpriv %s set VhtBw=%s;]], vifext..tostring(tonumber(i)-1), tostring(v[2])) + commands_1 = string.format([[ + iwpriv %s set HtBw=%s;]], vifext..tostring(tonumber(i)-1), tostring(htbw) + or tostring(cfgs["HT_BW"])) + -- workaround + if htbw == "1" and vhtbw == "0" then + commands_2 = string.format([[ + iwpriv %s set HtBssCoex=%s;]], vifext..tostring(tonumber(i)-1), diff["HT_BSSCoexistence"] + and tostring(diff["HT_BSSCoexistence"][2]) or tostring(cfgs["HT_BSSCoexistence"])) + else + commands_2 = string.format([[ + iwpriv %s set HtBssCoex=0;]], vifext..tostring(tonumber(i)-1)) + end + if commands_vifs then + debug_info_write(devname, commands_vifs) + debug_info_write(devname, commands_1) + debug_info_write(devname, commands_2) + end + end + commands_vifs_ssid = true + commands_bw = true + elseif k:find("AccessPolicy") then + local index = string.match(k, '%d') + if commands_access_2[index] then return end + + commands_vifs = string.format([[ + iwpriv %s set AccessPolicy=%s;]], vifext..tostring(index), tostring(v[2])) + debug_info_write(devname, commands_vifs) + if v[2] == '0' then break end + + -- Delete all entry first + local commands_del_list = string.format([[ + iwpriv %s set ACLClearAll=1;]], vifext..tostring(index)) + debug_info_write(devname, commands_del_list) + local list_old = cfgs["AccessControlList"..tostring(index)]:split() or {} + local list_old_i = (list_old[1] or ''):split(";") + local list_new = diff["AccessControlList"..tostring(index)] and diff["AccessControlList"..tostring(index)][2]:split() or {} + local list_old_i = (list_old[1] or ''):split(";") + local list_new_i = (list_new[1] or ''):split(";") + + if diff["AccessControlList"..tostring(index)] then + for i=1, #list_new_i do + local commands_aclist = string.format([[ + iwpriv %s set ACLAddEntry=%s;]], vifext..tostring(index), list_new_i[i]) + debug_info_write(devname, commands_aclist) + end + elseif cfgs["AccessControlList"..tostring(index)] and cfgs["AccessControlList"..tostring(index)] ~= "" then + for i=1, #list_old_i do + local commands_aclist = string.format([[ + iwpriv %s set ACLAddEntry=%s;]], vifext..tostring(index), list_old_i[i]) + debug_info_write(devname, commands_aclist) + end + end + commands_access_1[index] = true + elseif k:find("AccessControlList") then + local index = string.match(k, '%d') + if commands_access_1[index] then return end + -- Clear all entry first + local commands_del_list = string.format([[ + iwpriv %s set ACLClearAll=1;]], vifext..tostring(index)) + debug_info_write(devname, commands_del_list) + -- Then add entries + local commands_ac = string.format([[ + iwpriv %s set AccessPolicy=%s;]], vifext..tostring(index), diff["AccessPolicy"..tostring(index)] + and tostring(diff["AccessPolicy"..tostring(index)][2]) or cfgs["AccessPolicy"..tostring(index)]) + debug_info_write(devname, commands_ac) + local list_new = diff["AccessControlList"..tostring(index)] and diff["AccessControlList"..tostring(index)][2]:split() or {} + local list_new_i = (list_new[1] or ''):split(";") + + if diff["AccessControlList"..tostring(index)] and #list_new_i > 0 then + for i=1, #list_new_i do + local commands_aclist = string.format([[ + iwpriv %s set ACLAddEntry=%s;]], vifext..tostring(index), list_new_i[i]) + debug_info_write(devname, commands_aclist) + end + end + commands_access_2[index] = true + + -- Now I assume that the reset keywords are we did not consider, + -- and they all match the dat's keywords + -- So, I simply set the "iwpriv vif set k=v" + elseif vifs_cfg_parm(k) and vifs_cfg_parm(v[2]) then + if string.find(k, "ApCli") then + commands = string.format([[ + iwpriv %s set %s=%s;]], vifapcli..tostring(0), k, tostring(v[2])) + else + commands = string.format([[ + iwpriv %s set %s=%s;]], vifname, k, tostring(v[2])) + end + end + + if commands then + commands_dev = true -- it will set iwpriv vif set SSID=xxx; + debug_info_write(devname, commands) + elseif commandns then + debug_info_write(devname, commandns) + end + end + + if commands_vifs_ssid then + for i=1, #vifidx do + commands_vifs_ssid = string.format([[ + iwpriv %s set SSID="%s";]], vifext..tostring(tonumber(i)-1), diff["SSID"..tostring(i)] and + tostring(diff["SSID"..tostring(i)][2]) or cfgs["SSID"..tostring(i)]) + debug_info_write(devname, commands_vifs_ssid) + end + else + local ssid1 = true + for i=1, #vifidx do + if commands_ssid[i] then + debug_info_write(devname, commands_ssid[i]) + if i == 1 then ssid1 = false end + end + end + if ssid1 and commands_dev then debug_info_write(devname, last_command) end + end +end + +function quick_settings(devname,path) + local mtkwifi = require("mtkwifi") + local devs, l1parser = mtkwifi.__get_l1dat() + local path_last, cfgs, diff, device + assert(l1parser, "failed to parse l1profile!") + + -- If there is't /tmp/mtk/wifi/devname.last, wifi down/wifi up is necessary. + -- Case 1: The first time wifi setup; + -- Case 2: When reload wifi by pressing UI button. + if not mtkwifi.exists("/tmp/mtk/wifi/"..string.match(path, "([^/]+)\.dat")..".last") then + need_downup = true + end + -- Copy /tmp/mtk/wifi/devname.applied to /tmp/mtk/wifi/devname.last for diff + if not mtkwifi.exists("/tmp/mtk/wifi/"..string.match(path, "([^/]+)\.dat")..".applied") then + os.execute("cp -f "..path.." "..mtkwifi.__profile_previous_settings_path(path)) + else + os.execute("cp -f "..mtkwifi.__profile_applied_settings_path(path).. + " "..mtkwifi.__profile_previous_settings_path(path)) + end + -- there are no /tmp/mtk/wifi/devname.last + if need_downup then return true end + + path_last = mtkwifi.__profile_previous_settings_path(path) + diff = mtkwifi.diff_profile(path_last, path) + cfgs = mtkwifi.load_profile(path_last) + + if not next(diff) then return true end -- diff == nil + + -- It maybe better to save this parms in a new file. + need_downup_parms = {"HT_LDPC", "VHT_SGI", "VHT_LDPC", "idle_timeout_interval", + "E2pAccessMode", "MUTxRxEnable","DLSCapable","VHT_Sec80_Channel", + "Wds", "PowerUpenable", "session_timeout_interval", "MapMode", + "ChannelGrp","TxOP"} + + for k, v in pairs(diff) do + nixio.syslog("debug", "quick_settings diff : "..k.."="..v[2]) + for _, pat in ipairs(need_downup_parms) do + if string.find(k, pat) then + need_downup = true; + nixio.syslog("debug", "quick_settings: need_downup "..k.."="..v[2]) + break + end + end + if need_downup then break end + end + if need_downup then return true end + + + -- Quick Setting + os.execute("rm -rf /tmp/mtk/wifi/"..devname.."_quick_setting_cmd.sh") + device = devs.devname_ridx[devname] + + -- need to set Authmode and Encry before MFPC&MFPR + if cfgs["ApCliEnable"] and cfgs["ApCliEnable"] == "1" or + diff["ApCliEnable"] and diff["ApCliEnable"][2] =="1" then + __set_wifi_apcli_security(cfgs, diff, device, devname) + end + + __set_wifi_misc(cfgs, diff, device, devname) + + __set_he_mu(cfgs, diff, device, devname) + + -- security is complicated enough to get a special API + __set_wifi_security(cfgs, diff, device, devname) + + --execute all iwpriv cmd + os.execute("sh /tmp/mtk/wifi/"..devname.."_quick_setting_cmd.sh") + + -- save the quick seting log, we assume it can hold up to 10000 at most. + if mtkwifi.exists("/tmp/mtk/wifi/"..devname.."_quick_setting_cmd.sh") then + if mtkwifi.exists("/tmp/mtk/wifi/quick_setting_cmds.log") then + filesize = GetFileSize("/tmp/mtk/wifi/quick_setting_cmds.log") + if filesize > 10000 then + os.execute("mv -f /tmp/mtk/wifi/quick_setting_cmds.log /tmp/mtk/wifi/quick_setting_cmds_bak.log") + end + end + os.execute("echo ............................................... >> /tmp/mtk/wifi/quick_setting_cmds.log") + os.execute("cat /tmp/mtk/wifi/"..devname.."_quick_setting_cmd.sh >> /tmp/mtk/wifi/quick_setting_cmds.log") + end + return false +end diff --git a/package/mtk/drivers/wifi-profile/files/common/wifi_jedi b/package/mtk/drivers/wifi-profile/files/common/wifi_jedi new file mode 100755 index 0000000000..dec7ca7279 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/common/wifi_jedi @@ -0,0 +1,222 @@ +#!/usr/bin/env lua +-- Alternative for OpenWrt's /sbin/wifi. +-- Copyright Not Reserved. +-- Hua Shao + +package.path = '/lib/wifi/?.lua;'..package.path + +local mtkwifi = require("mtkwifi") +local nixio = require("nixio") + +function usage() + print("wifi [devname]") +end + + +function wifi_common_up(devname) + nixio.syslog("debug", "wifi_common_up "..tostring(devname)) + + -- need to find out the vif prefix for this device + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if string.match(vif, "ra%a-%d+") then + os.execute("ifconfig "..vif.." up") + end + end + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if string.match(vif, "apcli%a-%d+") then + os.execute("ifconfig "..vif.." up") + end + end + + if devname then + os.execute("rm -f /tmp/mtk/wifi/"..devname.."*.need_reload") + else + os.execute("rm -f /tmp/mtk/wifi/*.need_reload") + end +end + + +function wifi_common_down(devname) + nixio.syslog("debug", "wifi_common_down "..tostring(devname)) + + -- need to find out the vif prefix for this device + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), "\n")) + do + if string.match(vif, "apcli%d+") + or string.match(vif, "apclii%d+") then + os.execute("ifconfig "..vif.." down") + end + end + for _,vif in ipairs(string.split(mtkwifi.read_pipe("ls /sys/class/net"), " ")) + do + if string.match(vif, "ra%d+") + or string.match(vif, "rai%d+") + or string.match(vif, "rae%d+") + or string.match(vif, "rax%d+") then + os.execute("ifconfig "..vif.." down") + end + end +end + +function wifi_common_restart(devname) + nixio.syslog("debug", "wifi_common_restart "..tostring(devname)) + wifi_common_up() + wifi_common_down() +end + +function wifi_common_reload(devname) + nixio.syslog("debug", "wifi_common_reload "..tostring(devname)) + wifi_common_up() + wifi_common_down() +end + +function wifi_common_reset(devname) + nixio.syslog("debug", "wifi_common_reset called!") + local curpath = "/etc/wireless/" + if devname then + curpath = curpath..devname.."/" + end + local defpath = "/rom"..defpath + if mtkwifi.exists(defpath) then + os.execute("rm -rf "..curpath) + os.execute("cp -rf "..defpath.." "..curpath) + wifi_common_reload() + else + nixio.syslog("debug", defpath.." missing, unable to reset!") + end +end + +function wifi_common_status(devname) + nixio.syslog("debug", "wifi_common_status "..tostring(devname)) + print(mtkwifi.read_pipe("iwconfig")) + print(mtkwifi.read_pipe("ifconfig -a")) +end + +function wifi_common_detect(devname) + nixio.syslog("debug", "wifi_common_detect "..tostring(devname)) + local devs = mtkwifi.getdevs() + for _,dev in ipairs(devs) do + print("config wifi-device "..dev.devname.. + "\n\toption type "..dev.devname.. + "\n\toption vendor ralink".. + "\n\toption channel "..dev.Channel) + for _,vif in ipairs(dev.vifs) do + print("\nconfig wifi-iface".. + "\n\toption device"..dev.devname.. + "\n\toption ifname"..vif.vifname.. + "\n\toption network lan".. + "\n\toption mode ap") + end + end +end + +for _,f in ipairs(string.split(mtkwifi.read_pipe("find /lib/wifi/ -name \"*.lua\" 2>/dev/null"), "\n")) do + dofile(f) +end + +function wifi(cmd, devname) + local mtkwifi = require("mtkwifi") + local devs, l1parser = mtkwifi.__get_l1dat() + l1parser.creat_link_for_nvram() + if not devs or not l1parser then + return wifi_orig(cmd, devname) + end + + if devname then + local dev = devs.devname_ridx[devname] + local compatname = dev.init_compatible + assert(compatname) + + if _G[compatname.."_"..cmd] then + nixio.syslog("info", "call "..compatname.."_"..cmd.."("..devname..")") + _G[compatname.."_"..cmd](devname) + end + else + -- if devname not specified + if cmd == "restart" or cmd == "reload" then + local tab_compatname = {} + for key, dev in pairs(devs.devname_ridx) do + tab_compatname[key] = dev.init_compatible + end + local tab_rp = {} + for key,val in pairs(tab_compatname) do + tab_rp[val] = true + end + + for dev, val in pairs(tab_rp) do + nixio.syslog("info", "call "..dev.."_"..cmd) + _G[dev.."_"..cmd]() + end + else + for devname, dev in mtkwifi.__spairs(devs.devname_ridx) do + local compatname = dev.init_compatible + nixio.syslog("info", "call "..compatname.."_"..cmd.."("..devname..")") + _G[compatname.."_"..cmd](devname) + end + end + end +end + +function wifi_orig(cmd,devname) + print("wifi_orig",cmd,devname) + local relname = nil + if devname then + relname = string.split(devname,".")[1] + end + + if relname then + if _G[relname.."_"..cmd] then + nixio.syslog("info", "call "..relname.."_"..cmd.."("..devname..")") + _G[relname.."_"..cmd](devname) + end + else + local devinfo = mtkwifi.search_dev_and_profile() + local done = {} + for __devname in pairs(devinfo) do + local __relname = string.split(__devname,".")[1] + repeat + -- common case + if done[__relname] then break else done[__relname] = true end + if _G[__relname.."_"..cmd] then + nixio.syslog("info", "call "..__relname.."_"..cmd.."("..__devname..")") + _G[__relname.."_"..cmd](__devname) + break + end + -- try shell + local dev_shell = "/lib/wifi/"..__relname..".sh" + if mtkwifi.exists(dev_shell) then + local cmd = "source "..dev_shell.."; "..__relname.."_"..cmd.." > /dev/null" + nixio.syslog("info", cmd) + if os.execute(cmd) ~= 0 then + nixio.syslog("err", cmd) + end + break + end + -- fall back on common api + nixio.syslog("info", "no scripts for "..__relname.." found, fall back on common api!") + _G["wifi_common_"..cmd](__devname) + until true + end + end +end + +cmd = arg[1] +dev = arg[2] + +if cmd == "up" +or cmd == "down" +or cmd == "status" +or cmd == "detect" +or cmd == "reload" +or cmd == "restart" +or cmd == "reset" then + wifi(cmd, dev) +elseif cmd == "reload_legacy" then + nixio.syslog("info", "legacy command "..cmd) + wifi("reload", dev) +else + usage() +end + diff --git a/package/mtk/drivers/wifi-profile/files/mt7981/l1profile.dat b/package/mtk/drivers/wifi-profile/files/mt7981/l1profile.dat new file mode 100644 index 0000000000..00d915ee5d --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/mt7981/l1profile.dat @@ -0,0 +1,16 @@ +Default +INDEX0=MT7981 +INDEX0_profile_path=/etc/wireless/mediatek/mt7981.dbdc.b0.dat;/etc/wireless/mediatek/mt7981.dbdc.b1.dat +INDEX0_init_script=/lib/wifi/mtwifi.lua;/lib/wifi/mtwifi.lua +INDEX0_init_compatible=mtwifi;mtwifi +INDEX0_EEPROM_offset=0x0 +INDEX0_EEPROM_size=0x5000 +INDEX0_EEPROM_name=e2p +INDEX0_main_ifname=ra0;rax0 +INDEX0_ext_ifname=ra;rax +INDEX0_wds_ifname=wds;wdsx +INDEX0_apcli_ifname=apcli;apclix +INDEX0_mesh_ifname=mesh;meshx +INDEX0_nvram_zone=dev1;dev2 +INDEX0_single_sku_path=/etc/wireless/mediatek/mt7981-sku.dat +INDEX0_bf_sku_path=/etc/wireless/mediatek/mt7981-sku-bf.dat diff --git a/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku-bf.dat b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku-bf.dat new file mode 100644 index 0000000000..b7a18fce67 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku-bf.dat @@ -0,0 +1,71 @@ +# Single SKU Max Power Table (unit is 1 dBm) +# 2.4G Channel +Band: 2.4G MaxPower_4T MaxPower_3T MaxPower_2T +Ch1 14 14 13 +Ch2 12 11 17 +Ch3 16 11 12 +Ch4 7 11 7 +Ch5 12 15 13 +Ch6 11 14 9 +Ch7 10 15 6 +Ch8 15 17 14 +Ch9 6 9 6 +Ch10 16 13 8 +Ch11 14 14 7 +Ch12 11 9 8 +Ch13 6 11 14 +Ch14 17 13 16 + +# 5G Channel +Band: 5G MaxPower_4T MaxPower_3T MaxPower_2T +Ch184 15 10 14 +Ch188 10 17 15 +Ch192 6 12 8 +Ch196 13 6 8 +Ch8 12 13 11 +Ch12 11 10 16 +Ch16 12 13 11 +Ch36 9 9 12 +Ch40 7 15 7 +Ch44 17 15 13 +Ch48 8 7 8 +Ch52 8 11 10 +Ch56 11 10 11 +Ch60 7 6 15 +Ch64 13 16 11 +Ch68 6 9 13 +Ch72 13 16 17 +Ch76 12 13 6 +Ch80 17 14 6 +Ch84 11 7 7 +Ch88 9 8 17 +Ch92 16 8 12 +Ch96 16 13 6 +Ch100 8 7 13 +Ch104 13 14 10 +Ch108 14 8 6 +Ch112 16 17 12 +Ch116 16 13 12 +Ch120 7 10 7 +Ch124 14 13 9 +Ch128 17 10 17 +Ch132 12 6 11 +Ch136 17 17 10 +Ch140 6 15 6 +Ch144 12 7 10 +Ch149 9 12 16 +Ch153 10 15 11 +Ch157 8 8 14 +Ch161 11 6 7 +Ch165 11 7 15 +Ch169 17 6 13 +Ch173 8 15 12 +Ch177 10 15 7 +Ch181 13 11 10 + + + + + + + diff --git a/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku.dat b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku.dat new file mode 100644 index 0000000000..2296b53822 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981-sku.dat @@ -0,0 +1,64 @@ +# Single SKU Max Power Table (unit is 1 dBm) +# 2.4G Channel CCK OFDM VHT20 VHT40 TxStreamCapability_Delta TxSpatialStream_Delta +Band: 2.4G CCK_1M CCK_2M CCK_5.5M CCK_11M OFDM_6M OFDM_9M OFDM_12M OFDM_18M OFDM_24M OFDM_36M OFDM_48M OFDM_54M VHT20_MCS0 VHT20_MCS1 VHT20_MCS2 VHT20_MCS3 VHT20_MCS4 VHT20_MCS5 VHT20_MCS6 VHT20_MCS7 VHT20_MCS8 VHT20_MCS9 VHT40_MCS0 VHT40_MCS1 VHT40_MCS2 VHT40_MCS3 VHT40_MCS4 VHT40_MCS5 VHT40_MCS6 VHT40_MCS7 VHT40_MCS8 VHT40_MCS9 Txstream_3T Txstream_2T Txstream_1T Txstream_1SS Txstream_2SS Txstream_3SS Txstream_4SS +Ch1 16 12 15 17 18 11 10 15 15 15 18 15 10 16 20 11 17 13 9 8 20 1 3 6 6 3 1 0 +Ch2 11 19 19 11 15 18 17 16 20 14 13 11 14 10 19 17 18 9 15 18 8 1 3 6 6 3 1 0 +Ch3 13 11 14 12 11 12 9 18 14 14 19 17 11 16 20 17 20 8 18 8 18 1 3 6 6 3 1 0 +Ch4 13 14 15 10 18 9 10 10 20 13 8 13 8 10 20 17 18 13 17 19 20 1 3 6 6 3 1 0 +Ch5 10 12 14 12 9 15 19 9 8 17 11 13 8 17 9 20 16 11 16 13 8 1 3 6 6 3 1 0 +Ch6 20 9 15 11 10 17 16 8 18 17 13 9 18 13 15 9 13 14 14 12 17 1 3 6 6 3 1 0 +Ch7 11 19 20 17 15 16 17 9 19 20 12 14 15 11 14 11 16 12 8 20 18 1 3 6 6 3 1 0 +Ch8 13 9 15 14 14 10 11 13 13 12 10 18 10 15 12 9 19 15 18 14 13 1 3 6 6 3 1 0 +Ch9 18 9 19 20 15 15 8 9 18 14 17 8 10 13 12 11 8 14 10 13 11 1 3 6 6 3 1 0 +Ch10 9 9 20 20 19 11 17 18 19 11 20 18 18 18 9 19 10 8 12 17 16 1 3 6 6 3 1 0 +Ch11 15 11 8 8 12 9 18 18 8 9 17 13 15 9 9 11 19 10 11 14 20 1 3 6 6 3 1 0 +Ch12 11 13 11 15 20 8 11 19 19 9 9 15 17 11 17 20 17 12 16 16 8 1 3 6 6 3 1 0 +Ch13 8 9 18 12 9 12 15 14 13 15 18 13 15 13 20 14 19 12 20 17 9 1 3 6 6 3 1 0 +Ch14 12 19 8 16 12 8 15 9 14 13 16 10 11 17 20 9 14 10 9 13 16 1 3 6 6 3 1 0 + +# 5G Channel OFDM VHT20 VHT40 VHT80 VHT160 Txstream_Delta TxSpatialStream_Delta +Band: 5G OFDM_6M OFDM_9M OFDM_12M OFDM_18M OFDM_24M OFDM_36M OFDM_48M OFDM_54M VHT20_MCS0 VHT20_MCS1 VHT20_MCS2 VHT20_MCS3 VHT20_MCS4 VHT20_MCS5 VHT20_MCS6 VHT20_MCS7 VHT20_MCS8 VHT20_MCS9 VHT40_MCS0 VHT40_MCS1 VHT40_MCS2 VHT40_MCS3 VHT40_MCS4 VHT40_MCS5 VHT40_MCS6 VHT40_MCS7 VHT40_MCS8 VHT40_MCS9 VHT80_MCS0 VHT80_MCS1 VHT80_MCS2 VHT80_MCS3 VHT80_MCS4 VHT80_MCS5 VHT80_MCS6 VHT80_MCS7 VHT80_MCS8 VHT80_MCS9 VHT160_MCS0 VHT160_MCS1 VHT160_MCS2 VHT160_MCS3 VHT160_MCS4 VHT160_MCS5 VHT160_MCS6 VHT160_MCS7 VHT160_MCS8 VHT160_MCS9 Txstream_3T Txstream_2T Txstream_1T Txstream_1SS Txstream_2SS Txstream_3SS Txstream_4SS +Ch184 9 8 12 18 16 17 13 12 16 10 17 9 10 16 16 10 10 14 9 13 13 19 16 16 12 9 15 18 18 10 18 11 9 1 3 6 6 3 1 0 +Ch188 8 18 9 13 9 11 16 20 20 14 12 9 13 13 8 20 12 17 13 9 9 14 15 19 16 9 12 13 17 14 19 9 12 1 3 6 6 3 1 0 +Ch192 15 9 10 9 17 17 20 19 13 18 11 18 16 12 8 16 18 9 20 12 12 17 17 19 12 9 10 16 13 15 18 9 9 1 3 6 6 3 1 0 +Ch196 13 10 17 19 8 15 19 12 18 12 10 16 16 12 15 11 19 17 12 10 10 19 20 18 8 16 10 20 8 19 15 13 8 1 3 6 6 3 1 0 +Ch8 15 16 10 19 8 15 19 11 11 15 17 19 13 8 16 12 10 9 12 16 14 13 13 12 18 8 12 20 14 14 20 9 15 1 3 6 6 3 1 0 +Ch12 12 12 19 19 12 20 17 19 18 18 19 17 13 16 15 17 13 11 9 13 11 19 13 13 14 20 13 17 14 19 18 15 11 1 3 6 6 3 1 0 +Ch16 15 8 18 15 11 14 14 9 17 18 16 19 19 11 8 11 13 20 16 17 17 14 18 13 14 16 20 14 15 15 18 11 20 1 3 6 6 3 1 0 +Ch36 8 14 8 17 9 14 20 10 8 11 15 9 13 8 16 14 20 9 14 17 11 9 20 16 20 12 13 17 18 20 16 8 12 1 3 6 6 3 1 0 +Ch40 14 13 12 16 12 11 15 10 11 12 10 12 11 12 15 8 14 11 14 14 19 8 9 8 15 9 10 17 18 19 16 10 11 1 3 6 6 3 1 0 +Ch44 16 20 20 9 12 12 10 11 18 16 9 13 13 16 8 9 9 10 10 11 12 18 11 8 8 12 9 14 15 17 19 13 16 1 3 6 6 3 1 0 +Ch48 17 14 14 8 18 15 11 12 19 9 12 10 19 20 20 14 14 15 18 9 8 11 12 17 20 13 18 12 12 9 14 19 17 1 3 6 6 3 1 0 +Ch52 10 17 8 12 10 15 16 11 20 14 12 17 17 17 10 20 9 18 11 13 20 18 15 10 20 12 11 18 19 9 15 13 9 1 3 6 6 3 1 0 +Ch56 9 13 11 13 18 12 15 17 11 11 8 8 9 19 9 11 17 19 12 17 10 13 19 10 19 19 12 15 8 20 14 15 15 1 3 6 6 3 1 0 +Ch60 14 8 18 8 17 19 18 16 12 15 14 15 15 19 18 12 17 19 11 17 8 10 19 9 16 17 13 11 14 18 14 8 16 1 3 6 6 3 1 0 +Ch64 9 20 10 13 13 19 11 20 13 8 11 12 12 12 11 12 8 18 11 12 15 16 11 10 15 20 10 12 14 15 12 8 17 1 3 6 6 3 1 0 +Ch68 8 20 9 19 12 14 8 18 14 15 20 12 10 8 10 12 15 20 14 8 13 16 15 11 13 12 14 20 11 11 10 16 20 1 3 6 6 3 1 0 +Ch72 14 18 15 14 17 15 20 16 18 16 12 17 16 18 12 20 13 14 8 8 13 18 8 13 16 8 18 9 14 8 17 13 17 1 3 6 6 3 1 0 +Ch76 8 11 17 15 15 16 10 11 12 13 11 14 20 17 18 12 11 17 13 11 13 16 15 18 11 11 13 17 13 9 11 17 14 1 3 6 6 3 1 0 +Ch80 16 19 19 11 15 8 13 20 13 17 11 15 14 19 14 20 16 8 15 10 12 16 16 17 8 8 19 20 13 11 14 16 11 1 3 6 6 3 1 0 +Ch84 9 11 13 11 16 16 13 20 8 15 19 16 17 11 11 10 16 16 19 19 13 15 12 9 19 13 19 19 18 18 12 17 13 1 3 6 6 3 1 0 +Ch88 14 14 14 9 16 13 16 17 12 19 8 19 12 12 10 12 17 10 13 19 15 12 10 14 9 17 8 10 19 10 11 9 11 1 3 6 6 3 1 0 +Ch92 11 20 9 19 18 15 11 9 11 20 13 15 9 10 10 12 17 20 13 9 20 12 17 15 17 17 19 9 20 13 16 13 20 1 3 6 6 3 1 0 +Ch96 13 20 13 11 17 8 18 8 17 14 18 9 13 16 19 13 20 11 19 19 17 12 8 20 9 14 18 10 8 20 13 14 16 1 3 6 6 3 1 0 +Ch100 13 20 11 13 20 14 15 13 20 20 13 16 14 9 20 10 18 18 14 12 20 17 20 8 12 14 19 20 15 17 20 10 9 1 3 6 6 3 1 0 +Ch104 9 19 10 17 12 9 12 14 17 10 13 14 15 16 19 8 10 8 9 17 11 13 10 16 17 20 10 11 17 18 10 8 17 1 3 6 6 3 1 0 +Ch108 15 14 16 17 12 11 13 16 14 10 12 16 17 12 12 17 18 10 14 18 13 13 16 10 16 20 9 20 14 8 8 12 13 1 3 6 6 3 1 0 +Ch112 11 13 19 14 8 10 16 10 11 16 13 20 13 14 10 14 8 13 17 12 16 16 10 16 11 17 19 12 19 16 18 11 10 1 3 6 6 3 1 0 +Ch116 8 15 16 13 11 11 12 11 8 9 15 12 8 9 16 20 18 14 11 17 13 15 9 8 11 16 20 13 11 14 13 16 9 1 3 6 6 3 1 0 +Ch120 9 19 12 11 15 17 11 16 8 11 8 14 17 17 14 15 16 11 19 14 20 9 14 15 19 15 19 11 20 18 13 17 11 1 3 6 6 3 1 0 +Ch124 11 16 15 17 11 14 18 11 14 10 8 14 18 17 11 17 15 18 15 15 10 11 18 18 16 13 10 10 18 17 20 13 15 1 3 6 6 3 1 0 +Ch128 8 13 14 17 10 19 15 9 11 11 17 20 11 20 11 12 18 14 8 16 18 12 18 16 12 8 20 14 17 14 19 14 14 1 3 6 6 3 1 0 +Ch132 10 18 8 11 16 17 18 11 10 8 10 14 17 9 13 12 18 20 11 19 17 12 14 13 17 17 13 19 16 8 10 10 11 1 3 6 6 3 1 0 +Ch136 13 17 10 11 8 20 11 11 19 20 12 14 11 12 16 10 9 18 16 11 19 14 19 12 11 13 13 17 18 19 14 18 18 1 3 6 6 3 1 0 +Ch140 17 11 19 17 14 14 12 15 16 12 20 8 8 18 13 10 18 17 10 19 18 17 12 17 15 12 13 14 8 18 11 12 16 1 3 6 6 3 1 0 +Ch144 9 18 13 8 11 14 17 18 16 17 10 17 14 8 13 20 20 14 11 16 9 14 16 19 18 14 9 18 12 19 16 11 16 1 3 6 6 3 1 0 +Ch149 17 10 11 8 18 20 16 13 18 19 19 9 16 9 16 13 16 18 14 11 14 20 9 17 18 10 14 10 20 10 11 13 9 1 3 6 6 3 1 0 +Ch153 14 13 16 19 9 12 16 15 20 18 14 13 17 11 11 19 9 12 9 8 9 11 11 9 12 14 20 8 16 11 15 16 16 1 3 6 6 3 1 0 +Ch157 11 18 19 15 20 8 14 19 17 12 15 16 13 13 19 9 20 12 17 20 12 11 8 14 13 18 14 12 12 13 13 19 20 1 3 6 6 3 1 0 +Ch161 10 17 14 17 11 19 20 18 8 17 10 18 17 18 17 8 9 18 16 14 9 20 19 12 15 12 15 11 12 19 10 20 18 1 3 6 6 3 1 0 +Ch165 11 10 12 16 13 11 12 16 11 11 15 11 20 20 10 15 8 20 17 9 15 12 16 18 17 8 14 10 19 12 17 17 20 1 3 6 6 3 1 0 +Ch169 17 19 12 20 13 17 15 16 18 11 8 17 9 15 12 16 18 12 17 8 15 17 19 8 11 10 18 16 16 20 12 16 13 1 3 6 6 3 1 0 +Ch173 19 17 14 14 18 20 13 9 11 18 19 11 15 13 8 20 20 20 15 14 17 12 19 20 15 16 17 17 12 8 12 16 9 1 3 6 6 3 1 0 +Ch177 8 17 10 13 12 18 18 18 17 12 10 19 11 8 16 18 13 9 18 13 8 14 11 9 12 14 11 15 13 14 13 19 16 1 3 6 6 3 1 0 +Ch181 20 19 19 8 12 14 14 12 20 16 13 10 19 11 8 18 10 9 15 11 12 12 14 19 18 18 20 20 14 14 17 14 14 1 3 6 6 3 1 0 diff --git a/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b0.dat b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b0.dat new file mode 100644 index 0000000000..c234b6d538 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b0.dat @@ -0,0 +1,435 @@ +#The word of "Default" must not be removed +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable=0 +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +ApCliMuOfdmaDlEnable=0 +ApCliMuOfdmaUlEnable=0 +ApCliMuMimoDlEnable=0 +ApCliMuMimoUlEnable=0 +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=3 +AutoChannelSkipList=14 +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=0 +ChannelGrp= +CountryCode=CN +CountryRegion=1 +CountryRegionABand=7 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=1 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br-lan +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=0 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=1 +AMSDU_NUM=8 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=256 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=4 +HT_OpMode=0 +HT_PROTECT=1 +HT_RDG=0 +HT_RxStream=2 +HT_STBC=1 +HT_TxStream=2 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=0 +IEEE8021X=0 +IgmpSnEnable=1 +ITxBfEn=0 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MeshAuthMode= +MeshAutoLink=0 +MeshDefaultkey=0 +MeshEncrypType= +MeshId= +MeshWEPKEY= +MeshWPAKEY= +MUTxRxEnable=1 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=192.168.1.1 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=0 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br-lan +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=1 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SkuTableIdx=0 +SKUenable=0 +SREnable=1 +SRMode=0 +SRDPDEnable=0 +SRSDEnable=1 +PPEnable=0 +SSID= +SSID1=MTK_CHEETAH_AP_2.4G +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +CCKTxStream=4 +TWTSupport=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=0 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +Vht1024QamSupport=0 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En= +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En= +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WapiAsCertPath= +WapiAsIpAddr= +WapiAsPort= +Wapiifname= +WapiPsk1= +WapiPsk10= +WapiPsk11= +WapiPsk12= +WapiPsk13= +WapiPsk14= +WapiPsk15= +WapiPsk16= +WapiPsk2= +WapiPsk3= +WapiPsk4= +WapiPsk5= +WapiPsk6= +WapiPsk7= +WapiPsk8= +WapiPsk9= +WapiPskType= +WapiUserCertPath= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=1 +WiFiTest=0 +WirelessMode=16 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 +TxCmdMode=1 +MuOfdmaDlEnable=1 +MuOfdmaUlEnable=1 +MuMimoDlEnable=1 +MuMimoUlEnable=1 +MapMode=0 +IsICAPFW=0 +KernelRps=1 +MboSupport=1 +BSSColorValue=255 +QoSR1Enable=1 +DscpPriMapEnable=1 +ScsEnable=0 +QoSMgmtCapa=0 +BcnProt=0 +ApCliBcnProt=0 diff --git a/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b1.dat b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b1.dat new file mode 100644 index 0000000000..420ddb13b6 --- /dev/null +++ b/package/mtk/drivers/wifi-profile/files/mt7981/mt7981.dbdc.b1.dat @@ -0,0 +1,437 @@ +#The word of "Default" must not be removed +Default +AccessControlList0= +AccessControlList1= +AccessControlList10= +AccessControlList11= +AccessControlList12= +AccessControlList13= +AccessControlList14= +AccessControlList15= +AccessControlList2= +AccessControlList3= +AccessControlList4= +AccessControlList5= +AccessControlList6= +AccessControlList7= +AccessControlList8= +AccessControlList9= +AccessPolicy0=0 +AccessPolicy1=0 +AccessPolicy10=0 +AccessPolicy11=0 +AccessPolicy12=0 +AccessPolicy13=0 +AccessPolicy14=0 +AccessPolicy15=0 +AccessPolicy2=0 +AccessPolicy3=0 +AccessPolicy4=0 +AccessPolicy5=0 +AccessPolicy6=0 +AccessPolicy7=0 +AccessPolicy8=0 +AccessPolicy9=0 +AckPolicy=0;0;0;0 +APACM=0;0;0;0 +APAifsn=3;7;1;1 +ApCliAuthMode= +ApCliBssid= +ApCliDefaultKeyID= +ApCliEnable=0 +ApCliEncrypType= +ApCliKey1Str= +ApCliKey1Str1= +ApCliKey1Type= +ApCliKey2Str= +ApCliKey2Str1= +ApCliKey2Type= +ApCliKey3Str= +ApCliKey3Str1= +ApCliKey3Type= +ApCliKey4Str= +ApCliKey4Str1= +ApCliKey4Type= +ApCliSsid= +ApCliWirelessMode= +ApCliWPAPSK= +ApCliWPAPSK1= +ApCliMuOfdmaDlEnable=0 +ApCliMuOfdmaUlEnable=0 +ApCliMuMimoDlEnable=0 +ApCliMuMimoUlEnable=0 +APCwmax=6;10;4;3 +APCwmin=4;4;3;2 +APSDCapable=1 +APTxop=0;0;94;47 +AuthMode=OPEN +AutoChannelSelect=0 +AutoChannelSkipList=52;56;60;64; +AutoProvisionEn=0 +BandSteering=0 +BasicRate=15 +BeaconPeriod=100 +BFBACKOFFenable=0 +BgndScanSkipCh= +BGProtection=0 +BndStrgBssIdx= +BSSACM=0;0;0;0 +BSSAifsn=3;7;2;2 +BSSCwmax=10;10;4;3 +BSSCwmin=4;4;3;2 +BssidNum=1 +BSSTxop=0;0;94;47 +BW_Enable=0 +BW_Guarantee_Rate= +BW_Maximum_Rate= +BW_Priority= +BW_Root=0 +CalCacheApply=0 +CarrierDetect=0 +Channel=36 +ChannelGrp= +CountryCode=CN +CountryRegion=5 +CountryRegionABand=9 +CP_SUPPORT=2 +CSPeriod=6 +DBDC_MODE=1 +DebugFlags=0 +DefaultKeyID=1 +DfsCalibration=0 +DfsEnable=0 +DfsFalseAlarmPrevent=1 +DfsZeroWait=0 +DfsZeroWaitCacTime=255 +DfsDedicatedZeroWait=0 +DfsZeroWaitDefault=0 +DisableOLBC=0 +DtimPeriod=1 +E2pAccessMode=2 +EAPifname=br-lan +EDCCAEnable=1 +EncrypType=NONE +EthConvertMode=dongle +EtherTrafficBand=0 +Ethifname= +ETxBfEnCond=1 +FineAGC=0 +FixedTxMode= +ForceRoamSupport= +FragThreshold=2346 +FreqDelta=0 +FtSupport=0 +GreenAP=0 +G_BAND_256QAM=1 +HideSSID=0 +HT_AMSDU=1 +AMSDU_NUM=8 +HT_AutoBA=1 +HT_BADecline=0 +HT_BAWinSize=256 +HT_BSSCoexistence=1 +HT_BW=1 +HT_DisallowTKIP=1 +HT_EXTCHA=1 +HT_GI=1 +HT_HTC=1 +HT_LDPC=1 +HT_LinkAdapt=0 +HT_MCS=33 +HT_MpduDensity=4 +HT_OpMode=0 +HT_PROTECT=1 +HT_RDG=0 +HT_RxStream=2 +HT_STBC=1 +HT_TxStream=2 +IcapMode=0 +idle_timeout_interval=0 +IEEE80211H=1 +IEEE8021X=0 +IgmpSnEnable=1 +ITxBfEn=0 +Key1Str= +Key1Str1= +Key1Str10= +Key1Str11= +Key1Str12= +Key1Str13= +Key1Str14= +Key1Str15= +Key1Str16= +Key1Str2= +Key1Str3= +Key1Str4= +Key1Str5= +Key1Str6= +Key1Str7= +Key1Str8= +Key1Str9= +Key1Type=0 +Key2Str= +Key2Str1= +Key2Str10= +Key2Str11= +Key2Str12= +Key2Str13= +Key2Str14= +Key2Str15= +Key2Str16= +Key2Str2= +Key2Str3= +Key2Str4= +Key2Str5= +Key2Str6= +Key2Str7= +Key2Str8= +Key2Str9= +Key2Type=0 +Key3Str= +Key3Str1= +Key3Str10= +Key3Str11= +Key3Str12= +Key3Str13= +Key3Str14= +Key3Str15= +Key3Str16= +Key3Str2= +Key3Str3= +Key3Str4= +Key3Str5= +Key3Str6= +Key3Str7= +Key3Str8= +Key3Str9= +Key3Type=0 +Key4Str= +Key4Str1= +Key4Str10= +Key4Str11= +Key4Str12= +Key4Str13= +Key4Str14= +Key4Str15= +Key4Str16= +Key4Str2= +Key4Str3= +Key4Str4= +Key4Str5= +Key4Str6= +Key4Str7= +Key4Str8= +Key4Str9= +Key4Type=0 +LinkTestSupport=0 +MACRepeaterEn= +MACRepeaterOuiMode=2 +MeshAuthMode= +MeshAutoLink=0 +MeshDefaultkey=0 +MeshEncrypType= +MeshId= +MeshWEPKEY= +MeshWPAKEY= +MUTxRxEnable=1 +NoForwarding=0 +NoForwardingBTNBSSID=0 +own_ip_addr=192.168.1.1 +PcieAspm=0 +PERCENTAGEenable=0 +PhyRateLimit=0 +PMFMFPC=0 +PMFMFPR=0 +PMFSHA256=0 +PMKCachePeriod=10 +PowerUpCckOfdm=0:0:0:0:0:0:0 +PowerUpHT20=0:0:0:0:0:0:0 +PowerUpHT40=0:0:0:0:0:0:0 +PowerUpVHT160=0:0:0:0:0:0:0 +PowerUpVHT20=0:0:0:0:0:0:0 +PowerUpVHT40=0:0:0:0:0:0:0 +PowerUpVHT80=0:0:0:0:0:0:0 +PreAntSwitch= +PreAuth=0 +PreAuthifname=br-lan +RadioLinkSelection=0 +RadioOn=1 +RADIUS_Acct_Key= +RADIUS_Acct_Port=1813 +RADIUS_Acct_Server= +RADIUS_Key1= +RADIUS_Key10= +RADIUS_Key11= +RADIUS_Key12= +RADIUS_Key13= +RADIUS_Key14= +RADIUS_Key15= +RADIUS_Key16= +RADIUS_Key2= +RADIUS_Key3= +RADIUS_Key4= +RADIUS_Key5= +RADIUS_Key6= +RADIUS_Key7= +RADIUS_Key8= +RADIUS_Key9= +RADIUS_Port=1812 +RADIUS_Server=0 +RDRegion= +RED_Enable=1 +RekeyInterval=3600 +RekeyMethod=DISABLE +RRMEnable=1 +RTSThreshold=2347 +session_timeout_interval=0 +ShortSlot=1 +SkuTableIdx=0 +SKUenable=0 +SREnable=1 +SRMode=0 +SRDPDEnable=0 +SRSDEnable=1 +PPEnable=1 +SSID= +SSID1=MTK_CHEETAH_AP_5G +SSID10= +SSID11= +SSID12= +SSID13= +SSID14= +SSID15= +SSID16= +SSID2= +SSID3= +SSID4= +SSID5= +SSID6= +SSID7= +SSID8= +SSID9= +StationKeepAlive=0 +StreamMode=0 +StreamModeMac0= +StreamModeMac1= +StreamModeMac2= +StreamModeMac3= +TGnWifiTest=0 +ThermalRecal=0 +CCKTxStream=4 +TWTSupport=0 +TxBurst=1 +TxPower=100 +TxPreamble=1 +VHT_BW=2 +VHT_BW_SIGNAL=0 +VHT_LDPC=1 +VHT_Sec80_Channel=0 +VHT_SGI=1 +VHT_STBC=1 +Vht1024QamSupport=1 +VLANID=0 +VLANPriority=0 +VLANTag=0 +VOW_Airtime_Ctrl_En= +VOW_Airtime_Fairness_En=1 +VOW_BW_Ctrl=0 +VOW_Group_Backlog= +VOW_Group_DWRR_Max_Wait_Time= +VOW_Group_DWRR_Quantum= +VOW_Group_Max_Airtime_Bucket_Size= +VOW_Group_Max_Rate= +VOW_Group_Max_Rate_Bucket_Size= +VOW_Group_Max_Ratio= +VOW_Group_Max_Wait_Time= +VOW_Group_Min_Airtime_Bucket_Size= +VOW_Group_Min_Rate= +VOW_Group_Min_Rate_Bucket_Size= +VOW_Group_Min_Ratio= +VOW_Rate_Ctrl_En= +VOW_Refill_Period= +VOW_RX_En=1 +VOW_Sta_BE_DWRR_Quantum= +VOW_Sta_BK_DWRR_Quantum= +VOW_Sta_DWRR_Max_Wait_Time= +VOW_Sta_VI_DWRR_Quantum= +VOW_Sta_VO_DWRR_Quantum= +VOW_WATF_Enable= +VOW_WATF_MAC_LV0= +VOW_WATF_MAC_LV1= +VOW_WATF_MAC_LV2= +VOW_WATF_MAC_LV3= +VOW_WATF_Q_LV0= +VOW_WATF_Q_LV1= +VOW_WATF_Q_LV2= +VOW_WATF_Q_LV3= +VOW_WMM_Search_Rule_Band0= +VOW_WMM_Search_Rule_Band1= +WapiAsCertPath= +WapiAsIpAddr= +WapiAsPort= +Wapiifname= +WapiPsk1= +WapiPsk10= +WapiPsk11= +WapiPsk12= +WapiPsk13= +WapiPsk14= +WapiPsk15= +WapiPsk16= +WapiPsk2= +WapiPsk3= +WapiPsk4= +WapiPsk5= +WapiPsk6= +WapiPsk7= +WapiPsk8= +WapiPsk9= +WapiPskType= +WapiUserCertPath= +WCNTest=0 +Wds0Key= +Wds1Key= +Wds2Key= +Wds3Key= +WdsEnable=0 +WdsEncrypType=NONE +WdsList= +WdsPhyMode=0 +WHNAT=1 +WiFiTest=0 +WirelessMode=17 +WmmCapable=1 +WPAPSK= +WPAPSK1=12345678 +WPAPSK10= +WPAPSK11= +WPAPSK12= +WPAPSK13= +WPAPSK14= +WPAPSK15= +WPAPSK16= +WPAPSK2= +WPAPSK3= +WPAPSK4= +WPAPSK5= +WPAPSK6= +WPAPSK7= +WPAPSK8= +WPAPSK9= +WscConfMode=0 +WscConfStatus=2 +TxCmdMode=1 +MuOfdmaDlEnable=1 +MuOfdmaUlEnable=1 +MuMimoDlEnable=1 +MuMimoUlEnable=1 +MapMode=0 +IsICAPFW=0 +BSSColorValue=255 +MboSupport=1 +QoSR1Enable=1 +DscpPriMapEnable=1 +ScsEnable=0 +QoSMgmtCapa=0 +BcnProt=0 +ApCliBcnProt=0 diff --git a/target/linux/mediatek/modules.mk b/target/linux/mediatek/modules.mk index 467934256c..9a490e77e8 100644 --- a/target/linux/mediatek/modules.mk +++ b/target/linux/mediatek/modules.mk @@ -38,3 +38,21 @@ define KernelPackage/sdhci-mtk endef $(eval $(call KernelPackage,sdhci-mtk)) + +define KernelPackage/mediatek_hnat + SUBMENU:=Network Devices + TITLE:=Mediatek HNAT module + DEPENDS:=@TARGET_mediatek +kmod-nf-conntrack + KCONFIG:= \ + CONFIG_BRIDGE_NETFILTER=y \ + CONFIG_NETFILTER_FAMILY_BRIDGE=y \ + CONFIG_NET_MEDIATEK_HNAT + FILES:= \ + $(LINUX_DIR)/drivers/net/ethernet/mediatek/mtk_hnat/mtkhnat.ko +endef + +define KernelPackage/mediatek_hnat/description + Kernel modules for MediaTek HW NAT offloading +endef + +$(eval $(call KernelPackage,mediatek_hnat))