diff --git a/aic.rules b/aic.rules index d6118e3..eefb478 100644 --- a/aic.rules +++ b/aic.rules @@ -1,2 +1,3 @@ KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5721", SYMLINK+="aicudisk", RUN+="/usr/bin/eject /dev/%k" KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5723", SYMLINK+="tendaudisk", RUN+="/usr/bin/eject /dev/%k" +KERNEL=="sd*", ATTRS{idVendor}=="a69c", ATTRS{idProduct}=="5725", SYMLINK+="tendaudiskv2", RUN+="/usr/bin/eject /dev/%k" diff --git a/drivers/aic8800/Makefile b/drivers/aic8800/Makefile index 9209115..71b2fad 100644 --- a/drivers/aic8800/Makefile +++ b/drivers/aic8800/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/ ########## config option ########## export CONFIG_USE_FW_REQUEST = n -export CONFIG_PREALLOC_RX_SKB = n +export CONFIG_PREALLOC_RX_SKB = y export CONFIG_PREALLOC_TXQ = y ################################### @@ -50,7 +50,7 @@ KDIR = /lib/modules/$(shell uname -r)/build PWD = $(shell pwd) KVER = $(shell uname -r) MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800 -SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/) +SUBARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/armv.l/arm/ -e s/aarch64/arm64/ -e s/loongarch64/loongarch/ -e s/loong64/loongarch/) ARCH ?= $(SUBARCH) CROSS_COMPILE ?= endif diff --git a/drivers/aic8800/aic8800_fdrv/.gitignore b/drivers/aic8800/aic8800_fdrv/.gitignore new file mode 100644 index 0000000..c3c2d15 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/.gitignore @@ -0,0 +1,10 @@ +*.o +*.ko +*.order +*.symvers +*.o.d +*.o.cmd +*.ko.cmd +*.mod +*.mod.c +*.mod.cmd diff --git a/drivers/aic8800/aic8800_fdrv/Makefile b/drivers/aic8800/aic8800_fdrv/Makefile index 935814f..edce2c6 100644 --- a/drivers/aic8800/aic8800_fdrv/Makefile +++ b/drivers/aic8800/aic8800_fdrv/Makefile @@ -82,6 +82,7 @@ CONFIG_BR_SUPPORT = n CONFIG_USB_MSG_OUT_EP = y CONFIG_USB_MSG_IN_EP = y CONFIG_USB_RX_REASSEMBLE = n +CONFIG_WOWLAN = n #DCDW support tx aggr, D80 support both CONFIG_USB_RX_AGGR = n @@ -109,18 +110,32 @@ CONFIG_PREALLOC_TXQ ?= y CONFIG_USE_WIRELESS_EXT = y CONFIG_DPD = y CONFIG_FORCE_DPD_CALIB = y +CONFIG_LOFT_CALIB = n CONFIG_GKI = n CONFIG_SCHED_SCAN = n CONFIG_TEMP_COMP = n CONFIG_POWER_LIMIT = n +CONFIG_EXT_FEM_8800DCDW = n # CONFIG_MCC = n for sta and p2p concurrent in same channel. CONFIG_MCC = y CONFIG_LOAD_BT_PATCH_IN_FDRV = n +CONFIG_DYNAMIC_PWR = n +CONFIG_DYNAMIC_PERPWR = n +CONFIG_BAND_STEERING = n + +#support D80X2 can write rf result to file +CONFIG_WRITE_FILE_D80X2 = n ifneq ($(CONFIG_WIRELESS_EXT), y) CONFIG_USE_WIRELESS_EXT = n endif +ifeq ($(CONFIG_EXT_FEM_8800DCDW), y) +CONFIG_DPD = n +CONFIG_FORCE_DPD_CALIB = n +CONFIG_LOFT_CALIB = y +endif + # Support of MU-MIMO transmission (need FW support) ifeq ($(CONFIG_RWNX_BFMER), y) CONFIG_RWNX_MUMIMO_TX ?= n @@ -148,6 +163,7 @@ BR_NAME = br0 obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o $(MODULE_NAME)-y := \ + rwnx_wakelock.o \ rwnx_msg_tx.o \ rwnx_msg_rx.o \ rwnx_utils.o \ @@ -172,8 +188,11 @@ $(MODULE_NAME)-y := \ aic_vendor.o \ aic_priv_cmd.o \ aicwf_compat_8800dc.o \ - aicwf_compat_8800d80.o + aicwf_compat_8800d80.o \ + aicwf_compat_8800d80x2.o +$(MODULE_NAME)-$(CONFIG_BAND_STEERING) += aicwf_manager.o \ + aicwf_steering.o $(MODULE_NAME)-$(CONFIG_BR_SUPPORT) += aic_br_ext.o $(MODULE_NAME)-$(CONFIG_RWNX_RADAR) += rwnx_radar.o $(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_debugfs.o @@ -241,6 +260,10 @@ ccflags-$(CONFIG_RWNX_MUMIMO_TX) += -DCONFIG_RWNX_MUMIMO_TX ccflags-$(CONFIG_RFTEST) += -DCONFIG_RFTEST ccflags-$(CONFIG_MCC) += -DCONFIG_MCC ccflags-$(CONFIG_LOAD_BT_PATCH_IN_FDRV) += -DCONFIG_LOAD_BT_PATCH_IN_FDRV +ccflags-$(CONFIG_DYNAMIC_PWR) += -DCONFIG_DYNAMIC_PWR +ccflags-$(CONFIG_DYNAMIC_PERPWR) += -DCONFIG_DYNAMIC_PERPWR +ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING +ccflags-$(CONFIG_WRITE_FILE_D80X2) += -DRF_WRITE_FILE ifeq ($(CONFIG_SDIO_SUPPORT), y) ccflags-y += -DAICWF_SDIO_SUPPORT @@ -274,7 +297,7 @@ endif ccflags-$(CONFIG_RX_REORDER) += -DAICWF_RX_REORDER ccflags-$(CONFIG_ARP_OFFLOAD) += -DAICWF_ARP_OFFLOAD ccflags-$(CONFIG_USE_5G) += -DUSE_5G -ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DRADAR_OR_IR_DETECT +ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT ccflags-$(CONFIG_DOWNLOAD_FW) += -DCONFIG_DOWNLOAD_FW ccflags-$(CONFIG_USB_BT) += -DCONFIG_USB_BT ccflags-$(CONFIG_ALIGN_8BYTES) += -DCONFIG_ALIGN_8BYTES @@ -310,11 +333,14 @@ ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ ccflags-$(CONFIG_USE_WIRELESS_EXT) += -DCONFIG_USE_WIRELESS_EXT ccflags-$(CONFIG_DPD) += -DCONFIG_DPD ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD +ccflags-$(CONFIG_LOFT_CALIB) += -DCONFIG_LOFT_CALIB ccflags-$(CONFIG_GKI) += -DCONFIG_GKI ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP ccflags-$(CONFIG_POWER_LIMIT) += -DCONFIG_POWER_LIMIT +ccflags-$(CONFIG_EXT_FEM_8800DCDW) += -DCONFIG_EXT_FEM_8800DCDW +ccflags-$(CONFIG_WOWLAN) += -DCONFIG_WOWLAN MAKEFLAGS +=-j$(shell nproc) # Platform support list diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c index f3d0a78..a09fe79 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.c @@ -11,16 +11,31 @@ */ #include +#include +#include #include #include "rwnx_defs.h" #include "rwnx_msg_tx.h" #include "rwnx_debugfs.h" #include "rwnx_main.h" #include "aic_priv_cmd.h" +#include "aicwf_compat_8800dc.h" +#include "aicwf_compat_8800d80.h" +#include "aicwf_compat_8800d80x2.h" +#include "rwnx_mod_params.h" +#include "rwnx_platform.h" +#define FLASH_BIN_ADDR_8800M80 0x8000000 + extern void set_testmode(int); +extern int get_flash_bin_size(void); +extern u32 get_flash_bin_crc(void); extern int testmode; + +extern int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, + struct station_info *sinfo, u8 *phymode, u32 *tx_phyrate, u32 *rx_phyrate); + static void print_help(const char *cmd); struct dbg_rftest_cmd_cfm cfm = {{0,}}; @@ -69,7 +84,13 @@ enum { RDWR_EFUSE_HE_OFF, SET_USB_OFF, SET_PLL_TEST, - + SET_ANT_MODE, + GET_NOISE, + RDWR_BT_EFUSE_PWROFST, + EXEC_FLASH_OPER, + RDWR_PWRADD2X, + RDWR_EFUSE_PWRADD2X, + CHECK_FLASH=0x108, }; typedef struct { @@ -119,6 +140,14 @@ typedef struct u32_l usrdata[3]; // 3 words totally } cmd_ef_usrdata_t; +typedef struct +{ + u32_l flash_read_addr; + u32_l flash_read_size; +} cmd_check_flash_t; + +extern char country_code[]; + #define CMD_MAXARGS 30 #if 0//#include @@ -247,6 +276,22 @@ int str_starts(const char *str, const char *start) static int aic_priv_cmd_set_tx (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) { cmd_rf_settx_t settx_param; + u8_l set_p = 0; + u8_l lvl_band, lvl_mod, lvl_idx, lvl_pwr = 0; + u8_l buf[10]; +#ifdef CONFIG_POWER_LIMIT + int8_t max_pwr; + uint8_t r_idx; + txpwr_loss_conf_t txpwr_loss_tmp; + txpwr_loss_conf_t *txpwr_loss; + txpwr_loss = &txpwr_loss_tmp; +#endif +#ifdef AICWF_SDIO_SUPPORT + struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev; +#endif +#ifdef AICWF_USB_SUPPORT + struct aic_usb_dev *dev = g_rwnx_plat->usbdev; +#endif if (argc < 6) return -EINVAL; @@ -261,13 +306,69 @@ static int aic_priv_cmd_set_tx (struct rwnx_hw *rwnx_hw, int argc, char *argv[], } else { settx_param.tx_intv_us = 10000; // set default val 10ms } + if (argc > 7) { + if (dev->chipid == PRODUCT_ID_AIC8801){ + AICWFDBG(LOGERROR, "unsupported cmd\n"); + return -EINVAL; + } + lvl_pwr = command_strtoul(argv[7], NULL, 10); + AICWFDBG(LOGINFO, "lvl_pwr: %d\n", lvl_pwr); + + if (settx_param.chan >= 36) + lvl_band = 2; + else + lvl_band = 1; + if (settx_param.mode == 0) + lvl_mod = 0; + else if (settx_param.mode == 2 || settx_param.mode == 4) + lvl_mod = 1; + else if (settx_param.mode == 5) + lvl_mod = 2; + if (settx_param.mode >= 4) + lvl_idx = settx_param.rate & 0xF; + else if (settx_param.mode >= 2) + lvl_idx = settx_param.rate & 0x7; + else + lvl_idx = settx_param.rate; + + buf[0] = lvl_band; + buf[1] = lvl_mod; + buf[2] = lvl_idx; + buf[3] = lvl_pwr; + + set_p = 1; + } settx_param.max_pwr = POWER_LEVEL_INVALID_VAL; AICWFDBG(LOGINFO, "txparam:%d,%d,%d,%d,%d,%d\n", settx_param.chan, settx_param.bw, settx_param.mode, settx_param.rate, settx_param.length, settx_param.tx_intv_us); #ifdef CONFIG_POWER_LIMIT - settx_param.max_pwr = get_powerlimit_by_chnum(settx_param.chan); - AICWFDBG(LOGINFO, "max_pwr:%d\n", settx_param.max_pwr); + r_idx = get_ccode_region(country_code); + txpwr_loss = &txpwr_loss_tmp; + get_userconfig_txpwr_loss(txpwr_loss); + if (txpwr_loss->loss_enable_2g4 == 1) + AICWFDBG(LOGINFO, "%s:loss_value_2g4: %d\r\n", __func__, + txpwr_loss->loss_value_2g4); + if (txpwr_loss->loss_enable_5g == 1) + AICWFDBG(LOGINFO, "%s:loss_value_5g: %d\r\n", __func__, + txpwr_loss->loss_value_5g); + max_pwr = get_powerlimit_by_chnum(settx_param.chan, r_idx, settx_param.bw); + if (settx_param.chan >= 36) { + if (txpwr_loss->loss_enable_5g == 1) + max_pwr -= txpwr_loss->loss_value_5g; + } else { + if (txpwr_loss->loss_enable_2g4 == 1) + max_pwr -= txpwr_loss->loss_value_2g4; + } + if (!set_p || (lvl_pwr == 255)) { + settx_param.max_pwr = max_pwr; + AICWFDBG(LOGINFO, "max_pwr:%d\n", settx_param.max_pwr); + } else + AICWFDBG(LOGINFO, "the specified power is input without power limit\n"); #endif + + if (set_p && (lvl_pwr != 255)) + rwnx_send_rftest_req(rwnx_hw, RDWR_PWRLVL, 4, buf, &cfm); + rwnx_send_rftest_req(rwnx_hw, SET_TX, sizeof(cmd_rf_settx_t), (u8_l *)&settx_param, NULL); return 0; } @@ -389,8 +490,8 @@ static int aic_priv_cmd_set_xtal_cap_fine (struct rwnx_hw *rwnx_hw, int argc, ch return -EINVAL; xtal_cap_fine = command_strtoul(argv[1], NULL, 10); - AICWFDBG(LOGINFO, "xtal_cap =%x\r\n", xtal_cap_fine); - rwnx_send_rftest_req(rwnx_hw, SET_XTAL_CAP, sizeof(xtal_cap_fine), (u8_l *)&xtal_cap_fine, &cfm); + AICWFDBG(LOGINFO, "xtal_cap_fine =%x\r\n", xtal_cap_fine); + rwnx_send_rftest_req(rwnx_hw, SET_XTAL_CAP_FINE, sizeof(xtal_cap_fine), (u8_l *)&xtal_cap_fine, &cfm); memcpy(command, &cfm.rftest_result[0], 4); return 4; } @@ -439,7 +540,7 @@ static int aic_priv_cmd_set_freq_cal_fine (struct rwnx_hw *rwnx_hw, int argc, ch static int aic_priv_cmd_get_freq_cal (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) { - u8_l val; + u32_l val; #ifdef AICWF_SDIO_SUPPORT struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev; #endif @@ -450,7 +551,7 @@ static int aic_priv_cmd_get_freq_cal (struct rwnx_hw *rwnx_hw, int argc, char *a rwnx_send_rftest_req(rwnx_hw, GET_FREQ_CAL, 0, NULL, &cfm); memcpy(command, &cfm.rftest_result[0], 4); val = cfm.rftest_result[0]; - if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { + if (dev->chipid != PRODUCT_ID_AIC8801) { AICWFDBG(LOGINFO, "cap=0x%x (remain:%x), cap_fine=%x (remain:%x)\n", val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff); } else { @@ -696,7 +797,7 @@ static int aic_priv_cmd_rdwr_pwrlvl (struct rwnx_hw *rwnx_hw, int argc, char *ar AICWFDBG(LOGERROR, "wrong func: %x\n", func); return -EINVAL; } - if(dev->chipid == PRODUCT_ID_AIC8800D81){ + if((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)){ memcpy(command, &cfm.rftest_result[0], 6 * 12); return (6 * 12); } else { @@ -721,15 +822,15 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a } if (func == 0) { // read cur rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, 0, NULL, &cfm); - } else if (func <= 2) { // write 2.4g/5g pwr ofst - if ((argc > 4) && (dev->chipid == PRODUCT_ID_AIC8800D81)) { + } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 + if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFST, sizeof(buf), buf, &cfm); - } else if ((argc > 3) && (dev->chipid != PRODUCT_ID_AIC8800D81)) { + } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; @@ -746,6 +847,8 @@ static int aic_priv_cmd_rdwr_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *a res_len = 3; } else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) res_len = 3 * 3 + 3 * 6; + } else if ((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // ant0/1 + res_len = ( 3 * 3 + 3 * 6 ) * 2; } else { res_len = 3 + 4; } @@ -826,15 +929,15 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c } if (func == 0) { // read cur rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, 0, NULL, &cfm); - } else if (func <= 2) { // write 2.4g/5g pwr ofst - if ((argc > 4) && (dev->chipid == PRODUCT_ID_AIC8800D81)) { + } else if (func <= 4) { // write 2.4g/5g pwr ofst and ant0/1 + if ((argc > 4) && ((dev->chipid == PRODUCT_ID_AIC8800D81) || (dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2))) { u8_l type = (u8_l)command_strtoul(argv[2], NULL, 16); u8_l chgrp = (u8_l)command_strtoul(argv[3], NULL, 16); s8_l pwrofst = (u8_l)command_strtoul(argv[4], NULL, 10); u8_l buf[4] = {func, type, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set efuse pwrofst_%s:[%x][%x]=%d\r\n", (func == 1) ? "2.4g" : "5g", type, chgrp, pwrofst); rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFST, sizeof(buf), buf, &cfm); - } else if ((argc > 3) && (dev->chipid != PRODUCT_ID_AIC8800D81)) { + } else if ((argc > 3) && ((dev->chipid == PRODUCT_ID_AIC8801) || (dev->chipid == PRODUCT_ID_AIC8800DW) || (dev->chipid == PRODUCT_ID_AIC8800DC))) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; @@ -851,7 +954,9 @@ static int aic_priv_cmd_rdwr_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, c if ((dev->chipid == PRODUCT_ID_AIC8800DC) || (dev->chipid == PRODUCT_ID_AIC8800DW)) { // 6 = 3 (2.4g) * 2 res_len = 3 * 2; } else if (dev->chipid == PRODUCT_ID_AIC8800D81) { // 3 * 2 (2.4g) + 3 * 6 (5g) - res_len = 3 * 3 + 3 * 6; + res_len = (3 * 3 + 3 * 6) * 2; + } else if((dev->chipid == PRODUCT_ID_AIC8800D81X2) || (dev->chipid == PRODUCT_ID_AIC8800D89X2)) { // 3 * 2 (2.4g) *2 + 3 * 6 (5g) *2 + res_len = (3 * 3 + 3 * 6) * 2 * 2; } else { // 7 = 3(2.4g) + 4(5g) res_len = 3 + 4; } @@ -867,14 +972,14 @@ static int aic_priv_cmd_rdwr_efuse_pwrofstfine (struct rwnx_hw *rwnx_hw, int arg func = (u8_l)command_strtoul(argv[1], NULL, 16); } if (func == 0) { // read cur - rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, 0, NULL, &cfm); + rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, 0, NULL, &cfm); } else if (func <= 2) { // write 2.4g/5g pwr ofst if (argc > 3) { u8_l chgrp = (u8_l)command_strtoul(argv[2], NULL, 16); s8_l pwrofst = (u8_l)command_strtoul(argv[3], NULL, 10); u8_l buf[3] = {func, chgrp, (u8_l)pwrofst}; AICWFDBG(LOGINFO, "set pwrofstfine:[%x][%x]=%d\r\n", func, chgrp, pwrofst); - rwnx_send_rftest_req(rwnx_hw, RDWR_PWROFSTFINE, sizeof(buf), buf, &cfm); + rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWROFSTFINE, sizeof(buf), buf, &cfm); } else { AICWFDBG(LOGERROR, "wrong args\n"); return -EINVAL; @@ -999,7 +1104,7 @@ static int aic_priv_cmd_rdwr_efuse_he_off (struct rwnx_hw *rwnx_hw, int argc, ch func = command_strtoul(argv[1], NULL, 10); AICWFDBG(LOGINFO, "set he off: %d\n", func); - if(func == 1) { + if(func == 1 || func == 0) { rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_HE_OFF, sizeof(func), (u8_l *)&func, &cfm); AICWFDBG(LOGINFO, "he_off cfm: %d\n", cfm.rftest_result[0]); memcpy(command, &cfm.rftest_result[0], 4); @@ -1168,6 +1273,206 @@ static int aic_priv_cmd_set_pll_test (struct rwnx_hw *rwnx_hw, int argc, char *a return 0; } +static int aic_priv_cmd_set_ant_mode (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + u8_l func = 0; + if (argc > 1) { + func = command_strtoul(argv[1], NULL, 10); + AICWFDBG(LOGINFO, "ant %d\r\n", func); + rwnx_send_rftest_req(rwnx_hw, SET_ANT_MODE, sizeof(func), (u8_l *)&func, NULL); + } else { + return -EINVAL; + } + return 0; +} + +static int aic_priv_cmd_rdwr_bt_efuse_pwrofst (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + u8_l func = 0; + if (argc == 1) { + func = 0; + } else if (argc == 2) { + func = 1; + } + if (func == 0) { // read cur + rwnx_send_rftest_req(rwnx_hw, RDWR_BT_EFUSE_PWROFST, 0, NULL, &cfm); + } else if (func == 1) { // write bt tx pwrofst + int8_t bt_txpwrofst = command_strtoul(argv[1], NULL, 10); + AICWFDBG(LOGINFO, "set bt efuse pwrofst %d\r\n",bt_txpwrofst); + if (bt_txpwrofst < -7 || bt_txpwrofst > 7) { + AICWFDBG(LOGERROR, "wrong params %d, pwrofst limit -7 ~ 7\n", bt_txpwrofst); + return -EINVAL; + } else { + rwnx_send_rftest_req(rwnx_hw, RDWR_BT_EFUSE_PWROFST, sizeof(bt_txpwrofst), &bt_txpwrofst, &cfm); + } + } else { + AICWFDBG(LOGERROR, "wrong func: %x\n", func); + return -EINVAL; + } + memcpy(command, &cfm.rftest_result[0], 2); + return 2; +} + +static int aic_priv_cmd_exec_flash_oper(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + u8_l func = 0; + if (argc > 1) { + func = (s8_l)command_strtoul(argv[1], NULL, 10); + AICWFDBG(LOGINFO, "exec_flash_oper: %d\n", func); + rwnx_send_rftest_req(rwnx_hw, EXEC_FLASH_OPER, sizeof(func), &func, &cfm); + AICWFDBG(LOGINFO, "flash oper %u %u \n",cfm.rftest_result[0],cfm.rftest_result[1]); + } else { + AICWFDBG(LOGERROR, "wrong args\n"); + return -EINVAL; + } + + return 0; +} + +static int aic_priv_cmd_country_set(struct rwnx_hw *rwnx_hw, int argc, + char *argv[], char *command) +{ + int ret = 0; + struct ieee80211_regdomain *regdomain; + + if (argc < 2) { + AICWFDBG(LOGINFO, "%s param err\n", __func__); + return -1; + } + + AICWFDBG(LOGINFO, "cmd country_set: %s\n", argv[1]); + + regdomain = getRegdomainFromRwnxDB(rwnx_hw->wiphy, argv[1]); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + ret = regulatory_set_wiphy_regd( + rwnx_hw->wiphy, regdomain); +#else + ret = wiphy_apply_custom_regulatory( + rwnx_hw->wiphy, regdomain); +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */ + +#ifdef CONFIG_RADAR_OR_IR_DETECT + rwnx_radar_set_domain(&rwnx_hw->radar, regdomain->dfs_region); +#endif + +#ifdef CONFIG_POWER_LIMIT + if (!testmode){ + rwnx_send_me_chan_config_req(rwnx_hw, argv[1]); + } +#endif + + return ret; +} + +static int aic_priv_cmd_get_noise(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + rwnx_send_rftest_req(rwnx_hw, GET_NOISE, 0, NULL, &cfm); + + AICWFDBG(LOGINFO, "noise: %d,%d\n", (char)cfm.rftest_result[0], (char)cfm.rftest_result[1]); + command[0] = (char)cfm.rftest_result[0]; + command[1] = (char)cfm.rftest_result[1]; + + return 2; +} + +static int aic_priv_cmd_rdwr_pwradd2x (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + u8_l func = 0; + int8_t pwradd2x_in = 0; +#ifdef AICWF_SDIO_SUPPORT + struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev; +#endif +#ifdef AICWF_USB_SUPPORT + struct aic_usb_dev *dev = g_rwnx_plat->usbdev; +#endif + + if (dev->chipid != PRODUCT_ID_AIC8800D81) { + AICWFDBG(LOGERROR, "RDWR_PWRADD2X, only D40/80 support\n"); + return -EINVAL; + } + + if (argc > 1) { + func = (u8_l)command_strtoul(argv[1], NULL, 10); + } + if ((func > 0) && (argc > 2)) { + pwradd2x_in = (int8_t)command_strtoul(argv[2], NULL, 10); + } + if (func == 0) { // read cur + rwnx_send_rftest_req(rwnx_hw, RDWR_PWRADD2X, 0, NULL, &cfm); + } else if ((func == 1) || (func == 2)) { // write pwradd2x + AICWFDBG(LOGINFO, "set pwradd2x_%s %d\r\n", (func == 1) ? "2g4" : "5g", pwradd2x_in); + if (pwradd2x_in < -15 || pwradd2x_in > 15) { + AICWFDBG(LOGERROR, "wrong params %d, pwradd2x: -15 ~ 15\n", pwradd2x_in); + return -EINVAL; + } else { + u8_l buf[2] = {func, (u8_l)pwradd2x_in}; + rwnx_send_rftest_req(rwnx_hw, RDWR_PWRADD2X, sizeof(buf), buf, &cfm); + } + } else { + AICWFDBG(LOGERROR, "wrong func: %x\n", func); + return -EINVAL; + } + memcpy(command, &cfm.rftest_result[0], 2); + return 2; +} + +static int aic_priv_cmd_rdwr_efuse_pwradd2x (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + u8_l func = 0; + int8_t pwradd2x_in = 0; +#ifdef AICWF_SDIO_SUPPORT + struct aic_sdio_dev *dev = g_rwnx_plat->sdiodev; +#endif +#ifdef AICWF_USB_SUPPORT + struct aic_usb_dev *dev = g_rwnx_plat->usbdev; +#endif + + if (dev->chipid != PRODUCT_ID_AIC8800D81) { + AICWFDBG(LOGERROR, "RDWR_EFUSE_PWRADD2X, only D40/80 support\n"); + return -EINVAL; + } + + if (argc > 1) { + func = (u8_l)command_strtoul(argv[1], NULL, 10); + } + if ((func > 0) && (argc > 2)) { + pwradd2x_in = (int8_t)command_strtoul(argv[2], NULL, 10); + } + if (func == 0) { // read cur + rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWRADD2X, 0, NULL, &cfm); + } else if ((func == 1) || (func == 2)) { // write pwradd2x + AICWFDBG(LOGINFO, "set efuse pwradd2x_%s %d\r\n", (func == 1) ? "2g4" : "5g", pwradd2x_in); + if (pwradd2x_in < -15 || pwradd2x_in > 15) { + AICWFDBG(LOGERROR, "wrong params %d, pwradd2x: -15 ~ 15\n", pwradd2x_in); + return -EINVAL; + } else { + u8_l buf[2] = {func, (u8_l)pwradd2x_in}; + rwnx_send_rftest_req(rwnx_hw, RDWR_EFUSE_PWRADD2X, sizeof(buf), buf, &cfm); + } + } else { + AICWFDBG(LOGERROR, "wrong func: %x\n", func); + return -EINVAL; + } + memcpy(command, &cfm.rftest_result[0], 3); + return 3; +} + + + +static int aic_priv_cmd_check_flash(struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) +{ + cmd_check_flash_t cmd_check_flash; + cmd_check_flash.flash_read_addr = FLASH_BIN_ADDR_8800M80; + cmd_check_flash.flash_read_size = get_flash_bin_size(); + rwnx_send_rftest_req(rwnx_hw, CHECK_FLASH, sizeof(cmd_check_flash), (u8_l *)&cmd_check_flash, &cfm); + cfm.rftest_result[1] = get_flash_bin_crc(); + + AICWFDBG(LOGINFO, "flash_crc: %x %x\n", cfm.rftest_result[0], cfm.rftest_result[1]); + memcpy(command, &cfm.rftest_result[0], 8); + + return 8; +} static int aic_priv_cmd_help (struct rwnx_hw *rwnx_hw, int argc, char *argv[], char *command) { @@ -1192,7 +1497,7 @@ static const struct aic_priv_cmd aic_priv_commands[] = { "= display rx fcsok/total pkt num" }, { "set_rxstop", aic_priv_cmd_set_rxstop, "= stop rx " }, - { "set_tx_tone", aic_priv_cmd_set_tx_tone, + { "set_txtone", aic_priv_cmd_set_tx_tone, " val = 0/off" }, { "set_rx_meter", aic_priv_cmd_set_rx_meter, "= set rx meter " }, @@ -1270,6 +1575,20 @@ static const struct aic_priv_cmd aic_priv_commands[] = { "= off usb configure before usb disconnect" }, { "set_pll_test", aic_priv_cmd_set_pll_test, " = use pll test to measure saturation power" }, + { "set_ant", aic_priv_cmd_set_ant_mode, + " = 0/ant0, 1/ant1, 2/both" }, + { "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst, + " = read/write bt tx power offset into efuse" }, + { "exec_flash_oper",aic_priv_cmd_exec_flash_oper, + " = 0 check, 1 rec, 2 prot 3 rd_wcr0 4 er_wcr0 "}, + {"country_set", aic_priv_cmd_country_set, ""}, + {"get_noise", aic_priv_cmd_get_noise, "get noise"}, + {"rdwr_pwradd2x", aic_priv_cmd_rdwr_pwradd2x, + "a value is added for both 2.4G and 5G to achieve overall power adjustment of the band"}, + {"rdwr_efuse_pwradd2x", aic_priv_cmd_rdwr_efuse_pwradd2x, + "a value is added for both 2.4G and 5G to achieve overall power adjustment of the band, write to efuse"}, + {"check_flash", aic_priv_cmd_check_flash, + "check bin crc in flash" }, //Reserve for new aic_priv_cmd. { "help", aic_priv_cmd_help, @@ -1304,6 +1623,13 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) RWNX_DBG(RWNX_FN_ENTRY_STR); +#if 0 + if(!testmode) { + AICWFDBG(LOGERROR, "not in testmode\n"); + return -1; + } +#endif + argc = parse_line(command, argv); if (argc == 0) { return -1; @@ -1312,7 +1638,8 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) count = 0; cmd = aic_priv_commands; while (cmd->cmd) { - if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0) + if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0 && + strncasecmp(cmd->cmd, argv[0], strlen(cmd->cmd)) == 0) { match = cmd; if (strcasecmp(cmd->cmd, argv[0]) == 0) { @@ -1350,11 +1677,13 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len) } #define RWNX_COUNTRY_CODE_LEN 2 -#define CMD_SET_COUNTRY "COUNTRY" -#define CMD_SET_VENDOR_EX_IE "SET_VENDOR_EX_IE" -#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" -#define CMD_SET_TESTMODE "SET_TESTMODE" -#define CMD_SET_BLE_WAKE "SET_BLE_WAKE" +#define CMD_SET_COUNTRY "COUNTRY" +#define CMD_SET_VENDOR_EX_IE "SET_VENDOR_EX_IE" +#define CMD_SET_AP_WPS_P2P_IE "SET_AP_WPS_P2P_IE" +#define CMD_SET_TESTMODE "SET_TESTMODE" +#define CMD_SET_BLE_WAKE "SET_BLE_WAKE" +#define CMD_SET_MON_FREQ "SET_MON_FREQ" +#define CMD_GET_CS_INFO "GET_CS_INFO" struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, char *alpha2); @@ -1387,6 +1716,143 @@ void set_vendor_extension_ie(char *command){ } #endif//CONFIG_SET_VENDOR_EXTENSION_IE +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_chan_def *chandef); +#else +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef); +#endif +int rwnx_atoi2(char *value, int c_len); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +void set_mon_chan(struct rwnx_vif *vif, struct net_device *dev, char *parameter) +#else +void set_mon_chan(struct rwnx_vif *vif, char *parameter) +#endif +{ + struct cfg80211_chan_def *chandef = NULL; + int freq = 0; + + + chandef = (struct cfg80211_chan_def *)vmalloc(sizeof(struct cfg80211_chan_def)); + memset(chandef, 0, sizeof(struct cfg80211_chan_def)); + chandef->chan = (struct ieee80211_channel *)vmalloc(sizeof(struct ieee80211_channel)); + memset(chandef->chan, 0, sizeof(struct ieee80211_channel)); + + freq = rwnx_atoi2(parameter, 4); + + if(freq <= 2484){ + chandef->chan->band = NL80211_BAND_2GHZ; + }else{ + chandef->chan->band = NL80211_BAND_5GHZ; + } + chandef->chan->center_freq = freq; + chandef->width = NL80211_CHAN_WIDTH_20; + chandef->center_freq1 = chandef->chan->center_freq; + chandef->center_freq2 = 0; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, dev, chandef); +#else + rwnx_cfg80211_set_monitor_channel_(vif->rwnx_hw->wiphy, chandef); +#endif + + vfree(chandef->chan); + vfree(chandef); + +} + +int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val) +{ + struct rwnx_sta *sta = NULL; + u8 phymode = 0; + u32 tx_phyrate = 0, rx_phyrate = 0; + struct aicwf_cs_info cs_info; + struct station_info sinfo; + struct rwnx_sta_stats *stats; + struct rx_vector_2 *rx_vect2; + struct rwnx_chanctx *ctxt; + + if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_MONITOR) + return -EINVAL; + else if ((RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_STATION) || + (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_CLIENT)) { + AICWFDBG(LOGINFO, "%s: sta mode\n", __func__); + if (vif->sta.ap) + sta = vif->sta.ap; + } else { + struct rwnx_sta *sta_iter; + AICWFDBG(LOGINFO, "%s: ap mode, mac=%pM\n", __func__, mac_addr); + spin_lock_bh(&vif->rwnx_hw->cb_lock); + list_for_each_entry(sta_iter, &vif->ap.sta_list, list) { + if (sta_iter->valid && ether_addr_equal(sta_iter->mac_addr, mac_addr)) { + sta = sta_iter; + break; + } + } + spin_unlock_bh(&vif->rwnx_hw->cb_lock); + } + + memset(&cs_info, 0, sizeof(struct aicwf_cs_info)); + memcpy(cs_info.countrycode, country_code, 4); + + if((sta == NULL) && (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP)) { + sta = &vif->rwnx_hw->sta_table[vif->ap.bcmc_index]; + ctxt = &vif->rwnx_hw->chanctx_table[vif->ch_index]; + sta->center_freq = ctxt->chan_def.chan->center_freq; + sta->width = ctxt->chan_def.width; + } + + if(sta) { + stats = &sta->stats; + rx_vect2 = &stats->last_rx.rx_vect2; + + AICWFDBG(LOGINFO, "fill: staidx=%d\n", sta->sta_idx); + rwnx_fill_station_info(sta, vif, &sinfo, &phymode, &tx_phyrate, &rx_phyrate); + + cs_info.rssi = sinfo.signal; + //cs_info.bandwidth = sta->width; + if(sta->width < NL80211_CHAN_WIDTH_40) + cs_info.bandwidth = 0; + else if(sta->width < NL80211_CHAN_WIDTH_80) + cs_info.bandwidth = 1; + else + cs_info.bandwidth = 2; + cs_info.freq = sta->center_freq; + + cs_info.phymode = phymode; // 0:b 1:g 2:a 3:n 4:ac 5:ax + //snr (int8_t)rx_vect2->evm1, (int8_t)rx_vect2->evm2 + cs_info.snr = (int8_t)(rx_vect2->evm1) + (int8_t)(rx_vect2->evm2) / 2; + cs_info.noise = cs_info.rssi - cs_info.snr; //rssi - snr + + //chanutil TBD + cs_info.chan_time_ms = stats->last_chan_time; + cs_info.chan_time_busy_ms = stats->last_chan_busy_time; + cs_info.tx_ack_succ_stat = stats->tx_ack_succ_stat; + cs_info.tx_ack_fail_stat = stats->tx_ack_fail_stat; + cs_info.chan_tx_busy_time = stats->last_chan_tx_busy_time; + + cs_info.txpwr = cs_info.freq >5000? userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[0] : userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[0]; + if(sta->sta_idx < NX_REMOTE_STA_MAX) { + cs_info.rxnss = sinfo.rxrate.nss; + cs_info.rxmcs = sinfo.rxrate.mcs; + cs_info.txnss = sinfo.txrate.nss; + cs_info.txmcs = sinfo.txrate.mcs; + } + + cs_info.tx_phyrate = tx_phyrate; + cs_info.rx_phyrate = rx_phyrate; + + memcpy(val, &cs_info, sizeof(struct aicwf_cs_info)); + + AICWFDBG(LOGINFO, "phymode=%d. bw=%d, rssi=%d, tx_phyrate=%d, rx_phyrate=%d\n", cs_info.phymode, cs_info.bandwidth, cs_info.rssi, + tx_phyrate, rx_phyrate); + + return sizeof(struct aicwf_cs_info); + } + + return 0; +} int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) { @@ -1470,7 +1936,8 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) #if 1//Handle Android command - if(!strncasecmp(command, CMD_SET_COUNTRY, strlen(CMD_SET_COUNTRY))) { + if(!strncasecmp(command, CMD_SET_COUNTRY, strlen(CMD_SET_COUNTRY)) && + strncasecmp(command, "country_set", strlen("country_set"))) { skip = strlen(CMD_SET_COUNTRY) + 1; country = command + skip; if (!country || strlen(country) < RWNX_COUNTRY_CODE_LEN) { @@ -1497,10 +1964,24 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) #else wiphy_apply_custom_regulatory(vif->rwnx_hw->wiphy, regdomain); #endif + +#ifdef CONFIG_RADAR_OR_IR_DETECT + rwnx_radar_set_domain(&vif->rwnx_hw->radar, regdomain->dfs_region); +#endif + +#ifdef CONFIG_POWER_LIMIT + if (!testmode){ + rwnx_send_me_chan_config_req(vif->rwnx_hw, country); + } +#endif + ret = 0; + goto exit; } #ifdef CONFIG_SET_VENDOR_EXTENSION_IE else if(!strncasecmp(command, CMD_SET_VENDOR_EX_IE, strlen(CMD_SET_VENDOR_EX_IE))){ set_vendor_extension_ie(command); + ret = 0; + goto exit; } #endif//CONFIG_SET_VENDOR_EXTENSION_IE else if(!strncasecmp(command, CMD_SET_AP_WPS_P2P_IE, strlen(CMD_SET_AP_WPS_P2P_IE))){ @@ -1510,7 +1991,9 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) if(g_rwnx_plat && g_rwnx_plat->usbdev->rwnx_hw){ if (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW || (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC) || - (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81)){ + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81) || + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) || + (g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)){ set_testmode(!testmode); rwnx_send_reboot(g_rwnx_plat->usbdev->rwnx_hw); } @@ -1525,10 +2008,46 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) ret = 0; goto exit; } +#ifdef CONFIG_RWNX_MON_DATA + else if(!strncasecmp(command, CMD_SET_MON_FREQ, strlen(CMD_SET_MON_FREQ))){ + char *set_parameter; + skip = strlen(CMD_SET_MON_FREQ) + 1; + set_parameter = command + skip; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + set_mon_chan(vif, net, set_parameter); +#else + set_mon_chan(vif, set_parameter); +#endif + ret = 0; + goto exit; + } +#endif + else if(!strncasecmp(command, CMD_GET_CS_INFO, strlen(CMD_GET_CS_INFO))) { + u8 mac_addr[6]; + u8 val[128]; + int i; + u8 *offset; + + AICWFDBG(LOGDEBUG, "CMD_GET_CS_INFO,len=%d\n", priv_cmd.total_len); + offset = command + (strlen(CMD_GET_CS_INFO) + 1); + for(i=0; i<6; i++) { + mac_addr[i] = command_strtoul(offset, NULL, 16); + offset += 3; + } + bytes_written = get_cs_info(vif, mac_addr, val); + AICWFDBG(LOGDEBUG, "bytewritten=%d, addr=%pM\n", bytes_written, mac_addr); + + + memcpy(command, val, bytes_written); + + goto exit; + } + #endif//Handle Android command - bytes_written = handle_private_cmd(net, command, priv_cmd.total_len); + +exit: if (bytes_written >= 0) { if ((bytes_written == 0) && (priv_cmd.total_len > 0)) { command[0] = '\0'; @@ -1541,8 +2060,8 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) bytes_written++; priv_cmd.used_len = bytes_written; if (copy_to_user(priv_cmd.buf, command, bytes_written)) { - AICWFDBG(LOGERROR, "%s: failed to copy data to user buffer\n", __FUNCTION__); - ret = -EFAULT; + AICWFDBG(LOGINFO, "%s: failed to copy data to user buffer\n", __FUNCTION__); + ret = -EFAULT; } } else { @@ -1550,7 +2069,6 @@ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd) ret = bytes_written; } -exit: ///todo: add our unlock //net_os_wake_unlock(net); kfree(command); diff --git a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h index 7449190..50c9783 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h +++ b/drivers/aic8800/aic8800_fdrv/aic_priv_cmd.h @@ -19,6 +19,35 @@ typedef struct _android_wifi_priv_cmd { int total_len; } android_wifi_priv_cmd; +struct aicwf_cs_info { + u8_l phymode; + u8_l bandwidth; + u16_l freq; + + s8_l rssi; + s8_l snr; + s8_l noise; + u8_l txpwr; + + //chanutil + u16_l chan_time_ms; + u16_l chan_time_busy_ms; + + char countrycode[4]; + u8_l rxnss; + u8_l rxmcs; + u8_l txnss; + u8_l txmcs; + + u32_l tx_phyrate; + u32_l rx_phyrate; + + u32_l tx_ack_succ_stat; + u32_l tx_ack_fail_stat; + + u16_l chan_tx_busy_time; +}; + #ifdef CONFIG_COMPAT typedef struct _compat_android_wifi_priv_cmd { compat_caddr_t buf; @@ -28,6 +57,8 @@ typedef struct _compat_android_wifi_priv_cmd { #endif /* CONFIG_COMPAT */ int android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd); +int get_cs_info(struct rwnx_vif *vif, u8 *mac_addr, u8 *val); + #endif /* _AIC_PRIV_CMD_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/aic_vendor.c b/drivers/aic8800/aic8800_fdrv/aic_vendor.c index 105a02e..5394c71 100644 --- a/drivers/aic8800/aic8800_fdrv/aic_vendor.c +++ b/drivers/aic8800/aic8800_fdrv/aic_vendor.c @@ -314,17 +314,28 @@ out_put_fail: return -EMSGSIZE; } +struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, char *alpha2); + static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len) { int ret = 0, rem, type; const struct nlattr *iter; + struct ieee80211_regdomain *regdomain; nla_for_each_attr(iter, data, len, rem) { type = nla_type(iter); switch (type) { case ANDR_WIFI_ATTRIBUTE_COUNTRY: printk("%s(%d), ANDR_WIFI_ATTRIBUTE_COUNTRY: %s\n", __func__, __LINE__, (char *)nla_data(iter)); + regdomain = getRegdomainFromRwnxDB(wiphy, (char *)nla_data(iter)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + if((ret = regulatory_set_wiphy_regd(wiphy, regdomain))){ + AICWFDBG(LOGERROR, "regulatory_set_wiphy_regd fail \r\n"); + } +#else + wiphy_apply_custom_regulatory(wiphy, regdomain); +#endif break; default: pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c index 49d3558..9e98284 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80.c @@ -3,6 +3,9 @@ #include "reg_access.h" #define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt" +#define FW_USERCONFIG_NAME_8800D80_U11 "aic_userconfig_8800d80_u11.txt" +#define FW_USERCONFIG_NAME_8800D80_U11_PRO "aic_userconfig_8800d80_u11_pro.txt" +#define FW_USERCONFIG_NAME_8800D80_U11_CUS "aic_userconfig_8800d80_u11_cus.txt" #define FW_POWERLIMIT_NAME_8800D80 "aic_powerlimit_8800d80.txt" extern char aic_fw_path[200]; @@ -37,6 +40,18 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; char *filename = FW_USERCONFIG_NAME_8800D80; + if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS1 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS4) { + filename = FW_USERCONFIG_NAME_8800D80_U11; + } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U11_PRO + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS3 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS5 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS6) { + filename = FW_USERCONFIG_NAME_8800D80_U11_PRO; + } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800M80_CUS2) { + filename = FW_USERCONFIG_NAME_8800D80_U11_CUS; + } #ifndef ANDROID_PLATFORM sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80"); @@ -65,7 +80,7 @@ int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw){ } #ifdef CONFIG_POWER_LIMIT -extern char default_ccode[]; +extern char country_code[]; int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw) { int size; @@ -85,7 +100,7 @@ int rwnx_plat_powerlimit_load_8800d80(struct rwnx_hw *rwnx_hw) AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); /* parsing the file */ - rwnx_plat_powerlimit_parsing((char *)dst, size, default_ccode); + rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); rwnx_release_firmware_common(&dst); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c new file mode 100644 index 0000000..2d6c5e0 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.c @@ -0,0 +1,97 @@ +#include "rwnx_main.h" +#include "rwnx_msg_tx.h" +#include "reg_access.h" + +#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" +#define FW_POWERLIMIT_NAME_8800D80X2 "aic_powerlimit_8800d80x2.txt" + +extern char aic_fw_path[200]; + +int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw, + u32** buffer, const char *filename); +void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size); +void rwnx_plat_userconfig_parsing(char *buffer, int size); +void rwnx_release_firmware_common(u32** buffer); + + +int aicwf_set_rf_config_8800d80x2(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) +{ + int ret = 0; + + if ((ret = rwnx_send_txpwr_lvl_v4_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_lvl_adj_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_txpwr_ofst2x_v2_req(rwnx_hw))) { + return -1; + } + if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) { + return -1; + } + return 0 ; +} + + +int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw){ + int size; + u32 *dst=NULL; + char *filename = FW_USERCONFIG_NAME_8800D80X2; + +#ifndef ANDROID_PLATFORM + sprintf(aic_fw_path, "%s/%s", aic_fw_path, "aic8800D80X2"); +#endif + + AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + rwnx_plat_userconfig_parsing_8800d80x2((char *)dst, size); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "userconfig download complete\n\n"); + return 0; + +} + +#ifdef CONFIG_POWER_LIMIT +extern char country_code[]; +int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw) +{ + int size; + u32 *dst=NULL; + char *filename = FW_POWERLIMIT_NAME_8800D80X2; + + AICWFDBG(LOGINFO, "powerlimit file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(rwnx_hw, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of cfg file\n"); + dst = NULL; + return 0; + } + + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + /* parsing the file */ + rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "powerlimit download complete\n\n"); + return 0; +} +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.h new file mode 100644 index 0000000..df6f1dd --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800d80x2.h @@ -0,0 +1,9 @@ +#include + +int rwnx_plat_userconfig_load_8800d80x2(struct rwnx_hw *rwnx_hw); +#ifdef CONFIG_POWER_LIMIT +int rwnx_plat_powerlimit_load_8800d80x2(struct rwnx_hw *rwnx_hw); +#endif +int aicwf_set_rf_config_8800d80x2(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); + + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c index ac30601..53dbfcb 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.c @@ -45,6 +45,8 @@ #define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt" #define FW_POWERLIMIT_NAME_8800DC "aic_powerlimit_8800dc.txt" #define FW_POWERLIMIT_NAME_8800DW "aic_powerlimit_8800dw.txt" +#define FW_USERCONFIG_NAME_8800DW_W311 "aic_userconfig_8800dw_w311.txt" +#define FW_USERCONFIG_NAME_8800DW_U2 "aic_userconfig_8800dw_u2.txt" #ifdef CONFIG_LOAD_BT_PATCH_IN_FDRV enum aicbt_patch_table_type { @@ -240,6 +242,7 @@ u32 syscfg_tbl_8800dc[][2] = { u32 patch_tbl_wifisetting[][2] = { + {0x0004, 0x00020010}, //wdt_reboot_type, wdt_period_sec #if !defined(CONFIG_FPGA_VERIFICATION) {0x0090, 0x0013FC00}, //rx_ringbuf_start2 #endif @@ -248,6 +251,10 @@ u32 patch_tbl_wifisetting[][2] = {0x0120, 0x140A0100}, //usb agg tx params(total cnt, aggr cnt, out en, global out nak) #endif //CONFIG_USB_TX_AGGR {0x00b0, 0xAD180100}, +#ifdef CONFIG_BAND_STEERING + {0x0138, 0x00010a00}, //apm probe resp offload en +#endif + {0x0084, 0x00000040}, }; u32 jump_tbl[][2] = @@ -1453,6 +1460,7 @@ uint32_t agc_cfg_ram[] = { 0x00000000 }; +#if !defined(CONFIG_EXT_FEM_8800DCDW) uint32_t txgain_map[96] = { #ifdef CONFIG_FPGA_VERIFICATION 0x20c0c971, @@ -1632,9 +1640,9 @@ uint32_t txgain_map[96] = { 0x00ffcd70, 0x00ffcd80, 0x00ffcd90, - 0x00ffce80, - 0x00ffce93, - 0x00ffcf90, + 0x00ffcf68, + 0x00ffcf75, + 0x00ffcf83, 0x00ffc080, 0x00ffc090, 0x00ffc180, @@ -1733,8 +1741,8 @@ const uint32_t txgain_map_h[96] = 0xffcc6b, //15 0xffcc79, //16 0xffcd72, //17 - 0xffce60, //18 - 0xffce72, //19 + 0xffcf5b, //18 + 0xffcf66, //19 0xffcf72, //20 0xffcf80, //21 0xffcf90, //22 @@ -1757,6 +1765,214 @@ const uint32_t txgain_map_h[96] = 0xffc86b, //7 }; +#else /* #ifdef CONFIG_EXT_FEM_8800DCDW */ +const uint32_t txgain_map_femkct[96] = +{ + //11b + 0x00ffd780,//15 + 0x00ffd872,//16 + 0x00ffd880,//17 + 0x00ffd972,//18 + 0x00ffd980,//19 + 0x00ffda72,//20 + 0x00ffda80,//21 + 0x00ffdb72,//22 + 0x00ffdb80,//23 + 0x00ffdc72,//24 + 0x00ffdc80,//25 + 0x00ffdd72,//26 + 0x00ffdd80,//27 + 0x00ffde72,//28 + 0x00ffde80,//29 + 0x00ffdf72,//30 + 0x00ffd072,//-1 + 0x00ffd072,//0 + 0x00ffd080,//1 + 0x00ffd172,//2 + 0x00ffd180,//3 + 0x00ffd272,//4 + 0x00ffd280,//5 + 0x00ffd36d,//6 + 0x00ffd379,//7 + 0x00ffd46d,//8 + 0x00ffd479,//9 + 0x00ffd572,//10 + 0x00ffd580,//11 + 0x00ffd672,//12 + 0x00ffd680,//13 + 0x00ffd772,//14 + //high + 0x00ffc872,//11 + 0x00ffc880,//12 + 0x00ffc972,//13 + 0x00ffc980,//14 + 0x00ffca72,//15 + 0x00ffca80,//16 + 0x00ffcb72,//17 + 0x00ffcb80,//18 + 0x00ffcc72,//19 + 0x00ffcc80,//20 + 0x00ffcd72,//21 + 0x00ffcd80,//22 + 0x00ffce72,//23 + 0x00ffce80,//24 + 0x00ffcf72,//25 + 0x00ffcf80,//26 + 0x00ffc072,//-5 + 0x00ffc080,//-4 + 0x00ffc172,//-3 + 0x00ffc180,//-2 + 0x00ffc272,//-1 + 0x00ffc280,//0 + 0x00ffc372,//1 + 0x00ffc380,//2 + 0x00ffc472,//3 + 0x00ffc480,//4 + 0x00ffc572,//5 + 0x00ffc580,//6 + 0x00ffc672,//7 + 0x00ffc680,//8 + 0x00ffc772,//9 + 0x00ffc780,//10 + //low + 0x00ffc872,//11 + 0x00ffc880,//12 + 0x00ffc972,//13 + 0x00ffc980,//14 + 0x00ffca72,//15 + 0x00ffca80,//16 + 0x00ffcb72,//17 + 0x00ffcb80,//18 + 0x00ffcc72,//19 + 0x00ffcc80,//20 + 0x00ffcd72,//21 + 0x00ffcd80,//22 + 0x00ffce72,//23 + 0x00ffce80,//24 + 0x00ffcf72,//26 + 0x00ffcf80,//27 + 0x00ffc072,//-5 + 0x00ffc080,//-4 + 0x00ffc172,//-3 + 0x00ffc180,//-2 + 0x00ffc272,//-1 + 0x00ffc280,//0 + 0x00ffc372,//1 + 0x00ffc380,//2 + 0x00ffc472,//3 + 0x00ffc480,//4 + 0x00ffc572,//5 + 0x00ffc580,//6 + 0x00ffc672,//7 + 0x00ffc680,//8 + 0x00ffc772,//9 + 0x00ffc780,//10 +}; + +const uint32_t txgain_map_femkct_h[96] = +{ + //11b + 0x00ffd872,//15 + 0x00ffd880,//16 + 0x00ffd972,//17 + 0x00ffd980,//18 + 0x00ffd990,//19 + 0x00ffda72,//20 + 0x00ffda80,//21 + 0x00ffdb72,//22 + 0x00ffdb80,//23 + 0x00ffdc72,//24 + 0x00ffdc80,//25 + 0x00ffdd72,//26 + 0x00ffdd80,//27 + 0x00ffde72,//28 + 0x00ffde80,//29 + 0x00ffdf72,//30 + 0x00ffd072,//-1 + 0x00ffd072,//0 + 0x00ffd080,//1 + 0x00ffd172,//2 + 0x00ffd180,//3 + 0x00ffd272,//4 + 0x00ffd280,//5 + 0x00ffd379,//6 + 0x00ffd46d,//7 + 0x00ffd479,//8 + 0x00ffd572,//9 + 0x00ffd580,//10 + 0x00ffd672,//11 + 0x00ffd680,//12 + 0x00ffd772,//13 + 0x00ffd780,//14 + //high + 0x00ffc880,//11 + 0x00ffc972,//12 + 0x00ffc980,//13 + 0x00ffca72,//14 + 0x00ffca80,//15 + 0x00ffcb72,//16 + 0x00ffcb80,//17 + 0x00ffcc72,//18 + 0x00ffcc80,//19 + 0x00ffcc90,//20 + 0x00ffcd72,//21 + 0x00ffcd80,//22 + 0x00ffce72,//23 + 0x00ffce80,//24 + 0x00ffcf72,//25 + 0x00ffcf80,//26 + 0x00ffc080,//-5 + 0x00ffc172,//-4 + 0x00ffc180,//-3 + 0x00ffc272,//-2 + 0x00ffc280,//-1 + 0x00ffc372,//0 + 0x00ffc380,//1 + 0x00ffc472,//2 + 0x00ffc480,//3 + 0x00ffc572,//4 + 0x00ffc580,//5 + 0x00ffc672,//6 + 0x00ffc680,//7 + 0x00ffc772,//8 + 0x00ffc780,//9 + 0x00ffc872,//10 + //low + 0x00ffc880,//11 + 0x00ffc972,//12 + 0x00ffc980,//13 + 0x00ffca72,//14 + 0x00ffca80,//15 + 0x00ffcb72,//16 + 0x00ffcb80,//17 + 0x00ffcc72,//18 + 0x00ffcc80,//19 + 0x00ffcc90,//20 + 0x00ffcd72,//21 + 0x00ffcd80,//22 + 0x00ffce72,//23 + 0x00ffce80,//24 + 0x00ffcf72,//25 + 0x00ffcf80,//26 + 0x00ffc080,//-5 + 0x00ffc172,//-4 + 0x00ffc180,//-3 + 0x00ffc272,//-2 + 0x00ffc280,//-1 + 0x00ffc372,//0 + 0x00ffc380,//1 + 0x00ffc472,//2 + 0x00ffc480,//3 + 0x00ffc572,//4 + 0x00ffc580,//5 + 0x00ffc672,//6 + 0x00ffc680,//7 + 0x00ffc772,//8 + 0x00ffc780,//9 + 0x00ffc872,//10 +}; +#endif + u32 patch_tbl_func[][2] = { {0x00110054, 0x0018186D}, // same as jump_tbl idx 168 @@ -1770,6 +1986,7 @@ u32 patch_tbl_rf_func[][2] = }; +#if !defined(CONFIG_EXT_FEM_8800DCDW) u32 wifi_txgain_table_24g_8800dcdw[32] = { 0xA4B22189, //index 0 @@ -1914,6 +2131,80 @@ u32 wifi_txgain_table_24g_1_8800dcdw_h[32] = 0x00001825, }; +#else /* #ifdef CONFIG_EXT_FEM_8800DCDW */ +// ofdm +uint32_t wifi_txgain_table_24g_8800dcdw_femkct[32] = { + 0x919221C2, //index 0 + 0x00007825, + 0x899221C3, //index 1 + 0x00007825, + 0x8B9221C3, //index 2 + 0x00007825, + 0x929221C3, //index 3 + 0x00007825, + 0x949221C4, //index 4 + 0x00007825, + 0x969221C4, //index 5 + 0x00007825, + 0x949221C6, //index 6 + 0x00007825, + 0x949221C8, //index 7 + 0x00007825, + 0x9C9221C8, //index 8 + 0x00007825, + 0x9C9221CA, //index 9 + 0x00007825, + 0x9C9221CB, //index 10 + 0x00007825, + 0x939221D5, //index 11 + 0x00007825, + 0x9B9221D7, //index 12 + 0x00007825, + 0xA49221D7, //index 13 + 0x00007825, + 0xA79221D7, //index 14 + 0x00007825, + 0xBD9221D7, //index 15 + 0x00007825, +}; + +// 11b +uint32_t wifi_txgain_table_24g_1_8800dcdw_femkct[32] = { + 0x836E20C2, //index 0 + 0x00003024, + 0x856E20C2, //index 1 + 0x00003024, + 0x826E20C3, //index 2 + 0x00003024, + 0x836E20C3, //index 3 + 0x00003024, + 0x856E20C3, //index 4 + 0x00003024, + 0x876E20C3, //index 5 + 0x00003024, + 0x8B6E20C3, //index 6 + 0x00003024, + 0x926E20C4, //index 7 + 0x00003024, + 0x9A6E20C4, //index 8 + 0x00003024, + 0x936E20C5, //index 9 + 0x00003024, + 0x936E20C7, //index 10 + 0x00003024, + 0xA16E20C8, //index 11 + 0x00003024, + 0xA16E20CA, //index 12 + 0x00003024, + 0xA26E20CB, //index 13 + 0x00003024, + 0xAA6E20CD, //index 14 + 0x00003024, + 0xAC7220CF, //index 15 + 0x00003024, +}; +#endif + u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = { 0x82f282d1,//index 0 0x9591a324, @@ -2277,6 +2568,10 @@ err: rf_misc_ram_lite_t dpd_res; #endif +#ifdef CONFIG_LOFT_CALIB +rf_misc_ram_lite_t loft_res_local; +#endif + int aicwf_patch_table_load(struct rwnx_hw *rwnx_hw, char *filename) { int err = 0; @@ -2513,11 +2808,21 @@ void aicwf_patch_config_8800dc(struct rwnx_hw *rwnx_hw) #if !defined(CONFIG_FPGA_VERIFICATION) if ((IS_CHIP_ID_H())) { + #if defined(CONFIG_EXT_FEM_8800DCDW) + txgain_cfg_size = sizeof(txgain_map_femkct_h); + txgain_cfg_array = (u32 *)txgain_map_femkct_h; + #else txgain_cfg_size = sizeof(txgain_map_h); txgain_cfg_array = (u32 *)txgain_map_h; + #endif } else { + #if defined(CONFIG_EXT_FEM_8800DCDW) + txgain_cfg_size = sizeof(txgain_map_femkct); + txgain_cfg_array = (u32 *)txgain_map_femkct; + #else txgain_cfg_size = sizeof(txgain_map); txgain_cfg_array = (u32 *)txgain_map; + #endif } ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, txgain_cfg_addr, txgain_cfg_size, txgain_cfg_array); if (ret) { @@ -2588,6 +2893,7 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c if (testmode == FW_NORMAL_MODE) { + #if !defined(CONFIG_EXT_FEM_8800DCDW) if (IS_CHIP_ID_H()) { if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128))) return -1; @@ -2599,6 +2905,18 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128))) return -1; } + #else /* #ifdef CONFIG_EXT_FEM_8800DCDW */ + { + ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw_femkct, 128); + if (ret) { + return -1; + } + ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_femkct, 128); + if (ret) { + return -1; + } + } + #endif if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256))) return -1; @@ -2629,6 +2947,14 @@ int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_c return ret; } } + #elif defined(CONFIG_LOFT_CALIB) + if (loft_res_local.bit_mask[1]) { + ret = aicwf_loft_result_apply_8800dc(rwnx_hw, &loft_res_local); + if (ret) { + AICWFDBG(LOGINFO, "apply loft res fail: %d\n", ret); + return ret; + } + } #else { ret = aicwf_misc_ram_init_8800dc(rwnx_hw); @@ -2703,7 +3029,7 @@ int aicwf_plat_rftest_load_8800dc(struct rwnx_hw *rwnx_hw) return ret; } -#ifdef CONFIG_DPD +#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB) int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out) { int ret = 0; @@ -2712,61 +3038,81 @@ int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out) uint32_t misc_ram_addr; uint32_t ram_base_addr, ram_word_cnt; uint32_t bit_mask[4]; + uint32_t dpd_info_read_addr = 0xfe004; + uint32_t boot_argc_read_addr = 0x1220f0; + uint32_t flash_size_mem_addr = 0x40038030; + uint8_t flash_size = 0; int i; if (valid_out) { *valid_out = 0; } - if (testmode == FW_RFTEST_MODE) { - uint32_t vect1 = 0; - uint32_t vect2 = 0; - cfg_base = RAM_LMAC_FW_ADDR + 0x0004; - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "cfg_base:%x vcet1 rd fail: %d\n", cfg_base, ret); - return ret; - } - vect1 = cfm.memdata; - if ((vect1 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { - AICWFDBG(LOGERROR, "vect1 invalid: %x\n", vect1); - return ret; - } - cfg_base = RAM_LMAC_FW_ADDR + 0x0008; - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base, &cfm); - if (ret) { - AICWFDBG(LOGERROR, "cfg_base:%x vcet2 rd fail: %d\n", cfg_base, ret); - return ret; - } - vect2 = cfm.memdata; - if ((vect2 & 0xFFFF0000) != (RAM_LMAC_FW_ADDR & 0xFFFF0000)) { - AICWFDBG(LOGERROR, "vect2 invalid: %x\n", vect2); - return ret; - } - cfg_base = RAM_LMAC_FW_ADDR + 0x0164; - } - // init misc ram - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); + + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, boot_argc_read_addr, &cfm); if (ret) { - AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); + AICWFDBG(LOGERROR, "boot argc [0x%x] rd fail: %d\n", boot_argc_read_addr, ret); + return ret; + } + printk("boot argc %x\n", cfm.memdata); + if (cfm.memdata & 0x10) { + *valid_out = 1; return ret; } - misc_ram_addr = cfm.memdata; - AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); - // bit_mask - ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); - ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; - for (i = 0; i < ram_word_cnt; i++) { - ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); + if (chip_mcu_id) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, flash_size_mem_addr, &cfm); if (ret) { - AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + AICWFDBG(LOGERROR, "flash size[0x%x] rd fail: %d\n", flash_size_mem_addr, ret); return ret; } - bit_mask[i] = cfm.memdata; - } - AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]); - if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) && - (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) { - if (valid_out) { - *valid_out = 1; + flash_size = cfm.memdata & 0xff; + printk("flash size %x\n", flash_size); + if (flash_size == 0x16) { + dpd_info_read_addr += 0x4300000; + } else if (flash_size == 0x15) { + dpd_info_read_addr += 0x4100000; + } else if (flash_size == 0x18) { + dpd_info_read_addr += 0x4700000; + } else { + dpd_info_read_addr += 0x4100000; + } + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, dpd_info_read_addr, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "dpd info [0x%x] rd fail: %d\n", dpd_info_read_addr, ret); + return ret; + } + if (cfm.memdata & (1<<7)) { + if (valid_out) { + *valid_out = 1; + } + } + } else { + if (testmode == FW_RFTEST_MODE) { + cfg_base = RAM_LMAC_FW_ADDR + 0x0164; + } + // init misc ram + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); + return ret; + } + misc_ram_addr = cfm.memdata; + AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr); + // bit_mask + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); + ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; + for (i = 0; i < ram_word_cnt; i++) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + return ret; + } + bit_mask[i] = cfm.memdata; + } + AICWFDBG(LOGTRACE, "bit_mask:%x,%x,%x,%x\n",bit_mask[0],bit_mask[1],bit_mask[2],bit_mask[3]); + if ((bit_mask[0] == 0) && ((bit_mask[1] & 0xFFF00000) == 0x80000000) && + (bit_mask[2] == 0) && ((bit_mask[3] & 0xFFFFFF00) == 0x00000000)) { + if (valid_out) { + *valid_out = 1; + } } } return ret; @@ -2879,7 +3225,7 @@ int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res) for (i = 0; i < ram_word_cnt; i++) { ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); if (ret) { - AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + AICWFDBG(LOGERROR, "dpd_high[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); return ret; } dpd_res->dpd_high[i] = cfm.memdata; @@ -2890,7 +3236,7 @@ int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res) for (i = 0; i < ram_word_cnt; i++) { ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); if (ret) { - AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + AICWFDBG(LOGERROR, "loft_res[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); return ret; } dpd_res->loft_res[i] = cfm.memdata; @@ -3023,6 +3369,117 @@ int aicwf_dpd_result_write_8800dc(void *buf, int buf_len) #endif /* !CONFIG_FORCE_DPD_CALIB */ #endif +#ifdef CONFIG_LOFT_CALIB +int aicwf_loft_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res) +{ + int ret = 0; + uint32_t fw_addr, boot_type; + int valid_flag; + ret = aicwf_misc_ram_valid_check_8800dc(rwnx_hw, &valid_flag); + if (ret) { + AICWFDBG(LOGINFO, "misc ram check fail: %d\n", ret); + return ret; + } + if (valid_flag) { + AICWFDBG(LOGINFO, "misc ram valid, skip calib process\n"); + return ret; + } + ret = aicwf_plat_calib_load_8800dc(rwnx_hw); + if (ret) { + AICWFDBG(LOGINFO, "load calib bin fail: %d\n", ret); + return ret; + } + /* fw start */ + fw_addr = 0x00130009; + boot_type = HOST_START_APP_FNCALL; + AICWFDBG(LOGINFO, "Start app: %08x, %d\n", fw_addr, boot_type); + ret = rwnx_send_dbg_start_app_req(rwnx_hw, fw_addr, boot_type); + if (ret) { + AICWFDBG(LOGINFO, "start app fail: %d\n", ret); + return ret; + } + { // read loft res + const uint32_t cfg_base = 0x10164; + struct dbg_mem_read_cfm cfm; + uint32_t misc_ram_addr; + uint32_t ram_base_addr, ram_word_cnt; + int i; + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); + return ret; + } + misc_ram_addr = cfm.memdata; + // bit_mask + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); + ram_word_cnt = (MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved)) / 4; + for (i = 0; i < ram_word_cnt; i++) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "bit_mask[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + return ret; + } + loft_res->bit_mask[i] = cfm.memdata; + } + // loft_res + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res); + ram_word_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res) / 4; + for (i = 0; i < ram_word_cnt; i++) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, ram_base_addr + i * 4, &cfm); + if (ret) { + AICWFDBG(LOGERROR, "loft_res[0x%x] rd fail: %d\n", ram_base_addr + i * 4, ret); + return ret; + } + loft_res->loft_res[i] = cfm.memdata; + } + } + return ret; +} + +int aicwf_loft_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res) +{ + int ret = 0; + uint32_t cfg_base = 0x10164; + struct dbg_mem_read_cfm cfm; + uint32_t misc_ram_addr; + uint32_t ram_base_addr, ram_byte_cnt; + AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", loft_res->bit_mask[1]); + if (loft_res->bit_mask[1] == 0) { + AICWFDBG(LOGERROR, "void loft_res, bypass it.\n"); + return 0; + } + if (testmode == FW_RFTEST_MODE) { + cfg_base = RAM_LMAC_FW_ADDR + 0x0164; + } + if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) { + AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret); + return ret; + } + misc_ram_addr = cfm.memdata; + AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr); + /* Copy loft_res on the Embedded side */ + // bit_mask + AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", loft_res->bit_mask[0]); + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask); + ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved); + ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&loft_res->bit_mask[0]); + if (ret) { + AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret); + return ret; + } + // loft_res + AICWFDBG(LOGINFO, "loft_res[0]=%x\n", loft_res->loft_res[0]); + ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res); + ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res); + ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&loft_res->loft_res[0]); + if (ret) { + AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret); + return ret; + } + return ret; +} +#endif + int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; @@ -3054,6 +3511,14 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){ int size; u32 *dst=NULL; char *filename = FW_USERCONFIG_NAME_8800DW; + if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA) { + filename = FW_USERCONFIG_NAME_8800DW_W311; + } else if (rwnx_hw->usbdev->pid == USB_PRODUCT_ID_TENDA_U2 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS1 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS2 + || rwnx_hw->usbdev->pid == USB_PRODUCT_ID_AIC8800FC_CUS3) { + filename = FW_USERCONFIG_NAME_8800DW_U2; + } AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); @@ -3078,7 +3543,7 @@ int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){ } #ifdef CONFIG_POWER_LIMIT -extern char default_ccode[]; +extern char country_code[]; int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id) { @@ -3107,7 +3572,7 @@ int rwnx_plat_powerlimit_load_8800dcdw(struct rwnx_hw *rwnx_hw, uint16_t chip_id /* Copy the file on the Embedded side */ AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); - rwnx_plat_powerlimit_parsing((char *)dst, size, default_ccode); + rwnx_plat_powerlimit_parsing((char *)dst, size, country_code); rwnx_release_firmware_common(&dst); @@ -3162,6 +3627,7 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){ array3_tbl_t p_syscfg_msk_tbl; int ret, cnt; const u32 mem_addr = 0x40500000; + const u32 cache_mem_addr = 0x40100020; struct dbg_mem_read_cfm rd_mem_addr_cfm; ret = rwnx_send_dbg_mem_read_req(rwnx_hw, mem_addr, &rd_mem_addr_cfm); @@ -3175,6 +3641,21 @@ void system_config_8800dc(struct rwnx_hw *rwnx_hw){ chip_mcu_id = 1; } + if (chip_mcu_id) { + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cache_mem_addr, &rd_mem_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "%x rd fail: %d\n", mem_addr, ret); + return; + } + rd_mem_addr_cfm.memdata |= 0x01; + ret = rwnx_send_dbg_mem_write_req(rwnx_hw, cache_mem_addr, rd_mem_addr_cfm.memdata); + + if (ret) { + AICWFDBG(LOGERROR, "%x write fail: %d\n", cache_mem_addr, ret); + return; + } + } + ret = rwnx_send_dbg_mem_read_req(rwnx_hw, 0x00000020, &rd_mem_addr_cfm); if (ret) { AICWFDBG(LOGERROR, "[0x00000020] rd fail: %d\n", ret); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h index a46bd64..c0e53cb 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_compat_8800dc.h @@ -1,6 +1,6 @@ #include -#ifdef CONFIG_DPD +#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB) typedef struct { uint32_t bit_mask[3]; uint32_t reserved; @@ -22,17 +22,25 @@ typedef struct { #define MEMBER_SIZE(type, member) sizeof(((type *)0)->member) #define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t) +#endif +#ifdef CONFIG_DPD extern rf_misc_ram_lite_t dpd_res; #endif +#ifdef CONFIG_LOFT_CALIB +extern rf_misc_ram_lite_t loft_res_local; +#endif + int aicwf_patch_table_load(struct rwnx_hw *rwnx_hw, char *filename); void aicwf_patch_config_8800dc(struct rwnx_hw *rwnx_hw); int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm); int aicwf_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw); -#ifdef CONFIG_DPD +#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB) int aicwf_misc_ram_valid_check_8800dc(struct rwnx_hw *rwnx_hw, int *valid_out); int aicwf_plat_calib_load_8800dc(struct rwnx_hw *rwnx_hw); +#endif +#ifdef CONFIG_DPD int aicwf_dpd_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res); int aicwf_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res); #ifndef CONFIG_FORCE_DPD_CALIB @@ -40,6 +48,10 @@ int aicwf_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dp int aicwf_dpd_result_write_8800dc(void *buf, int buf_len); #endif #endif +#ifdef CONFIG_LOFT_CALIB +int aicwf_loft_calib_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res); +int aicwf_loft_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *loft_res); +#endif int aicwf_plat_patch_load_8800dc(struct rwnx_hw *rwnx_hw); int aicwf_plat_rftest_load_8800dc(struct rwnx_hw *rwnx_hw); int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_debug.h b/drivers/aic8800/aic8800_fdrv/aicwf_debug.h index 12fdca6..bec2500 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_debug.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_debug.h @@ -10,6 +10,7 @@ #define LOGTRACE 0x0004 #define LOGDEBUG 0x0008 #define LOGDATA 0x0010 +#define LOGSTEER 0x0020 extern int aicwf_dbg_level; void rwnx_data_dump(char* tag, void* data, unsigned long len); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_manager.c b/drivers/aic8800/aic8800_fdrv/aicwf_manager.c new file mode 100644 index 0000000..289e108 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_manager.c @@ -0,0 +1,601 @@ +/** + ****************************************************************************** + * + * Copyright (C) 2020 AIC semiconductor. + * + * @file aicwf_manager.c + * + * @brief netlink msg definitions + * + ****************************************************************************** + */ + +#include +#include +#include +#include "aicwf_manager.h" +#include "lmac_mac.h" +#include "aicwf_debug.h" + +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG(x) ((u8_l *)(x))[0], ((u8_l *)(x))[1], ((u8_l *)(x))[2], ((u8_l *)(x))[3], ((u8_l *)(x))[4], ((u8_l *)(x))[5] +#define MANAGER_STR "[MANAGER] USB " + + +static struct sock *nl_sock = NULL; + +static struct rwnx_vif *nl_rwnx_vif[PHY_BAND_MAX][CONFIG_IFACE_NUMBER] = {{NULL}}; +static u8_l nl_hook[PHY_BAND_MAX][CONFIG_IFACE_NUMBER] = {{0}}; + +static u8_l nl_daemon_on = 0; + +#define FREQ_2G_MIN 2412 +#define FREQ_2G_MAX 2484 +#define FREQ_5G_MIN 5170 +#define FREQ_5G_MAX 5825 +#define FREQ_6G_MIN 5925 +#define FREQ_6G_MAX 7125 + +static int freq_to_channel(int freq) +{ + if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) { + if (freq == 2484) { + return 14; + } else { + return (freq - 2412) / 5 + 1; + } + } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) { + return (freq - 5000) / 5; + } else if (freq >= FREQ_6G_MIN && freq <= FREQ_6G_MAX) { + return (freq - 5950) / 5; + } else { + AICWFDBG(LOGERROR, MANAGER_STR"aic Unsupported frequency: %d MHz\n", freq); + return -1; + } +} + + +void aicwf_nl_recv_msg(struct sk_buff *skb) +{ + struct rwnx_vif *rwnx_vif; + struct rwnx_sta *sta = NULL; + u8_l rwnx_hook = 0; + u8_l band; + u8_l ssid; + struct nlmsghdr *nlh = NULL; + struct b_nl_message *msg = NULL; + struct b_elm_header *hdr = NULL; + struct b_elm_intf *intf = NULL; + struct b_elm_sta_info *sta_info = NULL; + struct b_elm_roam_info *roam_info = NULL; + u32 offset = 0; + + if (skb == NULL) { + AICWFDBG(LOGERROR, MANAGER_STR"skb is null.\n"); + return; + } + + nlh = (struct nlmsghdr *)skb->data; + msg = (struct b_nl_message *)NLMSG_DATA(nlh); + + AICWFDBG(LOGSTEER, MANAGER_STR"%s, %d\n", __func__, msg->type); + + /* message type */ + switch(msg->type) { + case AIC_NL_DAEMON_ON_TYPE: + nl_daemon_on = 1; + AICWFDBG(LOGSTEER, MANAGER_STR"AIC_NL_DAEMON_ON_TYPE\n"); + for (band = 0; band < PHY_BAND_MAX; band++) { + for (ssid = 0; ssid < CONFIG_IFACE_NUMBER; ssid++) { + rwnx_vif = nl_rwnx_vif[band][ssid]; + rwnx_hook = nl_hook[band][ssid]; + + if (!rwnx_hook) { + AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_hook, %d,%d\n", __func__, band, ssid); + continue; + } + if (rwnx_vif == NULL || rwnx_vif->up == false) { + AICWFDBG(LOGSTEER, MANAGER_STR"%s, !rwnx_vif, %d,%d\n", __func__, band, ssid); + continue; + } + +#ifdef CONFIG_BAND_STEERING + aicwf_band_steering_init(rwnx_vif); +#endif + + spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock); + list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list){ + if (sta->valid) + aicwf_nl_send_new_sta_msg(rwnx_vif, sta->mac_addr); + } + spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); + } + } + break; + case AIC_NL_DAEMON_OFF_TYPE: + nl_daemon_on = 0; + break; +#ifdef CONFIG_BAND_STEERING + case AIC_NL_B_STEER_BLOCK_ADD_TYPE: + case AIC_NL_B_STEER_BLOCK_DEL_TYPE: + while (offset < msg->len) { + hdr = (struct b_elm_header *)(msg->content + offset); + offset += ELM_HEADER_LEN; + + switch(hdr->id) { + case AIC_ELM_INTF_ID: + intf = (struct b_elm_intf *)(msg->content + offset); + break; + case AIC_ELM_STA_INFO_ID: + sta_info = (struct b_elm_sta_info *)(msg->content + offset); + break; + default: + AICWFDBG(LOGERROR, MANAGER_STR"unknown element id.\n"); + break; + } + offset += hdr->len; + } + + if (intf && sta_info) { + band = intf->band; + ssid = intf->ssid; + AICWFDBG(LOGSTEER, MANAGER_STR"STEER_BLOCK band: %d, ssid: %d\n", band, ssid); + rwnx_vif = nl_rwnx_vif[band][ssid]; + rwnx_hook = nl_hook[band][ssid]; + + if (!rwnx_hook) { + AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_hook is null p1.\n"); + break; + } + if (rwnx_vif == NULL || rwnx_vif->up == false) { + AICWFDBG(LOGSTEER, MANAGER_STR"rwnx_vif is null/down p1.\n"); + break; + } + + if (msg->type == AIC_NL_B_STEER_BLOCK_ADD_TYPE) + aicwf_band_steering_block_entry_add(rwnx_vif, sta_info->mac); + else if (msg->type == AIC_NL_B_STEER_BLOCK_DEL_TYPE) + aicwf_band_steering_block_entry_del(rwnx_vif, sta_info->mac); + } + break; + case AIC_NL_B_STEER_ROAM_TYPE: + while (offset < msg->len) { + hdr = (struct b_elm_header *)(msg->content + offset); + offset += ELM_HEADER_LEN; + + /* element type: should handle wrong length */ + switch(hdr->id) { + case AIC_ELM_INTF_ID: + intf = (struct b_elm_intf *)(msg->content + offset); + break; + case AIC_ELM_ROAM_INFO_ID: + roam_info = (struct b_elm_roam_info *)(msg->content + offset); + break; + default: + AICWFDBG(LOGERROR, MANAGER_STR"unknown element id.\n"); + break; + } + offset += hdr->len; + } + + if (intf && roam_info) { + band = intf->band; + ssid = intf->ssid; + rwnx_vif = nl_rwnx_vif[band][ssid]; + rwnx_hook = nl_hook[band][ssid]; + + if (!rwnx_hook) { + AICWFDBG(LOGERROR, MANAGER_STR"rwnx_hook is null p2.\n"); + break; + } + if (rwnx_vif == NULL || rwnx_vif->up == false) { + AICWFDBG(LOGERROR, MANAGER_STR"rwnx_vif is null/down p2.\n"); + break; + } + + AICWFDBG(LOGSTEER, MANAGER_STR"AIC_NL_B_STEER_ROAM_TYPE (hostapd_cli)!\n"); + AICWFDBG(LOGSTEER, MANAGER_STR"sta_mac="MAC_FMT"\n", MAC_ARG(roam_info->sta_mac)); + AICWFDBG(LOGSTEER, MANAGER_STR"bss_mac="MAC_FMT" bss_ch=%u method=%s\n", + MAC_ARG(roam_info->bss_mac), + roam_info->bss_ch, + roam_info->method == 0 ? "11V" : "Deauth"); + + if (roam_info->method == 1) + aicwf_band_steering_roam_block_entry_add(rwnx_vif, roam_info->sta_mac); + } + break; +#endif + default: + AICWFDBG(LOGERROR, MANAGER_STR"unknown message type.\n"); + break; + } + + return; +} + +void aicwf_nl_send_msg(void *msg, u32 msg_len) +{ + struct nlmsghdr *nlh = NULL; + struct sk_buff *skb = NULL; + u32 skb_len; + s32 err; + + skb_len = NLMSG_SPACE(NL_MAX_MSG_SIZE); + skb = __dev_alloc_skb(skb_len, GFP_ATOMIC); + if (!skb) { + AICWFDBG(LOGERROR, MANAGER_STR"allocate skb failed.\n"); + goto func_return; + } + + nlh = nlmsg_put(skb, 0, 0, 0, NL_MAX_MSG_SIZE, 0); + if (!nlh) { + AICWFDBG(LOGERROR, MANAGER_STR"put netlink header failed.\n"); + kfree_skb(skb); + goto func_return; + } + + NETLINK_CB(skb).portid = 0; + NETLINK_CB(skb).dst_group = 0; + memset(NLMSG_DATA(nlh), 0, msg_len); + memcpy(NLMSG_DATA(nlh), (u8_l *)msg, msg_len); + + if (!nl_sock) { + AICWFDBG(LOGERROR, MANAGER_STR"[%s %u] nl_sock is NULL\n", __FUNCTION__, __LINE__); + goto msg_fail_skb; + } + + err = netlink_unicast(nl_sock, skb, NL_AIC_MANAGER_PID, MSG_DONTWAIT); + + if (err < 0) { + /* netlink_unicast() already kfree_skb */ + AICWFDBG(LOGSTEER, MANAGER_STR"send netlink unicast failed.\n"); + goto func_return; + } + +func_return: + return; + +msg_fail_skb: + kfree_skb(skb); +} + +static void aicwf_netlink_set_msg( + struct b_nl_message *msg, u32 *msg_len, void *elm, u32 elm_len) +{ + memcpy(msg->content + (*msg_len), elm, elm_len); + (*msg_len) += elm_len; + + return; +} + +void aicwf_nl_send_del_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_intf intf = {{0}}; + struct b_elm_sta_info sta_info = {{0}}; + + if (!nl_daemon_on) + return; + + AICWFDBG(LOGSTEER, MANAGER_STR"%s, "MAC_FMT"\n", __func__, MAC_ARG(mac)); + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* element header */ + hdr.id = AIC_ELM_STA_INFO_ID; + hdr.len = ELM_STA_INFO_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_STA_INFO_ID */ + memcpy(sta_info.mac, mac, 6); + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN); + + /* finish message */ + msg.type = AIC_NL_DEL_STA_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_send_new_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_intf intf = {{0}}; + struct b_elm_sta_info sta_info = {{0}}; + + if (!nl_daemon_on) + return; + + AICWFDBG(LOGSTEER, MANAGER_STR"%s, "MAC_FMT"\n", __func__, MAC_ARG(mac)); + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* element header */ + hdr.id = AIC_ELM_STA_INFO_ID; + hdr.len = ELM_STA_INFO_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_STA_INFO_ID */ + memcpy(sta_info.mac, mac, 6); + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN); + + /* finish message */ + msg.type = AIC_NL_NEW_STA_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_send_intf_rpt_msg(struct rwnx_vif *rwnx_vif) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_intf intf = {{0}}; + struct b_elm_intf_info intf_info = {0}; + + if (!nl_daemon_on) + return; + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + memcpy(intf.mac, rwnx_vif->ndev->dev_addr, 6); + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + memcpy(intf.name, rwnx_vif->ndev->name, 16); + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* element header */ + hdr.id = AIC_ELM_INTF_INFO_ID; + hdr.len = ELM_INTF_INFO_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_INFO_ID */ + intf_info.ch = freq_to_channel(rwnx_vif->ap.freq); + intf_info.tx_tp = 0; /* TBD */ + intf_info.rx_tp = 0; /* TBD */ + + intf_info.bss_info = 0; + intf_info.reg_class = (rwnx_vif->ap.band == 0) ? 81 : 128; + intf_info.phy_type = 7; + + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf_info, ELM_INTF_INFO_LEN); + + /* finish message */ + msg.type = AIC_NL_INTF_RPT_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_send_sta_rpt_msg(struct rwnx_vif *rwnx_vif, struct rwnx_sta *sta) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_intf intf = {{0}}; + struct b_elm_sta_info sta_info = {{0}}; + struct b_elm_sta_info_ext sta_info_ext = {{0}}; + + if (!nl_daemon_on) + return; + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + memcpy(intf.mac, rwnx_vif->ndev->dev_addr, 6); + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + memcpy(intf.name, rwnx_vif->ndev->name, 16); + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* element header */ + hdr.id = AIC_ELM_STA_INFO_ID; + hdr.len = ELM_STA_INFO_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_STA_INFO_ID */ + memcpy(sta_info.mac, sta->mac_addr, 6); + sta_info.rssi = sta->rssi; + sta_info.link_time = sta->link_time; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info, ELM_STA_INFO_LEN); + + /* element header */ + hdr.id = AIC_ELM_STA_INFO_EXT_ID; + hdr.len = ELM_STA_INFO_EXT_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_STA_INFO_EXT_ID */ + memcpy(sta_info_ext.mac, sta->mac_addr, 6); + sta_info_ext.supported_band = sta->support_band; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&sta_info_ext, ELM_STA_INFO_EXT_LEN); + + /* finish message */ + msg.type = AIC_NL_STA_RPT_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_send_frame_rpt_msg(struct rwnx_vif *rwnx_vif, u16_l frame_type, u8_l *sa, s8_l rssi) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_frame_info frame_info = {0}; + struct b_elm_intf intf = {{0}}; + + if (!nl_daemon_on) + return; + + //AICWFDBG(LOGSTEER, "[NETLINK] %s, sta: "MAC_FMT"\n", __func__, MAC_ARG(sa)); + + /* TBD */ + if (frame_type == WIFI_PROBEREQ && rssi <= LOW_RSSI_IGNORE) { + AICWFDBG(LOGSTEER, MANAGER_STR"WIFI_PROBEREQ <= %d, ignore\n", LOW_RSSI_IGNORE); + return; + } + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* element header */ + hdr.id = AIC_ELM_FRAME_INFO_ID; + hdr.len = ELM_FRAME_INFO_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_FRAME_INFO_ID */ + frame_info.frame_type = frame_type; + memcpy(frame_info.sa, sa, 6); + frame_info.rssi = rssi; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&frame_info, ELM_FRAME_INFO_LEN); + + /* finish message */ + msg.type = AIC_NL_FRAME_RPT_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_send_time_tick_msg(struct rwnx_vif *rwnx_vif) +{ + u32 msg_len = 0; + struct b_nl_message msg = {0}; + struct b_elm_header hdr = {0}; + struct b_elm_intf intf = {{0}}; + + if (!nl_daemon_on) + return; + + /* element header */ + hdr.id = AIC_ELM_INTF_ID; + hdr.len = ELM_INTF_LEN; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&hdr, ELM_HEADER_LEN); + + /* element: AIC_ELM_INTF_ID */ + intf.root = 0; /* TBD */ + intf.band = rwnx_vif->ap.band; + intf.ssid = rwnx_vif->rwnx_hw->iface_idx; + aicwf_netlink_set_msg(&msg, &msg_len, (void *)&intf, ELM_INTF_LEN); + + /* finish message */ + msg.type = AIC_NL_TIME_TICK_TYPE; + msg.len = msg_len; + + /* length += (type + len) */ + msg_len += 8; + aicwf_nl_send_msg((void *)&msg, msg_len); + + return; +} + +void aicwf_nl_hook(struct rwnx_vif *rwnx_vif, u8_l band, u8_l ssid) +{ + AICWFDBG(LOGSTEER, MANAGER_STR"%s band:%d, ssid:%d\n", __func__, band, ssid); + + nl_hook[band][ssid] = 1; + nl_rwnx_vif[band][ssid] = rwnx_vif; + + return; +} + +void aicwf_nl_hook_deinit(u8_l band, u8_l ssid) +{ + + AICWFDBG(LOGSTEER, MANAGER_STR"%s band:%d, ssid:%d\n", __func__, band, ssid); + + nl_hook[band][ssid] = 0; + nl_rwnx_vif[band][ssid] = NULL; + + return; +} + + +void aicwf_nl_init(void) +{ + if (nl_sock) { + AICWFDBG(LOGSTEER, MANAGER_STR"netlink already init.\n"); + return; + } + struct netlink_kernel_cfg cfg = { + .input = aicwf_nl_recv_msg, + }; + + nl_sock = netlink_kernel_create(&init_net, NL_AIC_PROTOCOL, &cfg); + if (!nl_sock) + AICWFDBG(LOGERROR, MANAGER_STR"create netlink falied.\n"); + + return; +} + +void aicwf_nl_deinit(void) +{ + if(nl_sock) + { + netlink_kernel_release(nl_sock); + nl_sock = NULL; + } + AICWFDBG(LOGSTEER, MANAGER_STR"[aicwf_nl_deinit] delete nl_sock netlink succeed.\n"); + + return; +} + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_manager.h b/drivers/aic8800/aic8800_fdrv/aicwf_manager.h new file mode 100644 index 0000000..36db12a --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_manager.h @@ -0,0 +1,146 @@ +#ifndef _AICWF_MANAGER_H_ +#define _AICWF_MANAGER_H_ + +#include "lmac_types.h" +#include "rwnx_defs.h" + +#define DRV_WLAN_MANAGER_VER "v1.0" + + +/* TBD */ +#define CONFIG_IFACE_NUMBER 1 + +#define NL_AIC_PROTOCOL_FRT_DRV 28 +#define NL_AIC_PROTOCOL_SEC_DRV 29 +#define NL_AIC_PROTOCOL NL_AIC_PROTOCOL_SEC_DRV + +#define NL_AIC_MANAGER_PID 5185 + +#define NL_MAX_MSG_SIZE 768 + +/* Netlink Message Type List */ +#define AIC_NL_DAEMON_ON_TYPE 1 +#define AIC_NL_DAEMON_OFF_TYPE 2 +#define AIC_NL_DAEMON_ALIVE_TYPE 3 +#define AIC_NL_DEL_STA_TYPE 4 +#define AIC_NL_NEW_STA_TYPE 5 +#define AIC_NL_INTF_RPT_TYPE 6 +#define AIC_NL_STA_RPT_TYPE 7 +#define AIC_NL_FRAME_RPT_TYPE 8 +#define AIC_NL_TIME_TICK_TYPE 9 +#define AIC_NL_PRIV_INFO_CMD_TYPE 10 +#ifdef CONFIG_BAND_STEERING +#define AIC_NL_B_STEER_CMD_TYPE 11 +#define AIC_NL_B_STEER_BLOCK_ADD_TYPE 12 +#define AIC_NL_B_STEER_BLOCK_DEL_TYPE 13 +#define AIC_NL_B_STEER_ROAM_TYPE 14 +#endif + +#define AIC_NL_GENERAL_CMD_TYPE 100 +#define AIC_NL_CUSTOMER_TYPE 101 +#define AIC_NL_CONFIG_UPDATE_TYPE 102 + +/* Element ID */ +#define AIC_ELM_INTF_ID 1 +#define AIC_ELM_INTF_INFO_ID 2 +#define AIC_ELM_FRAME_INFO_ID 3 +#define AIC_ELM_STA_INFO_ID 4 +#define AIC_ELM_ROAM_INFO_ID 5 +#define AIC_ELM_BUFFER_ID 6 +#define AIC_ELM_STA_INFO_EXT_ID 7 + +#define LOW_RSSI_IGNORE (-85) + +struct b_nl_message { + u32_l type; + u32_l len; + u8_l content[NL_MAX_MSG_SIZE]; +}; + +struct b_elm_header { + u8_l id; + u8_l len; +}; + +struct b_elm_intf { + u8_l mac[6]; + u8_l root; + u8_l band; + u8_l ssid; + s8_l name[16]; +}; + +struct b_elm_intf_info { + u16_l ch; + u8_l ch_clm; + u8_l ch_noise; + u32_l tx_tp; + u32_l rx_tp; + u32_l assoc_sta_num; + /* self neighbor report info */ + u32_l bss_info; + u8_l reg_class; + u8_l phy_type; +}; + +struct b_elm_frame_info { + u16_l frame_type; + u8_l sa[6]; + s8_l rssi; +}; + +struct b_elm_sta_info { + u8_l mac[6]; + s8_l rssi; + u32_l link_time; + u32_l tx_tp; /* kbits */ + u32_l rx_tp; /* kbits */ +}; + +struct b_elm_roam_info { + u8_l sta_mac[6]; /* station mac */ + u8_l bss_mac[6]; /* target bss mac */ + u16_l bss_ch; /* target bss channel */ + u8_l method; /* 0: 11V, 1: Deauth */ +}; + +struct b_elm_buffer { + u8_l buf[255]; +}; + +struct b_elm_sta_info_ext { + u8_l mac[6]; + u8_l supported_band; /* bit0:2g bit1:5g */ + u8_l empty[119]; /* for future use */ +}; + + +/* Element Size List */ +#define ELM_HEADER_LEN (sizeof(struct b_elm_header)) +#define ELM_INTF_LEN (sizeof(struct b_elm_intf)) +#define ELM_INTF_INFO_LEN (sizeof(struct b_elm_intf_info)) +#define ELM_FRAME_INFO_LEN (sizeof(struct b_elm_frame_info)) +#define ELM_STA_INFO_LEN (sizeof(struct b_elm_sta_info)) +#define ELM_ROAM_INFO_LEN (sizeof(struct b_elm_roam_info)) +#define ELM_BUFFER_LEN (sizeof(struct b_elm_buffer)) +#define ELM_STA_INFO_EXT_LEN (sizeof(struct b_elm_sta_info_ext)) + + + +void aicwf_nl_send_del_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_nl_send_new_sta_msg(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_nl_send_intf_rpt_msg(struct rwnx_vif *rwnx_vif); +void aicwf_nl_send_sta_rpt_msg(struct rwnx_vif *rwnx_vif, struct rwnx_sta *sta); +void aicwf_nl_send_frame_rpt_msg(struct rwnx_vif *rwnx_vif, u16_l frame_type, u8_l *sa, s8_l rssi); +void aicwf_nl_send_time_tick_msg(struct rwnx_vif *rwnx_vif); +void aicwf_nl_hook(struct rwnx_vif *rwnx_vif, u8_l band, u8_l iface_id); +void aicwf_nl_hook_deinit(u8_l band, u8_l ssid); +void aicwf_nl_init(void); +void aicwf_nl_deinit(void); +void aicwf_wlan_manager_recv_msg(struct b_nl_message *msg); +void aicwf_nl_recv_msg(struct sk_buff *skb); +void aicwf_nl_send_msg(void *msg, u32_l msg_len); + + +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c index c9f5a76..f8e79cc 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_sdio.c @@ -527,12 +527,7 @@ static void aicwf_sdio_bus_stop(struct device *dev) aicwf_sdio_pwrctl_timer(sdiodev, 0); if(timer_pending(&sdiodev->rwnx_hw->p2p_alive_timer)){ - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - ret = timer_delete(&sdiodev->rwnx_hw->p2p_alive_timer); - #else - ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer); - #endif - } + ret = del_timer(&sdiodev->rwnx_hw->p2p_alive_timer);} sdio_dbg("%s\n",__func__); if (sdiodev->pwrctl_tsk) { complete(&sdiodev->pwrctrl_trgg); @@ -1085,11 +1080,7 @@ void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration) spin_lock_bh(&sdiodev->pwrctl_lock); if (!duration) { if (timer_pending(&sdiodev->timer)) - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete_sync(&sdiodev->timer); - #else - del_timer_sync(&sdiodev->timer); - #endif + del_timer_sync(&sdiodev->timer); } else { sdiodev->active_duration = duration; timeout = msecs_to_jiffies(sdiodev->active_duration); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_steering.c b/drivers/aic8800/aic8800_fdrv/aicwf_steering.c new file mode 100644 index 0000000..d6d20ca --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_steering.c @@ -0,0 +1,217 @@ +/** + ****************************************************************************** + * + * Copyright (C) 2020 AIC semiconductor. + * + * @file aicwf_steering.c + * + * @brief band steering definitions + * + ****************************************************************************** + */ + +#include "aicwf_steering.h" +#include "rwnx_defs.h" + +#define MAC_FMT_B "%02x:%02x:%02x:%02x:%02x:%02x" +#define MAC_ARG_B(x) ((u8_l *)(x))[0], ((u8_l *)(x))[1], ((u8_l *)(x))[2], ((u8_l *)(x))[3], ((u8_l *)(x))[4], ((u8_l *)(x))[5] +#define STEEER_STR "[STEERING] USB " + +#ifdef CONFIG_BAND_STEERING + +static struct b_steer_block_entry *block_entry_lookup(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + u8_l i; + struct b_steer_block_entry *ent = NULL; + + for (i = 0; i < B_STEER_ENTRY_NUM; i++) { + ent = &(rwnx_vif->bsteerpriv.block_list[i]); + if (ent->used && (memcmp(ent->mac, mac, 6) == 0)) { + AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac)); + return ent; + } + } + + return NULL; +} + +void aicwf_band_steering_expire(struct rwnx_vif *rwnx_vif) +{ + u8_l i; + struct b_steer_block_entry *ent = NULL; + + if (rwnx_vif->bsteerpriv.inited == false) { + AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__); + return; + } + + spin_lock_bh(&(rwnx_vif->bsteerpriv.lock)); + + /* block entry */ + for (i = 0; i < B_STEER_ENTRY_NUM; i++) { + ent = &(rwnx_vif->bsteerpriv.block_list[i]); + if (!ent->used) + continue; + + if (ent->entry_expire) { + ent->entry_expire--; + if (ent->entry_expire == 0) + ent->used = 0; + } + } + + spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock)); + + return; +} + +s32_l aicwf_band_steering_block_chk(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + s32 ret = 0; + struct b_steer_block_entry *ent = NULL; + + if (rwnx_vif->bsteerpriv.inited == false) { + AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__); + return 0; + } + + spin_lock_bh(&(rwnx_vif->bsteerpriv.lock)); + + ent = block_entry_lookup(rwnx_vif, mac); + if (ent) + ret = 1; + + spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock)); + + return ret; +} + +void aicwf_band_steering_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + u8_l i; + struct b_steer_block_entry *ent = NULL; + + if (rwnx_vif->bsteerpriv.inited == false) { + AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__); + return; + } + + AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac)); + + spin_lock_bh(&(rwnx_vif->bsteerpriv.lock)); + + ent = block_entry_lookup(rwnx_vif, mac); + + /* already exist */ + if (ent) { + AICWFDBG(LOGSTEER, STEEER_STR"%s already exist\n", __func__); + ent->entry_expire = B_STEER_BLOCK_ENTRY_EXPIRE; + goto func_return; + } + + /* find an empty entry */ + for (i = 0; i < B_STEER_ENTRY_NUM; i++) { + if (!rwnx_vif->bsteerpriv.block_list[i].used) { + ent = &(rwnx_vif->bsteerpriv.block_list[i]); + break; + } + } + + /* add the entry */ + if (ent) { + AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac)); + ent->used = 1; + memcpy(ent->mac, mac, 6); + ent->entry_expire = B_STEER_BLOCK_ENTRY_EXPIRE; + } + +func_return: + spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock)); + + return; +} + +void aicwf_band_steering_block_entry_del(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + struct b_steer_block_entry *ent = NULL; + + if (rwnx_vif->bsteerpriv.inited == false) { + AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__); + return; + } + + AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac)); + + spin_lock_bh(&(rwnx_vif->bsteerpriv.lock)); + + ent = block_entry_lookup(rwnx_vif, mac); + if (ent) + ent->used = 0; + + spin_unlock_bh(&(rwnx_vif->bsteerpriv.lock)); + + return; +} + +void aicwf_band_steering_roam_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac) +{ + u8_l i; + struct b_steer_block_entry *ent = NULL; + + if (rwnx_vif->bsteerpriv.inited == false) { + AICWFDBG(LOGSTEER, STEEER_STR"%s bsteerpriv not inited\n", __func__); + return; + } + + AICWFDBG(LOGSTEER, STEEER_STR"%s "MAC_FMT_B"\n", __func__, MAC_ARG_B(mac)); + + spin_lock_bh(&rwnx_vif->bsteerpriv.lock); + + ent = block_entry_lookup(rwnx_vif, mac); + + /* already exist */ + if (ent) + goto func_return; + + /* find an empty entry */ + for (i = 0; i < B_STEER_ENTRY_NUM; i++) { + if (!rwnx_vif->bsteerpriv.block_list[i].used) { + ent = &(rwnx_vif->bsteerpriv.block_list[i]); + break; + } + } + + /* add the entry */ + if (ent) { + ent->used = 1; + memcpy(ent->mac, mac, 6); + ent->entry_expire = B_STEER_ROAM_BLOCK_ENTRY_EXPIRE; + } + +func_return: + spin_unlock_bh(&rwnx_vif->bsteerpriv.lock); + + return; +} + +void aicwf_band_steering_init(struct rwnx_vif *rwnx_vif) +{ + u8_l i; + + AICWFDBG(LOGSTEER, STEEER_STR"%s\n", __func__); + spin_lock_init(&rwnx_vif->bsteerpriv.lock); + rwnx_vif->bsteerpriv.inited = true; + + spin_lock_bh(&rwnx_vif->bsteerpriv.lock); + + /* block entry */ + for (i = 0; i < B_STEER_ENTRY_NUM; i++) + memset(&(rwnx_vif->bsteerpriv.block_list[i]), 0, sizeof(struct b_steer_block_entry)); + + spin_unlock_bh(&rwnx_vif->bsteerpriv.lock); + + return; +} + +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_steering.h b/drivers/aic8800/aic8800_fdrv/aicwf_steering.h new file mode 100644 index 0000000..b7c59ef --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/aicwf_steering.h @@ -0,0 +1,40 @@ +#ifndef _AICWF_STEERING_H_ +#define _AICWF_STEERING_H_ + +#include +#include "lmac_types.h" + +#ifdef CONFIG_BAND_STEERING + +#define B_STEER_ENTRY_NUM 64//32 + +#define B_STEER_BLOCK_ENTRY_EXPIRE 60 +#define B_STEER_ROAM_BLOCK_ENTRY_EXPIRE 5 +#define STEER_UPFATE_TIME 2000 + +struct rwnx_vif; + +struct b_steer_block_entry { + u8_l used; + u8_l mac[6]; + u32_l entry_expire; +}; + +struct b_steer_priv { + struct b_steer_block_entry block_list[B_STEER_ENTRY_NUM]; + spinlock_t lock; + bool inited; +}; + + +void aicwf_band_steering_expire(struct rwnx_vif *rwnx_vif); +s32_l aicwf_band_steering_block_chk(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_band_steering_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_band_steering_block_entry_del(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_band_steering_roam_block_entry_add(struct rwnx_vif *rwnx_vif, u8_l *mac); +void aicwf_band_steering_init(struct rwnx_vif *rwnx_vif); + +#endif + +#endif + diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c index 7b3084d..480fd07 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.c @@ -106,11 +106,7 @@ void tcp_ack_deinit(struct rwnx_hw *priv) drop_msg = NULL; write_seqlock_bh(&ack_m->ack_info[i].seqlock); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete(&ack_m->ack_info[i].timer); - #else - del_timer(&ack_m->ack_info[i].timer); - #endif + del_timer(&ack_m->ack_info[i].timer); drop_msg = ack_m->ack_info[i].msgbuf; ack_m->ack_info[i].msgbuf = NULL; write_sequnlock_bh(&ack_m->ack_info[i].seqlock); @@ -192,7 +188,7 @@ int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, case TCPOPT_WINDOW: if (*ptr < 15) *win_scale = (1 << (*ptr)); - printk("%d\n",*win_scale); + //printk("%d\n",*win_scale); break; default: drop = 2; @@ -379,11 +375,7 @@ int tcp_ack_handle(struct msg_buf *new_msgbuf, //printk("%lx \n",ack_info->msgbuf); drop_msg = ack_info->msgbuf; ack_info->msgbuf = NULL; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete(&ack_info->timer); - #else - del_timer(&ack_info->timer); - #endif + del_timer(&ack_info->timer); }else{ //printk("msgbuf is NULL \n"); } @@ -417,11 +409,7 @@ int tcp_ack_handle(struct msg_buf *new_msgbuf, atomic_read(&ack_m->max_drop_cnt)))) { ack_info->drop_cnt = 0; ack_info->in_send_msg = new_msgbuf; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete(&ack_info->timer); - #else - del_timer(&ack_info->timer); - #endif + del_timer(&ack_info->timer); } else { ret = 1; ack_info->msgbuf = new_msgbuf; @@ -454,7 +442,7 @@ int tcp_ack_handle_new(struct msg_buf *new_msgbuf, struct tcp_ack_msg *ack; int ret = 0; struct msg_buf *drop_msg = NULL; - struct msg_buf * send_msg = NULL; + //struct msg_buf * send_msg = NULL; //printk("",); write_seqlock_bh(&ack_info->seqlock); @@ -482,13 +470,9 @@ int tcp_ack_handle_new(struct msg_buf *new_msgbuf, (ack_info->drop_cnt >= atomic_read(&ack_m->max_drop_cnt)))){ ack_info->drop_cnt = 0; - send_msg = new_msgbuf; - ack_info->in_send_msg = send_msg; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete(&ack_info->timer); - #else - del_timer(&ack_info->timer); - #endif + //send_msg = new_msgbuf; + ack_info->in_send_msg = new_msgbuf; + del_timer(&ack_info->timer); }else{ ret = 1; ack_info->msgbuf = new_msgbuf; @@ -566,9 +550,6 @@ int filter_send_tcp_ack(struct rwnx_hw *priv, struct tcp_ack_info *ack_info; struct tcp_ack_manage *ack_m = &priv->ack_m; - if (plen > MAX_TCP_ACK) - return 0; - tcp_ack_update(ack_m); drop = tcp_check_ack(buf, &ack_msg, &win_scale); // printk("drop:%d win_scale:%d",drop,win_scale); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h index d872e63..542023f 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_tcp_ack.h @@ -27,26 +27,7 @@ struct msg_buf { //struct list_head list; struct sk_buff *skb; struct rwnx_vif *rwnx_vif; - /* data just tx cmd use,not include the head */ - /*void *data; - void *tran_data; - unsigned long pcie_addr; - u8 type; - u8 mode; - u16 len; - unsigned long timeout;*/ - - /*unsigned int fifo_id; - struct sprdwl_msg_list *msglist;*/ - - /*unsigned char buffer_type; - struct sprdwl_xmit_msg_list *xmit_msg_list; - unsigned char msg_type; - - unsigned long last_time; - u8 ctxt_id;*/ - }; struct tcp_ack_msg { diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c index 679ee83..b848421 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.c @@ -221,7 +221,7 @@ void aicwf_bus_deinit(struct device *dev) }else{ AICWFDBG(LOGINFO, "%s g_rwnx_plat->enabled is false\r\n", __func__); } - + #endif #ifdef AICWF_SDIO_SUPPORT sdiodev =bus_if->bus_priv.sdio; @@ -257,7 +257,7 @@ void aicwf_bus_deinit(struct device *dev) rwnx_cmd_mgr_deinit(&usb->cmd_mgr); #ifdef CONFIG_TX_TASKLET//AIDEN tasklet - tasklet_kill(&usb->xmit_tasklet); + tasklet_kill(&usb->xmit_tasklet); #endif AICWFDBG(LOGINFO, "%s Exit \n", __func__); @@ -329,7 +329,11 @@ static bool aicwf_another_ptk_1(struct rx_buff *buffer) u8 *read = buffer->read; u16 aggr_len = 0; - if(read == NULL || read >= buffer->end) { + if(read == NULL || read >= (buffer->end - 2)) { + return false; + } + + if(buffer->len < 2) { return false; } @@ -346,7 +350,7 @@ static bool aicwf_another_ptk(struct sk_buff *skb) u8 *data; u16 aggr_len = 0; - if (skb->data == NULL || skb->len == 0) { + if (skb->data == NULL || skb->len < 2) { return false; } data = skb->data; @@ -367,55 +371,55 @@ void rwnx_frame_parser(char* tag, char* data, unsigned long len); #ifdef CONFIG_RX_TASKLET int aicwf_tasklet_rxframes(struct aicwf_rx_priv *rx_priv) { + int ret = 0; + unsigned long flags = 0; + struct sk_buff *skb = NULL; /* Packet for event or data frames */ + u16 pkt_len = 0; + //struct sk_buff *skb_inblock = NULL; + u16 aggr_len = 0, adjust_len = 0; + u8 *data = NULL; + u8_l *msg = NULL; - int ret = 0; - unsigned long flags = 0; - struct sk_buff *skb = NULL; /* Packet for event or data frames */ - u16 pkt_len = 0; - //struct sk_buff *skb_inblock = NULL; - u16 aggr_len = 0, adjust_len = 0; - u8 *data = NULL; - u8_l *msg = NULL; - - while (1) { - //aicwf_usb_rx_submit_all_urb_(rx_priv->usbdev); - spin_lock_irqsave(&rx_priv->rxqlock, flags); - if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { - usb_info("no more rxdata\n"); - spin_unlock_irqrestore(&rx_priv->rxqlock,flags); - break; - } - skb = aicwf_frame_dequeue(&rx_priv->rxq); - spin_unlock_irqrestore(&rx_priv->rxqlock, flags); - if (skb == NULL) { - txrx_err("skb_error\r\n"); - break; - } - data = skb->data; - pkt_len = (*skb->data | (*(skb->data + 1) << 8)); - //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); + while (1) { + //aicwf_usb_rx_submit_all_urb_(rx_priv->usbdev); + spin_lock_irqsave(&rx_priv->rxqlock, flags); + if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { + usb_info("no more rxdata\n"); + spin_unlock_irqrestore(&rx_priv->rxqlock,flags); + break; + } + skb = aicwf_frame_dequeue(&rx_priv->rxq); + spin_unlock_irqrestore(&rx_priv->rxqlock, flags); + if (skb == NULL) { + txrx_err("skb_error\r\n"); + break; + } + data = skb->data; + pkt_len = (*skb->data | (*(skb->data + 1) << 8)); + //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); #ifndef CONFIG_USB_RX_REASSEMBLE - if (pkt_len > 1600) { - dev_kfree_skb(skb); - atomic_dec(&rx_priv->rx_cnt); - continue; - } + if (pkt_len > skb->len) { + AICWFDBG(LOGERROR, "%s pkt_len:%d skb->len:%d\r\n", __func__, pkt_len, skb->len); + dev_kfree_skb(skb); + atomic_dec(&rx_priv->rx_cnt); + continue; + } #endif - if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data + if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data #if 0 aggr_len = pkt_len + RX_HWHRD_LEN; if (aggr_len & (RX_ALIGNMENT - 1)) adjust_len = roundup(aggr_len, RX_ALIGNMENT); else adjust_len = aggr_len; - + skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_ATOMIC);//8 is for ccmp mic or wep icv if(skb_inblock == NULL){ txrx_err("no more space! skip!\n"); skb_pull(skb, adjust_len); continue; } - + skb_put(skb_inblock, aggr_len); memcpy(skb_inblock->data, data, aggr_len); #if 0//AIDEN @@ -425,14 +429,14 @@ int aicwf_tasklet_rxframes(struct aicwf_rx_priv *rx_priv) rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb, (void *)rx_priv); ///TODO: here need to add rx data process //skb_pull(skb, adjust_len); - } - else { // type : config - aggr_len = pkt_len; - if (aggr_len & (RX_ALIGNMENT - 1)) - adjust_len = roundup(aggr_len, RX_ALIGNMENT); - else - adjust_len = aggr_len; - + } + else { // type : config + aggr_len = pkt_len; + if (aggr_len & (RX_ALIGNMENT - 1)) + adjust_len = roundup(aggr_len, RX_ALIGNMENT); + else + adjust_len = aggr_len; + msg = kmalloc(aggr_len+4, GFP_ATOMIC); if(msg == NULL){ txrx_err("no more space for msg!\n"); @@ -442,22 +446,23 @@ int aicwf_tasklet_rxframes(struct aicwf_rx_priv *rx_priv) memcpy(msg, data, aggr_len + 4); if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); - + if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); skb_pull(skb, adjust_len+4); kfree(msg); dev_kfree_skb(skb); - } - - //dev_kfree_skb(skb); - atomic_dec(&rx_priv->rx_cnt); } - - return ret; + + //dev_kfree_skb(skb); + atomic_dec(&rx_priv->rx_cnt); } + + return ret; +} #endif +extern bool rx_urb_sched; int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) { #ifdef AICWF_SDIO_SUPPORT @@ -580,17 +585,17 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) pkt_len = (*data | (*(data + 1) << 8)); //printk("%s cnt:%d pkt_len:%d \r\n", __func__, cnt, pkt_len); #ifndef CONFIG_USB_RX_REASSEMBLE - if (pkt_len > 1600) { - AICWFDBG(LOGERROR, "%s pkt_len > 1600 \r\n", __func__); + if (pkt_len > buffer->len) { + AICWFDBG(LOGERROR, "%s pkt_len:%d buffer->len:%d\r\n", __func__, pkt_len, buffer->len); aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); atomic_dec(&rx_priv->rx_cnt); return -EBADE; } #endif - + if((data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data - aggr_len = pkt_len + RX_HWHRD_LEN; - + aggr_len = pkt_len + RX_HWHRD_LEN; + skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL); if (skb_inblock == NULL) { txrx_err("no more space! skip\n"); @@ -598,11 +603,12 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) atomic_dec(&rx_priv->rx_cnt); return -EBADE; } - + skb_put(skb_inblock, aggr_len); memcpy(skb_inblock->data, data, aggr_len); rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv); buffer->read = buffer->read + aggr_len; + buffer->len -= aggr_len; } else { // type : config aggr_len = pkt_len; @@ -618,21 +624,26 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) return -EBADE; } memcpy(msg, data, aggr_len + 4); - + if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); - + if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); - + if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); buffer->read = buffer->read + (adjust_len + 4); + buffer->len -= (adjust_len + 4); kfree(msg); } } aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); + if (rx_urb_sched) { + schedule_work(&rx_priv->usbdev->rx_urb_work); + rx_urb_sched = false; + } atomic_dec(&rx_priv->rx_cnt); } }else{ @@ -645,7 +656,7 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) } buffer = rxbuff_dequeue(&rx_priv->rxq); spin_unlock_irqrestore(&rx_priv->rxqlock, flags); - + if (buffer == NULL) { txrx_err("skb_error\r\n"); ASSERT_ERR(1); @@ -655,7 +666,8 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) pkt_len = (*data | (*(data + 1) << 8)); //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); #ifndef CONFIG_USB_RX_REASSEMBLE - if (pkt_len > 1600) { + if (pkt_len > buffer->len) { + AICWFDBG(LOGERROR, "%s pkt_len:%d buffer->len:%d\r\n", __func__, pkt_len, buffer->len); aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); atomic_dec(&rx_priv->rx_cnt); continue; @@ -669,7 +681,7 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) atomic_dec(&rx_priv->rx_cnt); continue; } - + skb_put(skb_inblock, pkt_len + RX_HWHRD_LEN); memcpy(skb_inblock->data, data, pkt_len + RX_HWHRD_LEN); rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv); @@ -680,7 +692,7 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) adjust_len = roundup(aggr_len, RX_ALIGNMENT); else adjust_len = aggr_len; - + msg = kmalloc(aggr_len+4, GFP_KERNEL); if(msg == NULL){ txrx_err("no more space for msg!\n"); @@ -688,169 +700,176 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv) return -EBADE; } memcpy(msg, data, aggr_len + 4); - + if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); - + if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); - + if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); - + kfree(msg); } - + aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock); + if (rx_urb_sched) { + schedule_work(&rx_priv->usbdev->rx_urb_work); + rx_urb_sched = false; + } atomic_dec(&rx_priv->rx_cnt); } } #else - if(aicwf_usb_rx_aggr){ - while (1) { - spin_lock_irqsave(&rx_priv->rxqlock, flags); - if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { - usb_info("no more rxdata\n"); - spin_unlock_irqrestore(&rx_priv->rxqlock,flags); - break; - } - skb = aicwf_frame_dequeue(&rx_priv->rxq); - spin_unlock_irqrestore(&rx_priv->rxqlock, flags); + if(aicwf_usb_rx_aggr){ + while (1) { + spin_lock_irqsave(&rx_priv->rxqlock, flags); + if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { + usb_info("no more rxdata\n"); + spin_unlock_irqrestore(&rx_priv->rxqlock,flags); + break; + } + skb = aicwf_frame_dequeue(&rx_priv->rxq); + spin_unlock_irqrestore(&rx_priv->rxqlock, flags); - if (skb == NULL) { - txrx_err("skb_error\r\n"); - ASSERT_ERR(1); - break; - } - while(aicwf_another_ptk(skb)) { - cnt++; - if (cnt > 30) { - //printk("%s err, break %d\n", __func__, cnt); - //break; - } - data = skb->data; - pkt_len = (*skb->data | (*(skb->data + 1) << 8)); - //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); + if (skb == NULL) { + txrx_err("skb_error\r\n"); + ASSERT_ERR(1); + break; + } + while(aicwf_another_ptk(skb)) { + cnt++; + if (cnt > 30) { + //printk("%s err, break %d\n", __func__, cnt); + //break; + } + data = skb->data; + pkt_len = (*skb->data | (*(skb->data + 1) << 8)); + //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); #ifndef CONFIG_USB_RX_REASSEMBLE - if (pkt_len > 1600) { - dev_kfree_skb(skb); - atomic_dec(&rx_priv->rx_cnt); - continue; - } + if (pkt_len > skb->len) { + AICWFDBG(LOGERROR, "%s pkt_len:%d skb->len:%d\r\n", __func__, pkt_len, skb->len); + //dev_kfree_skb(skb); + //atomic_dec(&rx_priv->rx_cnt); + //continue; + break; + } #endif - if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data - aggr_len = pkt_len + RX_HWHRD_LEN; - adjust_len = aggr_len; - skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv - if(skb_inblock == NULL){ - txrx_err("no more space! skip!\n"); - skb_pull(skb, adjust_len); - continue; - } + if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data + aggr_len = pkt_len + RX_HWHRD_LEN; + adjust_len = aggr_len; + skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv + if(skb_inblock == NULL){ + txrx_err("no more space! skip!\n"); + skb_pull(skb, adjust_len); + continue; + } - skb_put(skb_inblock, aggr_len); - memcpy(skb_inblock->data, data, aggr_len); - rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv); + skb_put(skb_inblock, aggr_len); + memcpy(skb_inblock->data, data, aggr_len); + rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv); - ///TODO: here need to add rx data process + ///TODO: here need to add rx data process - skb_pull(skb, adjust_len); + skb_pull(skb, adjust_len); - } - else { // type : config - aggr_len = pkt_len; - if (aggr_len & (RX_ALIGNMENT - 1)) - adjust_len = roundup(aggr_len, RX_ALIGNMENT); - else - adjust_len = aggr_len; + } + else { // type : config + aggr_len = pkt_len; + if (aggr_len & (RX_ALIGNMENT - 1)) + adjust_len = roundup(aggr_len, RX_ALIGNMENT); + else + adjust_len = aggr_len; - msg = kmalloc(aggr_len+4, GFP_KERNEL);//hdr(4)+config(aggrlen) - if(msg == NULL){ - txrx_err("no more space for msg!\n"); - aicwf_dev_skb_free(skb); - return -EBADE; - } - memcpy(msg, data, aggr_len + 4); + msg = kmalloc(aggr_len+4, GFP_KERNEL);//hdr(4)+config(aggrlen) + if(msg == NULL){ + txrx_err("no more space for msg!\n"); + aicwf_dev_skb_free(skb); + return -EBADE; + } + memcpy(msg, data, aggr_len + 4); - if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) - rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); + if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) + rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); - if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) - aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); + if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) + aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); - if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) - rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); + if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) + rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); - skb_pull(skb, adjust_len+4); - kfree(msg); + skb_pull(skb, adjust_len+4); + kfree(msg); - } - } - dev_kfree_skb(skb); - atomic_dec(&rx_priv->rx_cnt); - } - }else{ - while (1) { - spin_lock_irqsave(&rx_priv->rxqlock, flags); - if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { - usb_info("no more rxdata\n"); - spin_unlock_irqrestore(&rx_priv->rxqlock,flags); - break; - } - skb = aicwf_frame_dequeue(&rx_priv->rxq); - spin_unlock_irqrestore(&rx_priv->rxqlock, flags); + } + } + dev_kfree_skb(skb); + atomic_dec(&rx_priv->rx_cnt); + } + }else{ + while (1) { + spin_lock_irqsave(&rx_priv->rxqlock, flags); + if(aicwf_is_framequeue_empty(&rx_priv->rxq)) { + usb_info("no more rxdata\n"); + spin_unlock_irqrestore(&rx_priv->rxqlock,flags); + break; + } + skb = aicwf_frame_dequeue(&rx_priv->rxq); + spin_unlock_irqrestore(&rx_priv->rxqlock, flags); - if (skb == NULL) { - txrx_err("skb_error\r\n"); - ASSERT_ERR(1); - break; - } - data = skb->data; - pkt_len = (*skb->data | (*(skb->data + 1) << 8)); - //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); + if (skb == NULL) { + txrx_err("skb_error\r\n"); + ASSERT_ERR(1); + break; + } + data = skb->data; + pkt_len = (*skb->data | (*(skb->data + 1) << 8)); + //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); #ifndef CONFIG_USB_RX_REASSEMBLE - if (pkt_len > 1600) { - dev_kfree_skb(skb); - atomic_dec(&rx_priv->rx_cnt); - continue; - } + if (pkt_len > skb->len) { + AICWFDBG(LOGERROR, "%s pkt_len:%d skb->len:%d\r\n", __func__, pkt_len, skb->len); + dev_kfree_skb(skb); + atomic_dec(&rx_priv->rx_cnt); + continue; + } #endif - if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data - rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb, (void *)rx_priv); - } - else { // type : config - aggr_len = pkt_len; - if (aggr_len & (RX_ALIGNMENT - 1)) - adjust_len = roundup(aggr_len, RX_ALIGNMENT); - else - adjust_len = aggr_len; + if((skb->data[2] & USB_TYPE_CFG) != USB_TYPE_CFG) { // type : data + rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb, (void *)rx_priv); + } + else { // type : config + aggr_len = pkt_len; + if (aggr_len & (RX_ALIGNMENT - 1)) + adjust_len = roundup(aggr_len, RX_ALIGNMENT); + else + adjust_len = aggr_len; - msg = kmalloc(aggr_len+4, GFP_KERNEL); - if(msg == NULL){ - txrx_err("no more space for msg!\n"); - aicwf_dev_skb_free(skb); - return -EBADE; - } - memcpy(msg, data, aggr_len + 4); + msg = kmalloc(aggr_len+4, GFP_KERNEL); + if(msg == NULL){ + txrx_err("no more space for msg!\n"); + aicwf_dev_skb_free(skb); + return -EBADE; + } + memcpy(msg, data, aggr_len + 4); - if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) - rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); + if(((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP) && (rx_priv->usbdev->bus_if->state != (int)USB_DOWN_ST)) + rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4)); - if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) - aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); + if((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM) + aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4)); - if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) - rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); + if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_PRINT) + rwnx_rx_handle_print(rx_priv->usbdev->rwnx_hw, msg + 4, aggr_len); - skb_pull(skb, adjust_len+4); - kfree(msg); - dev_kfree_skb(skb); - } - atomic_dec(&rx_priv->rx_cnt); - } - } + skb_pull(skb, adjust_len+4); + kfree(msg); + dev_kfree_skb(skb); + } + atomic_dec(&rx_priv->rx_cnt); + } + } #endif return ret; @@ -887,7 +906,7 @@ int aicwf_process_msg_rxframes(struct aicwf_rx_priv *rx_priv) pkt_len = (*skb->data | (*(skb->data + 1) << 8)); //printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]); #if 0 //amsdu > 1600 - if (pkt_len > 1600) { + if (pkt_len > 1600) { dev_kfree_skb(skb); atomic_dec(&rx_priv->rx_cnt); continue; @@ -970,7 +989,7 @@ static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize for (i = 0; i < qsize; i++) { INIT_LIST_HEAD(&req->rxframe_list); list_add(&req->rxframe_list, q); - req->len = 0; + //req->len = 0; req++; } diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h index 29971f9..71c306b 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_txrxif.h @@ -23,7 +23,7 @@ #define DATA_BUF_MAX 2048 #define TXPKT_BLOCKSIZE 512 #define MAX_AGGR_TXPKT_LEN (1536*64) -#define CMD_TX_TIMEOUT 5000 +#define CMD_TX_TIMEOUT 2000 #define TX_ALIGNMENT 4 #ifdef CONFIG_USB_TX_AGGR @@ -152,6 +152,7 @@ struct aicwf_tx_priv { }; +#define DEFRAG_MAX_WAIT 40 //100 #ifdef AICWF_RX_REORDER #define MAX_REORD_RXFRAME 250 #define REORDER_UPDATE_TIME 500//50 @@ -178,13 +179,21 @@ struct reord_ctrl_info { }; struct recv_msdu { - struct sk_buff *pkt; - u8 tid; - u8 forward; - u16 seq_num; - uint len; - u8 *rx_data; - //for pending rx reorder list + struct sk_buff *pkt; + u8 tid; + u8 forward; + u16 seq_num; + //uint len; + u8 is_amsdu; + u8 is_ap_reord; + u8 ap_fwd_cnt; + u8 ap_resend_cnt; + u8 *rx_data; + struct sk_buff *first_fwd_skb; + struct sk_buff *last_fwd_skb; + struct sk_buff *first_resend_skb; + struct sk_buff *last_resend_skb; + //for pending rx reorder list struct list_head reord_pending_list; //for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue struct list_head rxframe_list; diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c index 45fefac..9b0a739 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.c @@ -15,6 +15,7 @@ #include "rwnx_defs.h" #include "usb_host.h" #include "rwnx_platform.h" +#include "rwnx_msg_tx.h" #ifdef CONFIG_GPIO_WAKEUP #ifdef CONFIG_PLATFORM_ROCKCHIP @@ -54,6 +55,8 @@ bool aicwf_usb_rx_aggr = true; bool aicwf_usb_rx_aggr = false; #endif atomic_t rx_urb_cnt; +bool rx_urb_sched = false; +u32 aicwf_usb_max_pkt_size = AICWF_USB_MAX_PKT_SIZE; void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state) { @@ -154,23 +157,23 @@ static void aicwf_usb_msg_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_u void rwnx_stop_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) { - u8 tid; - struct rwnx_txq *txq; - for(tid=0; tid<8; tid++) { - txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); - netif_stop_subqueue(txq->ndev, txq->ndev_idx); - } - } + u8 tid; + struct rwnx_txq *txq; + for(tid=0; tid<8; tid++) { + txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); + netif_stop_subqueue(txq->ndev, txq->ndev_idx); + } +} void rwnx_wake_sta_all_queues(struct rwnx_sta *sta, struct rwnx_hw *rwnx_hw) { - u8 tid; - struct rwnx_txq *txq; - for(tid=0; tid<8; tid++) { - txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); - netif_wake_subqueue(txq->ndev, txq->ndev_idx); - } - } + u8 tid; + struct rwnx_txq *txq; + for(tid=0; tid<8; tid++) { + txq = rwnx_txq_sta_get(sta, tid, rwnx_hw); + netif_wake_subqueue(txq->ndev, txq->ndev_idx); + } +} static void usb_txc_sta_flowctrl(struct aicwf_usb_buf *usb_buf, struct aic_usb_dev *usb_dev) { @@ -220,6 +223,7 @@ static void aicwf_usb_tx_complete(struct urb *urb) #ifdef CONFIG_USB_ALIGN_DATA if(usb_buf->usb_align_data) { kfree(usb_buf->usb_align_data); + usb_buf->usb_align_data = NULL; } #endif #ifndef CONFIG_USB_TX_AGGR @@ -256,68 +260,68 @@ void aicwf_usb_rx_submit_all_urb_(struct aic_usb_dev *usb_dev); #ifdef CONFIG_PREALLOC_RX_SKB static void aicwf_usb_rx_complete(struct urb *urb) - { - struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context; - struct aic_usb_dev *usb_dev = usb_buf->usbdev; - struct aicwf_rx_priv* rx_priv = usb_dev->rx_priv; - struct rx_buff *rx_buff = NULL; - unsigned long flags = 0; - - rx_buff = usb_buf->rx_buff; - usb_buf->rx_buff = NULL; - - atomic_dec(&rx_urb_cnt); - if(atomic_read(&rx_urb_cnt) < 10){ - AICWFDBG(LOGDEBUG, "%s %d \r\n", __func__, atomic_read(&rx_urb_cnt)); - //printk("%s %d \r\n", __func__, atomic_read(&rx_urb_cnt)); - } +{ + struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context; + struct aic_usb_dev *usb_dev = usb_buf->usbdev; + struct aicwf_rx_priv* rx_priv = usb_dev->rx_priv; + struct rx_buff *rx_buff = NULL; + unsigned long flags = 0; + + rx_buff = usb_buf->rx_buff; + usb_buf->rx_buff = NULL; + + atomic_dec(&rx_urb_cnt); + if(atomic_read(&rx_urb_cnt) < 10){ + AICWFDBG(LOGDEBUG, "%s %d \r\n", __func__, atomic_read(&rx_urb_cnt)); + //printk("%s %d \r\n", __func__, atomic_read(&rx_urb_cnt)); + } + + if(!usb_dev->rwnx_hw){ + aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); + aicwf_usb_rx_buf_put(usb_dev, usb_buf); + AICWFDBG(LOGERROR, "usb_dev->rwnx_hw is not ready \r\n"); + return; + } + + if (urb->actual_length > urb->transfer_buffer_length) { + aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); + aicwf_usb_rx_buf_put(usb_dev, usb_buf); + aicwf_usb_rx_submit_all_urb_(usb_dev); + return; + } + + if (urb->status != 0 || !urb->actual_length) { + aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); + aicwf_usb_rx_buf_put(usb_dev, usb_buf); + if(urb->status < 0){ + AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status); + + if(g_rwnx_plat->wait_disconnect_cb == false){ + g_rwnx_plat->wait_disconnect_cb = true; + if(atomic_read(&aicwf_deinit_atomic) > 0){ + atomic_set(&aicwf_deinit_atomic, 0); + down(&aicwf_deinit_sem); + AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__); + }else{ + g_rwnx_plat->wait_disconnect_cb = false; + } + } - if(!usb_dev->rwnx_hw){ - aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); - aicwf_usb_rx_buf_put(usb_dev, usb_buf); - AICWFDBG(LOGERROR, "usb_dev->rwnx_hw is not ready \r\n"); return; - } - - if (urb->actual_length > urb->transfer_buffer_length) { - aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); - aicwf_usb_rx_buf_put(usb_dev, usb_buf); + }else{ + //schedule_work(&usb_dev->rx_urb_work); aicwf_usb_rx_submit_all_urb_(usb_dev); return; } - - if (urb->status != 0 || !urb->actual_length) { - aicwf_prealloc_rxbuff_free(rx_buff, &rx_priv->rxbuff_lock); - aicwf_usb_rx_buf_put(usb_dev, usb_buf); - if(urb->status < 0){ - AICWFDBG(LOGDEBUG, "%s urb->status:%d \r\n", __func__, urb->status); - - if(g_rwnx_plat->wait_disconnect_cb == false){ - g_rwnx_plat->wait_disconnect_cb = true; - if(atomic_read(&aicwf_deinit_atomic) > 0){ - atomic_set(&aicwf_deinit_atomic, 0); - down(&aicwf_deinit_sem); - AICWFDBG(LOGINFO, "%s need to wait for disconnect callback \r\n", __func__); - }else{ - g_rwnx_plat->wait_disconnect_cb = false; - } - } - - return; - }else{ - //schedule_work(&usb_dev->rx_urb_work); - aicwf_usb_rx_submit_all_urb_(usb_dev); - return; - } - } - + } + if (usb_dev->state == USB_UP_ST) { spin_lock_irqsave(&rx_priv->rxqlock, flags); - if (aicwf_usb_rx_aggr) { - rx_buff->len = urb->actual_length; + //if (aicwf_usb_rx_aggr) { + rx_buff->len = urb->actual_length; //printk("%s rx_buff->len:%d \r\n", __func__, rx_buff->len); - } - + //} + if(!aicwf_rxbuff_enqueue(usb_dev->dev, &rx_priv->rxq, rx_buff)){ spin_unlock_irqrestore(&rx_priv->rxqlock, flags); usb_err("rx_priv->rxq is over flow!!!\n"); @@ -328,7 +332,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) } spin_unlock_irqrestore(&rx_priv->rxqlock, flags); atomic_inc(&rx_priv->rx_cnt); - + if(atomic_read(&rx_priv->rx_cnt) == 1){ complete(&rx_priv->usbdev->bus_if->busrx_trgg); } @@ -425,7 +429,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) reassemble_done = true; } } else { - if (frag_len == AICWF_USB_MAX_PKT_SIZE) { + if (frag_len == aicwf_usb_max_pkt_size) { reassemble_valid = true; } } @@ -470,7 +474,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) u32 pkt_len = skb->data[0] | (skb->data[1] << 8); if ((type & USB_TYPE_CFG) != USB_TYPE_CFG) { u32 pkt_total_len = pkt_len + RX_HWHRD_LEN; - if ((pkt_total_len > AICWF_USB_MAX_PKT_SIZE) && (skb->len == AICWF_USB_MAX_PKT_SIZE)) { + if ((pkt_total_len > aicwf_usb_max_pkt_size) && (skb->len == aicwf_usb_max_pkt_size)) { AICWFDBG(LOGINFO, "reassemble pkt, len=%u\n", pkt_total_len); struct sk_buff *reassemble_skb = __dev_alloc_skb(pkt_total_len, GFP_ATOMIC/*GFP_KERNEL*/); if (reassemble_skb) { @@ -479,7 +483,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) rx_priv->rx_reassemble_skb = reassemble_skb; rx_priv->rx_reassemble_total_len = pkt_total_len; rx_priv->rx_reassemble_cur_len = skb->len; - rx_priv->rx_reassemble_total_frags = ALIGN(pkt_total_len, AICWF_USB_MAX_PKT_SIZE) / AICWF_USB_MAX_PKT_SIZE; + rx_priv->rx_reassemble_total_frags = ALIGN(pkt_total_len, aicwf_usb_max_pkt_size) / aicwf_usb_max_pkt_size; rx_priv->rx_reassemble_cur_frags = 1; } else { usb_err("reassemble pkt alloc fail, len=%u\n", pkt_total_len); @@ -495,7 +499,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) } else { if (type == USB_TYPE_CFG_CMD_RSP) { u32 pkt_total_len = ALIGN((pkt_len + 4), 4); - if ((pkt_total_len > AICWF_USB_MAX_PKT_SIZE) && (skb->len == AICWF_USB_MAX_PKT_SIZE)) { + if ((pkt_total_len > aicwf_usb_max_pkt_size) && (skb->len == aicwf_usb_max_pkt_size)) { AICWFDBG(LOGINFO, "reassemble pkt, len=%u\n", pkt_total_len); struct sk_buff *reassemble_skb = __dev_alloc_skb(pkt_total_len, GFP_ATOMIC/*GFP_KERNEL*/); if (reassemble_skb) { @@ -504,7 +508,7 @@ static void aicwf_usb_rx_complete(struct urb *urb) rx_priv->rx_reassemble_skb = reassemble_skb; rx_priv->rx_reassemble_total_len = pkt_total_len; rx_priv->rx_reassemble_cur_len = skb->len; - rx_priv->rx_reassemble_total_frags = ALIGN(pkt_total_len, AICWF_USB_MAX_PKT_SIZE) / AICWF_USB_MAX_PKT_SIZE; + rx_priv->rx_reassemble_total_frags = ALIGN(pkt_total_len, aicwf_usb_max_pkt_size) / aicwf_usb_max_pkt_size; rx_priv->rx_reassemble_cur_frags = 1; } else { usb_err("reassemble pkt alloc fail, len=%u\n", pkt_total_len); @@ -751,9 +755,10 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, rx_buff = aicwf_prealloc_rxbuff_alloc(&usb_dev->rx_priv->rxbuff_lock); if (rx_buff == NULL) { AICWFDBG(LOGERROR, "failed to alloc rxbuff\r\n"); - aicwf_usb_rx_buf_put(usb_dev, usb_buf); - return -1; - } + aicwf_usb_rx_buf_put(usb_dev, usb_buf); + rx_urb_sched = true; + return -1; + } rx_buff->len = 0; rx_buff->start = rx_buff->data; rx_buff->read = rx_buff->start; @@ -801,9 +806,9 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, } if(aicwf_usb_rx_aggr){ - skb = __dev_alloc_skb(AICWF_USB_AGGR_MAX_PKT_SIZE, GFP_ATOMIC/*GFP_KERNEL*/); + skb = __dev_alloc_skb(AICWF_USB_AGGR_MAX_PKT_SIZE, GFP_ATOMIC/*GFP_KERNEL*/); } else { - skb = __dev_alloc_skb(AICWF_USB_MAX_PKT_SIZE, GFP_ATOMIC/*GFP_KERNEL*/); + skb = __dev_alloc_skb(aicwf_usb_max_pkt_size, GFP_ATOMIC/*GFP_KERNEL*/); } if (!skb) { aicwf_usb_rx_buf_put(usb_dev, usb_buf); @@ -821,7 +826,7 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_in_pipe, - skb->data, AICWF_USB_MAX_PKT_SIZE, aicwf_usb_rx_complete, usb_buf); + skb->data, aicwf_usb_max_pkt_size, aicwf_usb_rx_complete, usb_buf); } usb_buf->usbdev = usb_dev; @@ -836,10 +841,10 @@ static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev, aicwf_usb_rx_buf_put(usb_dev, usb_buf); msleep(100); - return -1; + return -1; }else{ - atomic_inc(&rx_urb_cnt); - } + atomic_inc(&rx_urb_cnt); + } return 0; } #endif @@ -857,7 +862,7 @@ static void aicwf_usb_rx_submit_all_urb(struct aic_usb_dev *usb_dev) while((usb_buf = aicwf_usb_rx_buf_get(usb_dev)) != NULL) { if (aicwf_usb_submit_rx_urb(usb_dev, usb_buf)) { AICWFDBG(LOGERROR, "sub rx fail\n"); - return; + return; #if 0 AICWFDBG(LOGERROR, "usb rx refill fail\n"); if (usb_dev->state != USB_UP_ST) @@ -1330,11 +1335,11 @@ int usb_busrx_thread(void *data) #ifdef CONFIG_TXRX_THREAD_PRIO if (busrx_thread_prio > 0) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) - sched_set_fifo_low(current); + sched_set_fifo_low(current); #else - struct sched_param param; - param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); - sched_setscheduler(current, SCHED_FIFO, ¶m); + struct sched_param param; + param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); + sched_setscheduler(current, SCHED_FIFO, ¶m); #endif } #endif @@ -1373,19 +1378,19 @@ int usb_msg_busrx_thread(void *data) struct aicwf_bus *bus_if = rx_priv->usbdev->bus_if; #ifdef CONFIG_TXRX_THREAD_PRIO - if (busrx_thread_prio > 0) { + if (busrx_thread_prio > 0) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)) - sched_set_fifo_low(current); + sched_set_fifo_low(current); #else - struct sched_param param; - param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); - sched_setscheduler(current, SCHED_FIFO, ¶m); + struct sched_param param; + param.sched_priority = (busrx_thread_prio < MAX_RT_PRIO)?busrx_thread_prio:(MAX_RT_PRIO-1); + sched_setscheduler(current, SCHED_FIFO, ¶m); #endif - } + } #endif - AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); - AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); - AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); + AICWFDBG(LOGINFO, "%s the policy of current thread is:%d\n", __func__, current->policy); + AICWFDBG(LOGINFO, "%s the rt_priority of current thread is:%d\n", __func__, current->rt_priority); + AICWFDBG(LOGINFO, "%s the current pid is:%d\n", __func__, current->pid); @@ -1504,7 +1509,7 @@ static void aicwf_usb_free_urb(struct list_head *q, spinlock_t *qlock) spin_lock_irqsave(qlock, flags); list_for_each_entry_safe(usb_buf, tmp, q, list) { - spin_unlock_irqrestore(qlock, flags); + spin_unlock_irqrestore(qlock, flags); if (!usb_buf->urb) { usb_err("bad usb_buf\n"); spin_lock_irqsave(qlock, flags); @@ -1605,7 +1610,7 @@ err: static int aicwf_usb_alloc_msg_rx_urb(struct aic_usb_dev *usb_dev) { int i; - + AICWFDBG(LOGINFO, "%s AICWF_USB_MSG_RX_URBS:%d \r\n", __func__, AICWF_USB_MSG_RX_URBS); for (i = 0; i < AICWF_USB_MSG_RX_URBS; i++) { @@ -1728,7 +1733,8 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb) u16 index = 0; bool need_cfm = false; #ifdef CONFIG_USB_ALIGN_DATA//AIDEN - int align; + u8 *buf_align; + int align; #endif if (usb_dev->state != USB_UP_ST) { @@ -1823,6 +1829,7 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb) #if defined CONFIG_USB_NO_TRANS_DMA_MAP #error "CONFIG_USB_NO_TRANS_DMA_MAP not supported" #endif +#if 0 usb_buf->usb_align_data = (u8*)kmalloc(sizeof(u8) * buf_len + align_param, GFP_ATOMIC); align = ((unsigned long)(usb_buf->usb_align_data)) & (align_param - 1); @@ -1830,6 +1837,21 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb) usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_out_pipe, usb_buf->usb_align_data + (align_param - align), buf_len, aicwf_usb_tx_complete, usb_buf); +#else + if (!IS_ALIGNED((unsigned long)buf, align_param)) { + usb_buf->usb_align_data = (u8*)kmalloc(sizeof(u8) * buf_len + align_param, GFP_ATOMIC); + if (usb_buf->usb_align_data) { + align = ((unsigned long)(usb_buf->usb_align_data)) & (align_param - 1); + buf_align = usb_buf->usb_align_data + (align_param - align); + memcpy(buf_align, buf, buf_len); + } + } else { + buf_align = buf; + } + + usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_out_pipe, + buf_align, buf_len, aicwf_usb_tx_complete, usb_buf); +#endif #else usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_out_pipe, buf, buf_len, aicwf_usb_tx_complete, usb_buf); @@ -1878,14 +1900,15 @@ static int aicwf_usb_bus_start(struct device *dev) aicwf_usb_state_change(usb_dev, USB_UP_ST); usb_dev->rx_prepare_ready = false; - aicwf_usb_rx_prepare(usb_dev); aicwf_usb_tx_prepare(usb_dev); #ifdef CONFIG_USB_MSG_IN_EP if(usb_dev->msg_in_pipe){ aicwf_usb_msg_rx_prepare(usb_dev); + } else { + aicwf_usb_rx_prepare(usb_dev); } #endif - if(!usb_dev->rx_prepare_ready){ + if(!usb_dev->msg_in_pipe && !usb_dev->rx_prepare_ready){ AICWFDBG(LOGERROR, "%s rx prepare fail\r\n", __func__); return -1; }else{ @@ -1933,7 +1956,7 @@ static void aicwf_usb_cancel_all_urbs_(struct aic_usb_dev *usb_dev) usb_kill_anchored_urbs(&usb_dev->rx_submitted); #ifdef CONFIG_USB_MSG_IN_EP if(usb_dev->msg_in_pipe){ - usb_kill_anchored_urbs(&usb_dev->msg_rx_submitted); + usb_kill_anchored_urbs(&usb_dev->msg_rx_submitted); } #endif } @@ -1956,8 +1979,8 @@ static void aicwf_usb_bus_stop(struct device *dev) return; if(g_rwnx_plat && g_rwnx_plat->wait_disconnect_cb == true){ - atomic_set(&aicwf_deinit_atomic, 1); - up(&aicwf_deinit_sem); + atomic_set(&aicwf_deinit_atomic, 1); + up(&aicwf_deinit_sem); } aicwf_usb_state_change(usb_dev, USB_DOWN_ST); //aicwf_usb_cancel_all_urbs(usb_dev);//AIDEN @@ -2117,18 +2140,23 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in /* Check interface number */ #ifdef CONFIG_USB_BT - if (usb->actconfig->desc.bNumInterfaces != 3) { + if (usb->actconfig->desc.bNumInterfaces != 3) #else - if (usb->actconfig->desc.bNumInterfaces != 1) { + if (usb->actconfig->desc.bNumInterfaces != 1) #endif + { AICWFDBG(LOGERROR, "Number of interfaces: %d not supported\n", usb->actconfig->desc.bNumInterfaces); if(usb_dev->chipid == PRODUCT_ID_AIC8800DC){ AICWFDBG(LOGERROR, "AIC8800DC change to AIC8800DW\n"); usb_dev->chipid = PRODUCT_ID_AIC8800DW; - }else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) { - AICWFDBG(LOGERROR, "AIC8800D80\n"); - } else { + } else if (usb_dev->chipid == PRODUCT_ID_AIC8800D81) { + AICWFDBG(LOGINFO, "AIC8800D80\n"); + } else if(usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || + usb_dev->chipid == PRODUCT_ID_AIC8800D89X2 || + usb_dev->chipid == PRODUCT_ID_AIC8800D81){ + //TODO + }else{ ret = -ENODEV; goto exit; } @@ -2193,17 +2221,33 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in } #endif #ifdef CONFIG_USB_MSG_IN_EP - if(usb_dev->chipid != PRODUCT_ID_AIC8801){ - if (usb_dev->msg_in_pipe == 0) { - AICWFDBG(LOGINFO, "No RX Msg (in) Bulk EP found\n"); - } + if(usb_dev->chipid != PRODUCT_ID_AIC8801){ + if (usb_dev->msg_in_pipe == 0) { + AICWFDBG(LOGINFO, "No RX Msg (in) Bulk EP found\n"); } + } #endif - if (usb->speed == USB_SPEED_HIGH){ - AICWFDBG(LOGINFO, "Aic high speed USB device detected\n"); - }else{ - AICWFDBG(LOGINFO, "Aic full speed USB device detected\n"); + switch (usb->speed) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + case USB_SPEED_SUPER_PLUS: + AICWFDBG(LOGINFO, "Aic super plus speed USB device detected\n"); + break; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) + case USB_SPEED_SUPER: + AICWFDBG(LOGINFO, "Aic super speed USB device detected\n"); + break; +#endif + case USB_SPEED_HIGH: + AICWFDBG(LOGINFO, "Aic high speed USB device detected\n"); + break; + case USB_SPEED_FULL: + AICWFDBG(LOGINFO, "Aic full speed USB device detected\n"); + break; + default: + AICWFDBG(LOGINFO, "Aic unknown speed(%d) USB device detected\n", usb->speed); + break; } exit: @@ -2293,7 +2337,9 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid usb_dev->chipid = PRODUCT_ID_AIC8801; AICWFDBG(LOGINFO, "%s USE AIC8801\r\n", __func__); return 0; - }else if(pid == USB_PRODUCT_ID_AIC8800DC){ + }else if(pid == USB_PRODUCT_ID_AIC8800DC || pid == USB_PRODUCT_ID_TENDA + || pid == USB_PRODUCT_ID_TENDA_U2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS1 + || pid == USB_PRODUCT_ID_AIC8800FC_CUS2 || pid == USB_PRODUCT_ID_AIC8800FC_CUS3){ usb_dev->chipid = PRODUCT_ID_AIC8800DC; AICWFDBG(LOGINFO, "%s USE AIC8800DC\r\n", __func__); return 0; @@ -2301,11 +2347,42 @@ static int aicwf_usb_chipmatch(struct aic_usb_dev *usb_dev, u16_l vid, u16_l pid usb_dev->chipid = PRODUCT_ID_AIC8800DW; AICWFDBG(LOGINFO, "%s USE AIC8800DW\r\n", __func__); return 0; - }else if(pid == USB_PRODUCT_ID_AIC8800D81 || vid == USB_VENDOR_ID_TP || pid == USB_PRODUCT_ID_AIC8800D83 - || vid == USB_VENDOR_ID_TENDA || pid == USB_PRODUCT_ID_AIC8800D84 || pid == USB_PRODUCT_ID_AIC8800D85){ + }else if(pid == USB_PRODUCT_ID_AIC8800D81 || pid == USB_PRODUCT_ID_AIC8800D41 + || pid == USB_PRODUCT_ID_TENDA_U11 || pid == USB_PRODUCT_ID_TENDA_U11_PRO + || pid == USB_PRODUCT_ID_AIC8800M80_CUS1 || pid == USB_PRODUCT_ID_AIC8800M80_CUS2 + || pid == USB_PRODUCT_ID_AIC8800M80_CUS3 || pid == USB_PRODUCT_ID_AIC8800M80_CUS4 + || pid == USB_PRODUCT_ID_AIC8800M80_CUS5 || pid == USB_PRODUCT_ID_AIC8800M80_CUS6){ usb_dev->chipid = PRODUCT_ID_AIC8800D81; aicwf_usb_rx_aggr = true; - AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__); + AICWFDBG(LOGINFO, "%s USE AIC8800D81\r\n", __func__); + return 0; + }else if(pid == USB_PRODUCT_ID_AIC8800D81X2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D81X2; + aicwf_usb_max_pkt_size = AICWF_USB_MAX_AMSDU_PKT_SIZE; + if (usb_dev->udev->speed <= USB_SPEED_HIGH) { + aicwf_usb_rx_aggr = true; + } else { + #ifdef CONFIG_PLATFORM_HI + aicwf_usb_rx_aggr = true; + #else + aicwf_usb_rx_aggr = false; + #endif + } + AICWFDBG(LOGINFO, "%s USE AIC8800D81X2\r\n", __func__); + return 0; + }else if(pid == USB_PRODUCT_ID_AIC8800D89X2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D89X2; + aicwf_usb_max_pkt_size = AICWF_USB_MAX_AMSDU_PKT_SIZE; + if (usb_dev->udev->speed <= USB_SPEED_HIGH) { + aicwf_usb_rx_aggr = true; + } else { + #ifdef CONFIG_PLATFORM_HI + aicwf_usb_rx_aggr = true; + #else + aicwf_usb_rx_aggr = false; + #endif + } + AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); return 0; }else{ return -1; @@ -2326,7 +2403,7 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i #endif usb_dev = kzalloc(sizeof(struct aic_usb_dev), GFP_ATOMIC); - + AICWFDBG(LOGDEBUG, "%s usb_dev:%d usb_tx_buf:%d usb_rx_buf:%d\r\n", __func__, (int)sizeof(struct aic_usb_dev), @@ -2361,7 +2438,7 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i memset(usb_dev->usb_tx_buf, 0, (int)(sizeof(struct aicwf_usb_buf) * AICWF_USB_TX_URBS)); - + memset(usb_dev->usb_rx_buf, 0, (int)(sizeof(struct aicwf_usb_buf) * AICWF_USB_RX_URBS)); @@ -2370,9 +2447,12 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i usb_dev->udev = usb; usb_dev->dev = &usb->dev; usb_set_intfdata(intf, usb_dev); - + + usb_dev->vid = id->idVendor; + usb_dev->pid = id->idProduct; + ret = aicwf_usb_chipmatch(usb_dev, id->idVendor, id->idProduct); - + if (ret < 0) { AICWFDBG(LOGERROR, "%s pid:0x%04X vid:0x%04X unsupport\n", __func__, id->idVendor, id->idProduct); @@ -2442,6 +2522,9 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i AICWFDBG(LOGERROR, "aicwf_rwnx_usb_platform_init err %d\n", ret); goto out_free_bus; } + if(usb_dev->msg_in_pipe){ + aicwf_usb_rx_prepare(usb_dev); + } aicwf_hostif_ready(); #ifdef CONFIG_GPIO_WAKEUP @@ -2468,7 +2551,7 @@ static void aicwf_usb_disconnect(struct usb_interface *intf) { struct aic_usb_dev *usb_dev = (struct aic_usb_dev *) usb_get_intfdata(intf); - AICWFDBG(LOGINFO, "%s Enter\r\n", __func__); + AICWFDBG(LOGINFO, "%s Enter\r\n", __func__); if(g_rwnx_plat->wait_disconnect_cb == false){ atomic_set(&aicwf_deinit_atomic, 0); @@ -2505,59 +2588,53 @@ static void aicwf_usb_disconnect(struct usb_interface *intf) static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state) { struct aic_usb_dev *usb_dev = - (struct aic_usb_dev *) usb_get_intfdata(intf); -#ifdef CONFIG_GPIO_WAKEUP - struct rwnx_vif *rwnx_vif, *tmp; - //unsigned long irqflags; -#endif - - printk("%s enter\r\n", __func__); - -#ifdef CONFIG_GPIO_WAKEUP -// spin_lock_irqsave(&irq_lock, irqflags); -// rwnx_enable_hostwake_irq(); -// spin_unlock_irqrestore(&irq_lock, irqflags); - atomic_inc(&irq_count); - - list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { - if (rwnx_vif->ndev) - netif_device_detach(rwnx_vif->ndev); - } -#endif - - aicwf_usb_state_change(usb_dev, USB_SLEEP_ST); + (struct aic_usb_dev *) usb_get_intfdata(intf); + struct rwnx_vif *rwnx_vif, *tmp; + + AICWFDBG(LOGINFO, "%s enter\r\n", __func__); +#ifdef CONFIG_WOWLAN + rwnx_send_dummy_reboot(usb_dev->rwnx_hw); +#endif + list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { + if (rwnx_vif->ndev){ + netif_tx_stop_all_queues(rwnx_vif->ndev); + mdelay(1000); + } + } + aicwf_usb_state_change(usb_dev, USB_SLEEP_ST); aicwf_bus_stop(usb_dev->bus_if); + list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { + if (rwnx_vif->ndev) + netif_device_detach(rwnx_vif->ndev); + } - return 0; +return 0; } static int aicwf_usb_resume(struct usb_interface *intf) { struct aic_usb_dev *usb_dev = - (struct aic_usb_dev *) usb_get_intfdata(intf); -#ifdef CONFIG_GPIO_WAKEUP - struct rwnx_vif *rwnx_vif, *tmp; -// unsigned long irqflags; -#endif - printk("%s enter\r\n", __func__); + (struct aic_usb_dev *) usb_get_intfdata(intf); + struct rwnx_vif *rwnx_vif, *tmp; + AICWFDBG(LOGINFO, "%s enter\r\n", __func__); + list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { + if (rwnx_vif->ndev) + netif_device_attach(rwnx_vif->ndev); + } -#ifdef CONFIG_GPIO_WAKEUP -// spin_lock_irqsave(&irq_lock, irqflags); -// rwnx_disable_hostwake_irq(); -// spin_unlock_irqrestore(&irq_lock, irqflags); - atomic_dec(&irq_count); + if (usb_dev->state != USB_UP_ST){ + aicwf_bus_start(usb_dev->bus_if); + } - list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { - if (rwnx_vif->ndev) - netif_device_attach(rwnx_vif->ndev); + list_for_each_entry_safe(rwnx_vif, tmp, &usb_dev->rwnx_hw->vifs, list) { + if (rwnx_vif->ndev){ + netif_tx_wake_all_queues(rwnx_vif->ndev); + } + } + if(usb_dev->msg_in_pipe){ + aicwf_usb_rx_prepare(usb_dev); } -#endif - - if (usb_dev->state == USB_UP_ST) - return 0; - - aicwf_bus_start(usb_dev->bus_if); return 0; } @@ -2575,15 +2652,21 @@ static struct usb_device_id aicwf_usb_id_table[] = { {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D41, 0xff, 0xff, 0xff)}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DC, 0xff, 0xff, 0xff)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800DW)}, - {USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC8800D83)}, - {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81)}, - {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D83)}, - {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D84)}, - {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D85)}, - {USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_TP)}, - {USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_MERCURY)}, - {USB_DEVICE(USB_VENDOR_ID_TP, USB_PRODUCT_ID_FAST)}, + {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D81X2, 0xff, 0xff, 0xff)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800D89X2)}, {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA)}, + {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U2)}, + {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11)}, + {USB_DEVICE(USB_VENDOR_ID_TENDA, USB_PRODUCT_ID_TENDA_U11_PRO)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS1)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS2)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800FC_CUS3)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS1)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS2)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS3)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS4)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS5)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_PRODUCT_ID_AIC8800M80_CUS6)}, #endif {} }; @@ -2619,7 +2702,7 @@ void aicwf_usb_exit(void) { int retry = 5; AICWFDBG(LOGINFO, "%s Enter\r\n", __func__); - + AICWFDBG(LOGDEBUG, "%s in_interrupt:%d in_softirq:%d in_atomic:%d\r\n", __func__, (int)in_interrupt(), (int)in_softirq(), (int)in_atomic()); do{ @@ -2631,7 +2714,7 @@ void aicwf_usb_exit(void) break; } }while(atomic_read(&aicwf_deinit_atomic) == 0); - + atomic_set(&aicwf_deinit_atomic, 0); if(down_timeout(&aicwf_deinit_sem, msecs_to_jiffies(SEM_TIMOUT)) != 0){ AICWFDBG(LOGERROR, "%s semaphore waiting timeout\r\n", __func__); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h index e8e3191..49f7355 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_usb.h +++ b/drivers/aic8800/aic8800_fdrv/aicwf_usb.h @@ -17,38 +17,46 @@ /* USB Device ID */ #define USB_VENDOR_ID_AIC 0xA69C #define USB_VENDOR_ID_AIC_V2 0x368B -#define USB_VENDOR_ID_TP 0x2357 #define USB_VENDOR_ID_TENDA 0x2604 -#define USB_PRODUCT_ID_TP 0x014e -#define USB_PRODUCT_ID_MERCURY 0x014b -#define USB_PRODUCT_ID_FAST 0x014f - -#define USB_PRODUCT_ID_TENDA 0x001f - #ifndef CONFIG_USB_BT -#define USB_PRODUCT_ID_AIC8800 0x8800 -#define USB_PRODUCT_ID_AIC8801 0x8801 -#define USB_PRODUCT_ID_AIC8800DC 0x88dc -#define USB_PRODUCT_ID_AIC8800DW 0x88dd -#define USB_PRODUCT_ID_AIC8800D81 0x8d81 +#define USB_PRODUCT_ID_AIC8800 0x8800 +#define USB_PRODUCT_ID_AIC8801 0x8801 +#define USB_PRODUCT_ID_AIC8800DC 0x88dc +#define USB_PRODUCT_ID_AIC8800DW 0x88dd +#define USB_PRODUCT_ID_AIC8800D81 0x8d81 +#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91 +#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99 #else -#define USB_PRODUCT_ID_AIC8801 0x8801 -#define USB_PRODUCT_ID_AIC8800DC 0x88dc -#define USB_PRODUCT_ID_AIC8800DW 0x88dd -#define USB_PRODUCT_ID_AIC8800D81 0x8d81 -#define USB_PRODUCT_ID_AIC8800D41 0x8d41 -#define USB_PRODUCT_ID_AIC8800D83 0x8d83 -#define USB_PRODUCT_ID_AIC8800D84 0x8d84 -#define USB_PRODUCT_ID_AIC8800D85 0x8d85 - +#define USB_PRODUCT_ID_AIC8801 0x8801 +#define USB_PRODUCT_ID_AIC8800DC 0x88dc +#define USB_PRODUCT_ID_AIC8800DW 0x88dd +#define USB_PRODUCT_ID_AIC8800D81 0x8d81 +#define USB_PRODUCT_ID_AIC8800D41 0x8d41 +#define USB_PRODUCT_ID_AIC8800D81X2 0x8d91 +#define USB_PRODUCT_ID_AIC8800D89X2 0x8d99 +#define USB_PRODUCT_ID_TENDA 0x0013 +#define USB_PRODUCT_ID_TENDA_U2 0x0014 +#define USB_PRODUCT_ID_TENDA_U11 0x001f +#define USB_PRODUCT_ID_TENDA_U11_PRO 0x0020 +#define USB_PRODUCT_ID_AIC8800FC_CUS1 0x88df +#define USB_PRODUCT_ID_AIC8800FC_CUS2 0x88E0 +#define USB_PRODUCT_ID_AIC8800FC_CUS3 0x88E1 +#define USB_PRODUCT_ID_AIC8800M80_CUS1 0x8D83 +#define USB_PRODUCT_ID_AIC8800M80_CUS2 0x8D85 +#define USB_PRODUCT_ID_AIC8800M80_CUS3 0x8D86 +#define USB_PRODUCT_ID_AIC8800M80_CUS4 0x8D89 +#define USB_PRODUCT_ID_AIC8800M80_CUS5 0x8D8A +#define USB_PRODUCT_ID_AIC8800M80_CUS6 0x8D8C #endif enum AICWF_IC{ PRODUCT_ID_AIC8801 = 0, PRODUCT_ID_AIC8800DC, PRODUCT_ID_AIC8800DW, - PRODUCT_ID_AIC8800D81 + PRODUCT_ID_AIC8800D81, + PRODUCT_ID_AIC8800D81X2, + PRODUCT_ID_AIC8800D89X2 }; @@ -71,6 +79,7 @@ enum AICWF_IC{ #endif #define AICWF_USB_MSG_MAX_PKT_SIZE (2048) #define AICWF_USB_MAX_PKT_SIZE (2048) +#define AICWF_USB_MAX_AMSDU_PKT_SIZE (2048*6) #define AICWF_USB_FC_PERSTA_HIGH_WATER 64 #define AICWF_USB_FC_PERSTA_LOW_WATER 16 @@ -183,6 +192,8 @@ struct aic_usb_dev { #endif u16 chipid; bool tbusy; + u16_l vid; + u16_l pid; }; extern void aicwf_usb_exit(void); diff --git a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c index bc0643d..d97a82f 100644 --- a/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c +++ b/drivers/aic8800/aic8800_fdrv/aicwf_wext_linux.c @@ -970,6 +970,26 @@ static int aicwf_set_scan(struct net_device *dev, struct iw_request_info *a, } } +#if WIRELESS_EXT >= 17 + if (wrqu->data.length == sizeof(struct iw_scan_req)) { + struct iw_scan_req *req = (struct iw_scan_req *)extra; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + int len = min((int)req->essid_len, 32); + request->ssids = kmalloc(sizeof(struct cfg80211_ssid), GFP_KERNEL); + if(!request->ssids){ + AICWFDBG(LOGERROR, "%s Failied to alloc memory for ssids", __func__); + return -ENOMEM; + } + memset(request->ssids, 0, sizeof(struct cfg80211_ssid)); + memcpy(request->ssids[0].ssid, req->essid, len); + request->ssids[0].ssid_len = len; + request->n_ssids = 1; + AICWFDBG(LOGDEBUG,"IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len); + } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) + AICWFDBG(LOGDEBUG,"aic_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n"); + } +#endif if ((ret = rwnx_send_scanu_req(rwnx_hw, rwnx_vif, request))){ return ret; } @@ -980,7 +1000,6 @@ static int aicwf_set_scan(struct net_device *dev, struct iw_request_info *a, if (!wait_for_completion_killable_timeout(&rwnx_hw->wext_scan_com, wext_scan_timeout)) { AICWFDBG(LOGERROR, "%s WEXT scan timeout", __func__); } - return 0; } diff --git a/drivers/aic8800/aic8800_fdrv/lmac_mac.h b/drivers/aic8800/aic8800_fdrv/lmac_mac.h index 9851210..1d90007 100644 --- a/drivers/aic8800/aic8800_fdrv/lmac_mac.h +++ b/drivers/aic8800/aic8800_fdrv/lmac_mac.h @@ -472,6 +472,7 @@ enum mac_connection_flags #define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x01 #define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x02 #define IEEE80211_HE_PHY_CAP2_DOPPLER_RX 0x20 +#define IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ 0x04 #define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x08 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x18 #define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00 diff --git a/drivers/aic8800/aic8800_fdrv/lmac_msg.h b/drivers/aic8800/aic8800_fdrv/lmac_msg.h index 9dbc1ba..b0b51df 100644 --- a/drivers/aic8800/aic8800_fdrv/lmac_msg.h +++ b/drivers/aic8800/aic8800_fdrv/lmac_msg.h @@ -402,6 +402,17 @@ enum mm_msg_tag MM_SET_TXPWR_LVL_ADJ_REQ, MM_SET_TXPWR_LVL_ADJ_CFM, + MM_RADAR_DETECT_IND, + + MM_SET_APF_PROG_REQ, + MM_SET_APF_PROG_CFM, + + MM_GET_APF_PROG_REQ, + MM_GET_APF_PROG_CFM, + + MM_SET_TXPWR_PER_STA_REQ, + MM_SET_TXPWR_PER_STA_CFM, + /// MAX number of messages MM_MAX, }; @@ -1264,6 +1275,17 @@ struct mm_set_rf_config_req u32_l data[64]; }; +typedef struct +{ + u32_l magic_num; /*“GWCR” or ’SWCR”*/ + u32_l info_flag; + u32_l calib_flag; + u32_l reserved0; + u32_l res_data[536/sizeof(u32_l)]; +}wf_rf_calib_res_drv_t; + +#define DRIVER_GET_WIFI_CALRES_MAGIC_NUM 0x52435747 +#define DRIVER_SET_WIFI_CALRES_MAGIC_NUM 0x52435753 struct mm_set_rf_calib_req { @@ -1277,6 +1299,20 @@ struct mm_set_rf_calib_req }; +struct mm_set_rf_calib_req_v2 +{ + u32_l cal_cfg_24g; + u32_l cal_cfg_5g; + u32_l param_alpha; + u32_l bt_calib_en; + u32_l bt_calib_param; + u8_l xtal_cap; + u8_l xtal_cap_fine; + u8_l reserved0[2]; + wf_rf_calib_res_drv_t cal_res; + +}; + struct mm_set_rf_calib_cfm { u32_l rxgain_24g_addr; @@ -1285,6 +1321,15 @@ struct mm_set_rf_calib_cfm u32_l txgain_5g_addr; }; +struct mm_set_rf_calib_cfm_v2 +{ + u32_l rxgain_24g_addr; + u32_l rxgain_5g_addr; + u32_l txgain_24g_addr; + u32_l txgain_5g_addr; + wf_rf_calib_res_drv_t cal_res; +}; + struct mm_get_mac_addr_req { u32_l get; @@ -1304,7 +1349,13 @@ struct mm_get_sta_info_cfm { u32_l rate_info; u32_l txfailed; - u8 rssi; + u8 rssi; + u8 reserved[3]; + u32_l chan_time; + u32_l chan_busy_time; + u32_l ack_fail_stat; + u32_l ack_succ_stat; + u32_l chan_tx_busy_time; }; typedef struct @@ -1340,6 +1391,20 @@ typedef struct s8_l pwrlvl_11ax_5g[12]; } txpwr_lvl_conf_v3_t; +typedef struct +{ + u8_l enable; + s8_l pwrlvl_11b_11ag_2g4[12]; + s8_l pwrlvl_11n_11ac_2g4[10]; + s8_l pwrlvl_11ax_2g4[12]; + s8_l pwrlvl_11a_5g[8]; + s8_l pwrlvl_11n_11ac_5g[10]; + s8_l pwrlvl_11ax_5g[12]; + s8_l pwrlvl_11a_6g[8]; + s8_l pwrlvl_11n_11ac_6g[10]; + s8_l pwrlvl_11ax_6g[12]; +} txpwr_lvl_conf_v4_t; + typedef struct { u8_l enable; @@ -1353,6 +1418,7 @@ struct mm_set_txpwr_lvl_req txpwr_lvl_conf_t txpwr_lvl; txpwr_lvl_conf_v2_t txpwr_lvl_v2; txpwr_lvl_conf_v3_t txpwr_lvl_v3; + txpwr_lvl_conf_v4_t txpwr_lvl_v4; }; }; @@ -1363,8 +1429,10 @@ struct mm_set_txpwr_lvl_adj_req typedef struct { - u8_l loss_enable; - u8_l loss_value; + u8_l loss_enable_2g4; + s8_l loss_value_2g4; + u8_l loss_enable_5g; + s8_l loss_value_5g; } txpwr_loss_conf_t; typedef struct @@ -1424,16 +1492,58 @@ typedef struct typedef struct { - int8_t enable; - int8_t pwrofst2x_tbl_2g4[3][3]; - int8_t pwrofst2x_tbl_5g[3][6]; + u8_l enable; + s8_l pwrofst2x_tbl_2g4[3][3]; + s8_l pwrofst2x_tbl_5g[3][6]; } txpwr_ofst2x_conf_t; +/* + * pwrofst2x_v2_tbl_2g4_ant0/1[3][3]: + * +---------------+----------+---------------+--------------+ + * | ChGrp\RateTyp | DSSS | OFDM_HIGHRATE | OFDM_LOWRATE | + * +---------------+----------+---------------+--------------+ + * | CH_1_4 | [0][0] | [0][1] | Reserved | + * +---------------+----------+---------------+--------------+ + * | CH_5_9 | [1][0] | [1][1] | Reserved | + * +---------------+----------+---------------+--------------+ + * | CH_10_13 | [2][0] | [2][1] | Reserved | + * +---------------+----------+---------------+--------------+ + * pwrofst2x_v2_tbl_5g_ant0/1[6][3]: + * +-----------------+---------------+--------------+--------------+ + * | ChGrp\RateTyp | OFDM_HIGHRATE | OFDM_LOWRATE | OFDM_MIDRATE | + * +-----------------+---------------+--------------+--------------+ + * | CH_42(36~50) | [0][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + * | CH_58(51~64) | [1][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + * | CH_106(98~114) | [2][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + * | CH_122(115~130) | [3][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + * | CH_138(131~146) | [4][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + * | CH_155(147~166) | [5][0] | Reserved | Reserved | + * +-----------------+---------------+--------------+--------------+ + */ + +typedef struct +{ + u8_l enable; + u8_l pwrofst_flags; + s8_l pwrofst2x_tbl_2g4_ant0[3][3]; + s8_l pwrofst2x_tbl_2g4_ant1[3][3]; + s8_l pwrofst2x_tbl_5g_ant0[6][3]; + s8_l pwrofst2x_tbl_5g_ant1[6][3]; + s8_l pwrofst2x_tbl_6g_ant0[15]; + s8_l pwrofst2x_tbl_6g_ant1[15]; +} txpwr_ofst2x_conf_v2_t; + struct mm_set_txpwr_ofst_req { union { txpwr_ofst_conf_t txpwr_ofst; txpwr_ofst2x_conf_t txpwr_ofst2x; + txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; }; }; @@ -1978,8 +2088,26 @@ enum vendor_hwconfig_tag{ AP_PS_LEVEL_SET_REQ, CUSTOMIZED_FREQ_REQ, WAKEUP_INFO_REQ, + KEEPALIVE_PKT_REQ, }; +enum vendor_hwconfig_tag_x2{ + ACS_TXOP_REQ_X2 = 0, + CHANNEL_ACCESS_REQ_X2, + MAC_TIMESCALE_REQ_X2, + CCA_THRESHOLD_REQ_X2, + BWMODE_REQ_X2, + CHIP_TEMP_GET_REQ_X2, + STBC_MCS_SET_REQ_X2, + MAX_AGG_TX_CNT_REQ_X2, + MAX_BW_MCS_THRESH_SET_REQ_X2, + DCM_FORCE_EN_REQ_X2, + AUTO_CCA_EN_REQ_X2, + NSS_1T2R_REQ_X2, + ON_AIR_DUTY_CYCLE_REQ_X2, +}; + + enum { BWMODE20M = 0, BWMODE10M, @@ -2005,7 +2133,8 @@ struct mm_set_channel_access_req u8_l long_nav_en; u8_l cfe_en; u8_l rc_retry_cnt[3]; - s8_l ccademod_th; + s8_l ccademod_th; + u8_l remove_1m2m; }; struct mm_set_mac_timescale_req @@ -2047,6 +2176,58 @@ struct mm_get_chip_temp_cfm s8_l degree; }; +struct mm_get_stbc_msc_req +{ + u32_l hwconfig_id; + u8_l enable; + u8_l mcs_thresh; +}; + +struct mm_set_max_tx_agg_cnt_req +{ + u32_l hwconfig_id; + u8_l enale; + u8_l mcs_thresh; + u8_l max_agg_cnt[AC_MAX]; +}; + +struct mm_set_max_bw_mcs_thresh_req +{ + u32_l hwconfig_id; + u8_l enale; + u8_l max_bw_mcs_thresh; +}; + +struct mm_set_dcm_force_en_req +{ + u32_l hwconfig_id; + u8_l enable; +}; + + +struct mm_set_auto_cca_en_req +{ + u32_l hwconfig_id; + u8_l enable; + int8_t max_cca_thresh; + u8_l default_cca_set; + int8_t default_cca_thresh; +}; + +struct mm_set_nss_1t2r_req +{ + u32_l hwconfig_id; + u8_l enable; +}; + +struct mm_set_on_air_duty_cycle_req +{ + u32_l hwconfig_id; + u8_l enable; + u8_l percent;//10 means 10%, 1-99 +}; + + struct mm_set_vendor_hwconfig_cfm { u32_l hwconfig_id; @@ -2062,6 +2243,15 @@ struct mm_set_customized_freq_req u16_l map_freq[4]; }; +struct mm_set_keepalive_req +{ + u32_l hwconfig_id; + u16_l code; + u16_l length; + u32_l intv; + u8_l payload[]; +}; + struct mm_set_txop_req { u16_l txop_bk; @@ -2100,6 +2290,18 @@ enum vendor_swconfig_tag EXT_FLAGS_MASK_SET_REQ, }; +enum vendor_swconfig_tag_x2 +{ + BCN_CFG_REQ_X2 = 0, + TEMP_COMP_SET_REQ_X2, + TEMP_COMP_GET_REQ_X2, + EXT_FLAGS_SET_REQ_X2, + EXT_FLAGS_GET_REQ_X2, + EXT_FLAGS_MASK_SET_REQ_X2, + TWO_ANT_RSSI_GET_REQ_X2, +}; + + struct mm_set_bcn_cfg_req { /// Ignore or not bcn tim bcmc bit @@ -2184,6 +2386,12 @@ struct mm_set_vendor_swconfig_cfm }; }; +struct mm_set_txpwr_lvl_per_sta_req +{ + u8_l sta_idx; + s8_l tx_pwr_offset; +}; + /// Structure containing the parameters of the @ref ME_RC_STATS_REQ message. struct me_rc_stats_req { @@ -2551,13 +2759,13 @@ struct apm_stop_req struct apm_start_cac_req { /// Control channel on which we have to start the CAC - struct mac_chan_def chan; + struct mac_chan_op chan; /// Center frequency of the first segment - u32_l center_freq1; + //u32_l center_freq1; /// Center frequency of the second segment (only in 80+80 configuration) - u32_l center_freq2; + //u32_l center_freq2; /// Width of channel - u8_l ch_width; + //u8_l ch_width; /// Index of the VIF for which the CAC is started u8_l vif_idx; }; @@ -3007,7 +3215,7 @@ struct dbg_rftest_cmd_req struct dbg_rftest_cmd_cfm { - u32_l rftest_result[18]; + u32_l rftest_result[32]; }; struct dbg_gpio_write_req { @@ -3069,6 +3277,21 @@ struct dbg_mem_block_write_cfm u32_l wstatus; }; +/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_READ_REQ message. +struct dbg_mem_block_read_req +{ + u32_l memaddr; + u32_l memsize; +}; + +/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_READ_CFM message. +struct dbg_mem_block_read_cfm +{ + u32_l memaddr; + u32_l memsize; + u32_l memdata[1024 / sizeof(u32_l)]; +}; + /// Structure containing the parameters of the @ref DBG_START_APP_REQ message. struct dbg_start_app_req { @@ -3233,5 +3456,44 @@ struct tdls_peer_traffic_ind_cfm u8_l status; }; +struct mm_set_wakeup_info_req { + u32_l hwconfig_id; + u16_l code; + u16_l offset; + u16_l length; + u8_l mask_and_pattern[]; + }; + +struct dbg_pwm_init_req +{ + /// PWM_CHANNEL_GPIO + u8 pwm_gpidx; + /// 0 normal 1 breath + u8 mode; + /// 0 config only 1 run after config + u8 run; + u32 tmr_cnt; + u32 dty_cnt; + u32 step_val; + /// 0 disable 1 enable + u8 gpio_en; + /// 0 input 1 output + u8 gpio_dir; + /// 0 low 1 high + u8 gpio_val; +}; + +struct dbg_pwm_deinit_req +{ + /// PWM_CHANNEL_GPIO + u8 pwm_gpidx; + /// 0 disable 1 enable + u8 gpio_en; + /// 0 input 1 output + u8 gpio_dir; + /// 0 low 1 high + u8 gpio_val; +}; + #endif // LMAC_MSG_H_ diff --git a/drivers/aic8800/aic8800_fdrv/reg_access.h b/drivers/aic8800/aic8800_fdrv/reg_access.h index b1d9c01..112ef03 100644 --- a/drivers/aic8800/aic8800_fdrv/reg_access.h +++ b/drivers/aic8800/aic8800_fdrv/reg_access.h @@ -21,7 +21,7 @@ #define ROM_FMAC_FW_ADDR 0x00010000 #define RAM_FMAC_FW_ADDR 0x00120000 #define ROM_FMAC_PATCH_ADDR 0x00180000 -#ifdef CONFIG_DPD +#if defined(CONFIG_DPD) || defined(CONFIG_LOFT_CALIB) #define ROM_FMAC_CALIB_ADDR 0x00130000 #endif diff --git a/drivers/aic8800/aic8800_fdrv/regdb.c b/drivers/aic8800/aic8800_fdrv/regdb.c index 8d29c97..d3ac7ac 100644 --- a/drivers/aic8800/aic8800_fdrv/regdb.c +++ b/drivers/aic8800/aic8800_fdrv/regdb.c @@ -1,2874 +1,2878 @@ -#include -#include -#include +/** + ****************************************************************************** + * + * Copyright (C) 2020 AIC semiconductor. + * + * @file regdb.c + * + * @brief country code Dependent document + * https://mirrors.edge.kernel.org/pub/software/network/wireless-regdb/ + * wireless-regdb-2024.05.08 + * + ****************************************************************************** + */ -//#include "regdb.h" +#include +#include +#include #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0) -#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ -{ \ - .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ - .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ - .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ - .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\ - .power_rule.max_eirp = DBM_TO_MBM(eirp), \ - .flags = reg_flags, \ -} +#define REG_RULE_EXT(start, end, bw, gain, eirp, dfs_cac, reg_flags) \ + { \ + .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \ + .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \ + .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \ + .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \ + .power_rule.max_eirp = DBM_TO_MBM(eirp), \ + .flags = reg_flags, \ + } #define NL80211_RRF_AUTO_BW 0 #endif + static const struct ieee80211_regdomain regdom_00 = { - .n_reg_rules = 2, .alpha2 = "00", + .n_reg_rules = 2, .reg_rules = { - // 1...14 + // 1 - 14 REG_RULE(2390 - 10, 2510 + 10, 40, 0, 20, 0), - // 36...165 + // 36 - 165 REG_RULE(5150 - 10, 5970 + 10, 80, 0, 20, 0), } }; +#if 0 +static const struct ieee80211_regdomain regdom_00 = { + .n_reg_rules = 8, + .alpha2 = "00", + .reg_rules = { + REG_RULE_EXT(2402, 2472, 40, 0, 20, 0, 0), + // 12 - 13 + REG_RULE_EXT(2457, 2482, 20, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | 0), + // 14 + REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM | 0), + // 36 - 48 + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | 0), + // 52 - 64 + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_IR | NL80211_RRF_DFS | 0), + // 100 - 144 + REG_RULE_EXT(5490, 5730, 160, 0, 20, 0, NL80211_RRF_NO_IR | NL80211_RRF_DFS | 0), + //149 - 165 + REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, NL80211_RRF_NO_IR | 0), + REG_RULE_EXT(57240, 63720, 2160, 0, 0, 0, 0), + }}; +#endif + static const struct ieee80211_regdomain regdom_AD = { .alpha2 = "AD", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5710, 80, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_AE = { .alpha2 = "AE", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - //REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_AF = { .alpha2 = "AF", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_AI = { .alpha2 = "AI", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_AL = { .alpha2 = "AL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_AM = { .alpha2 = "AM", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 18, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 18, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_AN = { .alpha2 = "AN", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_AR = { .alpha2 = "AR", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - //REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - // NL80211_RRF_AUTO_BW | 0), - //REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - // NL80211_RRF_DFS | - // NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5270, 5330, 40, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - //REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - // NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_AS = { .alpha2 = "AS", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_AT = { .alpha2 = "AT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_AU = { .alpha2 = "AU", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 36, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5600, 80, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5650, 5730, 80, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5730, 5850, 80, 0, 36, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5850, 5875, 20, 0, 14, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5925, 6425, 160, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 43, 0, NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 9}; static const struct ieee80211_regdomain regdom_AW = { .alpha2 = "AW", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_AZ = { .alpha2 = "AZ", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_BA = { .alpha2 = "BA", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_BB = { .alpha2 = "BB", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_BD = { .alpha2 = "BD", - .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BE = { .alpha2 = "BE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BF = { .alpha2 = "BF", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_BG = { .alpha2 = "BG", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BH = { .alpha2 = "BH", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 20, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_BL = { .alpha2 = "BL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_BM = { .alpha2 = "BM", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_BN = { .alpha2 = "BN", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_BO = { .alpha2 = "BO", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 80, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_BR = { .alpha2 = "BR", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 27, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 27, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 30, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_NO_IR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BS = { .alpha2 = "BS", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_BT = { .alpha2 = "BT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_BW = { + .alpha2 = "BW", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_BY = { .alpha2 = "BY", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_BZ = { .alpha2 = "BZ", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_CA = { .alpha2 = "CA", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5600, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5650, 5730, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_CF = { .alpha2 = "CF", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 40, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 40, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 40, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 40, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 40, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 40, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 40, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 40, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_CH = { .alpha2 = "CH", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_CI = { .alpha2 = "CI", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_CL = { .alpha2 = "CL", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_CN = { .alpha2 = "CN", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - REG_RULE_EXT(57240, 59400, 2160, 0, 28, 0, 0), - REG_RULE_EXT(59400, 63720, 2160, 0, 44, 0, 0), - REG_RULE_EXT(63720, 65880, 2160, 0, 28, 0, 0), - }, - .n_reg_rules = 7 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 33, 0, 0), + REG_RULE_EXT(57240, 59400, 2160, 0, 28, 0, 0), + REG_RULE_EXT(59400, 63720, 2160, 0, 44, 0, 0), + REG_RULE_EXT(63720, 65880, 2160, 0, 28, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_CO = { .alpha2 = "CO", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_CR = { .alpha2 = "CR", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; + +static const struct ieee80211_regdomain regdom_CU = { + .alpha2 = "CU", + .dfs_region = NL80211_DFS_FCC, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 23, 0, 0), + REG_RULE_EXT(5150, 5350, 80, 0, 23, 0, NL80211_RRF_NO_IR | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 80, 0, 24, 0, NL80211_RRF_NO_IR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 23, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_CX = { .alpha2 = "CX", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_CY = { .alpha2 = "CY", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_CZ = { .alpha2 = "CZ", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_DE = { .alpha2 = "DE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5695, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - /*REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, - NL80211_RRF_DFS | 0),*/ - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_DK = { .alpha2 = "DK", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_DM = { .alpha2 = "DM", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_DO = { .alpha2 = "DO", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_DZ = { .alpha2 = "DZ", - .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5670, 160, 0, 23, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_EC = { .alpha2 = "EC", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 21, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 21, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_EE = { .alpha2 = "EE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_EG = { .alpha2 = "EG", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_ES = { .alpha2 = "ES", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_ET = { .alpha2 = "ET", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_FI = { .alpha2 = "FI", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_FM = { .alpha2 = "FM", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_FR = { .alpha2 = "FR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5695, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_GB = { .alpha2 = "GB", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5730, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5925, 6425, 160, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_GD = { .alpha2 = "GD", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_GE = { .alpha2 = "GE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 18, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 18, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_GF = { .alpha2 = "GF", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_GH = { .alpha2 = "GH", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_GI = { + .alpha2 = "GI", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_GL = { .alpha2 = "GL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5710, 80, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_GP = { .alpha2 = "GP", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_GR = { .alpha2 = "GR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_GT = { .alpha2 = "GT", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_GU = { .alpha2 = "GU", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_GY = { .alpha2 = "GY", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 23, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_HK = { .alpha2 = "HK", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 36, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5730, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5730, 5850, 80, 0, 36, 0, 0), + REG_RULE_EXT(5925, 6425, 160, 0, 14, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_HN = { .alpha2 = "HN", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_HR = { .alpha2 = "HR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_HT = { .alpha2 = "HT", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_HU = { .alpha2 = "HU", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_ID = { .alpha2 = "ID", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5815, 80, 0, 23, 0, 0), - }, - .n_reg_rules = 2 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 27, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5150, 5350, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5825, 80, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_IE = { .alpha2 = "IE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_IL = { .alpha2 = "IL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_IN = { .alpha2 = "IN", - .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 30, 0, 0), + REG_RULE_EXT(5250, 5350, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_IQ = { + .alpha2 = "IQ", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_IR = { .alpha2 = "IR", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 2}; static const struct ieee80211_regdomain regdom_IS = { .alpha2 = "IS", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_IT = { .alpha2 = "IT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_JM = { .alpha2 = "JM", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_JO = { .alpha2 = "JO", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 23, 0, 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), + REG_RULE_EXT(5735, 5835, 80, 0, 23, 0, 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_JP = { .alpha2 = "JP", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, - NL80211_RRF_NO_OFDM | 0), - REG_RULE_EXT(4910, 4990, 40, 0, 23, 0, 0), - REG_RULE_EXT(5030, 5090, 40, 0, 23, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 23, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 7 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(2474, 2494, 20, 0, 20, 0, NL80211_RRF_NO_OFDM | 0), + REG_RULE_EXT(4910, 4990, 40, 0, 23, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 23, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5925, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 10, 0, 0), + }, + .n_reg_rules = 8}; static const struct ieee80211_regdomain regdom_KE = { .alpha2 = "KE", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), - REG_RULE_EXT(5490, 5570, 80, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5775, 40, 0, 23, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, 0), + REG_RULE_EXT(5490, 5570, 80, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5775, 40, 0, 23, 0, 0), + }, + .n_reg_rules = 4}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_KG = { + .alpha2 = "KG", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_KH = { .alpha2 = "KH", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_KN = { .alpha2 = "KN", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_KP = { .alpha2 = "KP", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5630, 80, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 20, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5630, 20, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5815, 20, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_KR = { .alpha2 = "KR", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 23, 0, 0), + REG_RULE_EXT(5150, 5230, 40, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5230, 5250, 20, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 23, 0, 0), + REG_RULE_EXT(5925, 7125, 160, 0, 15, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 43, 0, 0), + }, + .n_reg_rules = 8}; static const struct ieee80211_regdomain regdom_KW = { .alpha2 = "KW", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_KY = { .alpha2 = "KY", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_KZ = { .alpha2 = "KZ", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - }, - .n_reg_rules = 1 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 20, 0, NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_LB = { .alpha2 = "LB", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_LC = { .alpha2 = "LC", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5815, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_LI = { .alpha2 = "LI", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_LK = { .alpha2 = "LK", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 20, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_LS = { .alpha2 = "LS", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_LT = { .alpha2 = "LT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_LU = { .alpha2 = "LU", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_LV = { .alpha2 = "LV", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_LY = { + .alpha2 = "LY", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_MA = { .alpha2 = "MA", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_MC = { .alpha2 = "MC", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MD = { .alpha2 = "MD", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_ME = { .alpha2 = "ME", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MF = { .alpha2 = "MF", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MH = { .alpha2 = "MH", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MK = { .alpha2 = "MK", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_MN = { .alpha2 = "MN", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MO = { .alpha2 = "MO", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 40, 0, 23, 0, 0), - REG_RULE_EXT(5250, 5330, 40, 0, 23, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 40, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .dfs_region = NL80211_DFS_FCC, + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 23, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 30, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MP = { .alpha2 = "MP", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_MQ = { .alpha2 = "MQ", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MR = { .alpha2 = "MR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MT = { .alpha2 = "MT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_MU = { .alpha2 = "MU", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; + +static const struct ieee80211_regdomain regdom_MV = { + .alpha2 = "MV", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 20, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MW = { .alpha2 = "MW", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_MX = { .alpha2 = "MX", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_MY = { .alpha2 = "MY", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_NA = { + .alpha2 = "NA", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +static const struct ieee80211_regdomain regdom_NG = { + .alpha2 = "NG", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_NI = { .alpha2 = "NI", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_NL = { .alpha2 = "NL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_NO = { .alpha2 = "NO", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5470, 5795, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5815, 5850, 35, 0, 33, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(17100, 17300, 200, 0, 20, 0, 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 7 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 71000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_NP = { .alpha2 = "NP", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_NZ = { .alpha2 = "NZ", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_OM = { .alpha2 = "OM", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_PA = { .alpha2 = "PA", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 36, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 36, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 30, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 30, 0, 0), + REG_RULE_EXT(5725, 5850, 80, 0, 36, 0, 0), + REG_RULE_EXT(57000, 64000, 2160, 0, 43, 0, 0), + }, + .n_reg_rules = 6}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_PE = { .alpha2 = "PE", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PF = { .alpha2 = "PF", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_PG = { .alpha2 = "PG", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_PH = { .alpha2 = "PH", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PK = { .alpha2 = "PK", .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5270, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5270, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | + NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5610, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | + NL80211_RRF_DFS | 0), + REG_RULE_EXT(5610, 5725, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 30, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PL = { .alpha2 = "PL", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PM = { .alpha2 = "PM", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_PR = { .alpha2 = "PR", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_PT = { .alpha2 = "PT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_PW = { .alpha2 = "PW", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_PY = { .alpha2 = "PY", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_QA = { .alpha2 = "QA", - .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 2 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | + NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_RE = { .alpha2 = "RE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_RO = { .alpha2 = "RO", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_RS = { .alpha2 = "RS", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), - REG_RULE_EXT(5150, 5350, 40, 0, 23, 0, - NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(5470, 5725, 20, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | + NL80211_RRF_DFS | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_RU = { .alpha2 = "RU", - .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5650, 5730, 80, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5350, 160, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5650, 5850, 160, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5925, 6425, 160, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, + NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_RW = { .alpha2 = "RW", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_SA = { .alpha2 = "SA", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_SE = { .alpha2 = "SE", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_SG = { .alpha2 = "SG", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 23, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5730, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 30, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 24, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_SI = { .alpha2 = "SI", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_SK = { .alpha2 = "SK", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_SM = { + .alpha2 = "SM", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_SN = { .alpha2 = "SN", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_SR = { .alpha2 = "SR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_SV = { .alpha2 = "SV", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 20, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 20, 0, 23, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 20, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_SY = { .alpha2 = "SY", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - }, - .n_reg_rules = 1 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + }, + .n_reg_rules = 1}; static const struct ieee80211_regdomain regdom_TC = { .alpha2 = "TC", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_TD = { .alpha2 = "TD", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_TG = { .alpha2 = "TG", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 40, 0, 20, 0, 0), - REG_RULE_EXT(5250, 5330, 40, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5710, 40, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 40, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 40, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5710, 40, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_TH = { .alpha2 = "TH", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_TJ = { + .alpha2 = "TJ", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_TM = { + .alpha2 = "TM", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_TN = { .alpha2 = "TN", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_TR = { .alpha2 = "TR", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5495, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_TT = { .alpha2 = "TT", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_TW = { .alpha2 = "TW", - .dfs_region = NL80211_DFS_JP, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5270, 5330, 40, 0, 17, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5590, 80, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5650, 5710, 40, 0, 30, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_FCC, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 30, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5730, 160, 0, 23, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 30, 0, 0), + REG_RULE_EXT(5945, 6425, 320, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +static const struct ieee80211_regdomain regdom_TZ = { + .alpha2 = "TZ", + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 2}; + static const struct ieee80211_regdomain regdom_UA = { .alpha2 = "UA", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(5150, 5350, 40, 0, 20, 0, - NL80211_RRF_NO_OUTDOOR | 0), - REG_RULE_EXT(5490, 5670, 80, 0, 20, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 20, 0, 0), - REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5150, 5250, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5725, 5850, 80, 0, 20, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 16, 0, + NL80211_RRF_NO_OUTDOOR | 0), + }, + .n_reg_rules = 6}; static const struct ieee80211_regdomain regdom_UG = { .alpha2 = "UG", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_US = { .alpha2 = "US", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - // 1...13 - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - // 36 40 44 48 - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - // 52 56 60 64 - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - // 100 104 108 112 116 120 124 - REG_RULE_EXT(5490, 5650, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - // 128 132 136 140 - REG_RULE_EXT(5650, 5710, 40, 0, 24, 0, - NL80211_RRF_DFS | 0), - // 149 153 157 161 165 - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - REG_RULE_EXT(57240, 63720, 2160, 0, 40, 0, 0), - }, - .n_reg_rules = 7 -}; + .reg_rules = + { + // 1...11 + REG_RULE_EXT(2400, 2472, 40, 0, 30, 0, 0), + // 36 40 44 48 + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + // 52 56 60 64 + REG_RULE_EXT(5250, 5350, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + // 100 104 108 112 116 120 124 + REG_RULE_EXT(5470, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + // 128 132 136 140 + REG_RULE_EXT(5730, 5850, 80, 0, 30, 0, NL80211_RRF_AUTO_BW | 0), + // 149 153 157 161 165 + REG_RULE_EXT(5850, 5895, 40, 0, 27, 0, + NL80211_RRF_AUTO_BW | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(5925, 7125, 320, 0, 12, 0, + NL80211_RRF_NO_IR | NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57240, 71000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 8}; +//Certified laboratory requirements static const struct ieee80211_regdomain regdom_UY = { .alpha2 = "UY", - .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_UZ = { .alpha2 = "UZ", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - }, - .n_reg_rules = 3 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + }, + .n_reg_rules = 3}; static const struct ieee80211_regdomain regdom_VC = { .alpha2 = "VC", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_VE = { .alpha2 = "VE", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 23, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 23, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_VI = { .alpha2 = "VI", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2472, 40, 0, 30, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 24, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_VN = { .alpha2 = "VN", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5730, 80, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_VU = { .alpha2 = "VU", .dfs_region = NL80211_DFS_FCC, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, - NL80211_RRF_DFS | 0), - REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), - }, - .n_reg_rules = 5 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 17, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 24, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5730, 160, 0, 24, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5735, 5835, 80, 0, 30, 0, 0), + }, + .n_reg_rules = 5}; static const struct ieee80211_regdomain regdom_WF = { .alpha2 = "WF", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; + +static const struct ieee80211_regdomain regdom_WS = { + .alpha2 = "WS", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 40, 0, 20, 0, 0), + REG_RULE_EXT(5250, 5330, 40, 0, 20, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5490, 5710, 40, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_FK = { + .alpha2 = "FK", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_FO = { + .alpha2 = "FO", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_YE = { .alpha2 = "YE", - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - }, - .n_reg_rules = 1 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + }, + .n_reg_rules = 1}; static const struct ieee80211_regdomain regdom_YT = { .alpha2 = "YT", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; static const struct ieee80211_regdomain regdom_ZA = { .alpha2 = "ZA", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5695, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - /*REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0),*/ - }, - .n_reg_rules = 4 -}; + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 30, 0, 0), + }, + .n_reg_rules = 4}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_ZM = { + .alpha2 = "ZM", + .dfs_region = NL80211_DFS_ETSI, + .reg_rules = + { + REG_RULE_EXT(2400, 2483, 40, 0, 20, 0, 0), + REG_RULE_EXT(5150, 5250, 80, 0, 23, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5350, 80, 0, 20, 0, + NL80211_RRF_NO_OUTDOOR | NL80211_RRF_DFS | + NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5470, 5725, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + REG_RULE_EXT(5725, 5875, 80, 0, 14, 0, 0), + REG_RULE_EXT(5945, 6425, 160, 0, 23, 0, NL80211_RRF_NO_OUTDOOR | 0), + REG_RULE_EXT(57000, 66000, 2160, 0, 40, 0, 0), + }, + .n_reg_rules = 7}; static const struct ieee80211_regdomain regdom_ZW = { .alpha2 = "ZW", .dfs_region = NL80211_DFS_ETSI, - .reg_rules = { - REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), - REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, - NL80211_RRF_DFS | - NL80211_RRF_AUTO_BW | 0), - REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, - NL80211_RRF_DFS | 0), - }, - .n_reg_rules = 4 + .reg_rules = + { + REG_RULE_EXT(2402, 2482, 40, 0, 20, 0, 0), + REG_RULE_EXT(5170, 5250, 80, 0, 20, 0, NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5250, 5330, 80, 0, 20, 0, + NL80211_RRF_DFS | NL80211_RRF_AUTO_BW | 0), + REG_RULE_EXT(5490, 5710, 160, 0, 27, 0, NL80211_RRF_DFS | 0), + }, + .n_reg_rules = 4}; + +//kernel undefined +static const struct ieee80211_regdomain regdom_WW = { + .n_reg_rules = 2, + .alpha2 = "WW", + .reg_rules = + { + // 1...14 + REG_RULE(2390 - 10, 2510 + 10, 40, 0, 20, 0), + // 36...165 + REG_RULE(5150 - 10, 5970 + 10, 80, 0, 20, 0), + }, }; +//kernel undefined +static const struct ieee80211_regdomain regdom_XX = { + .n_reg_rules = 1, + .alpha2 = "XX", + .reg_rules = + { + /* IEEE 802.11b/g, channels 1..11 */ + REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0), + }, +}; + +//Keep "XX" at the end when inserting const struct ieee80211_regdomain *reg_regdb[] = { - ®dom_00, - ®dom_AD, - ®dom_AE, - ®dom_AF, - ®dom_AI, - ®dom_AL, - ®dom_AM, - ®dom_AN, - ®dom_AR, - ®dom_AS, - ®dom_AT, - ®dom_AU, - ®dom_AW, - ®dom_AZ, - ®dom_BA, - ®dom_BB, - ®dom_BD, - ®dom_BE, - ®dom_BF, - ®dom_BG, - ®dom_BH, - ®dom_BL, - ®dom_BM, - ®dom_BN, - ®dom_BO, - ®dom_BR, - ®dom_BS, - ®dom_BT, - ®dom_BY, - ®dom_BZ, - ®dom_CA, - ®dom_CF, - ®dom_CH, - ®dom_CI, - ®dom_CL, - ®dom_CN, - ®dom_CO, - ®dom_CR, - ®dom_CX, - ®dom_CY, - ®dom_CZ, - ®dom_DE, - ®dom_DK, - ®dom_DM, - ®dom_DO, - ®dom_DZ, - ®dom_EC, - ®dom_EE, - ®dom_EG, - ®dom_ES, - ®dom_ET, - ®dom_FI, - ®dom_FM, - ®dom_FR, - ®dom_GB, - ®dom_GD, - ®dom_GE, - ®dom_GF, - ®dom_GH, - ®dom_GL, - ®dom_GP, - ®dom_GR, - ®dom_GT, - ®dom_GU, - ®dom_GY, - ®dom_HK, - ®dom_HN, - ®dom_HR, - ®dom_HT, - ®dom_HU, - ®dom_ID, - ®dom_IE, - ®dom_IL, - ®dom_IN, - ®dom_IR, - ®dom_IS, - ®dom_IT, - ®dom_JM, - ®dom_JO, - ®dom_JP, - ®dom_KE, - ®dom_KH, - ®dom_KN, - ®dom_KP, - ®dom_KR, - ®dom_KW, - ®dom_KY, - ®dom_KZ, - ®dom_LB, - ®dom_LC, - ®dom_LI, - ®dom_LK, - ®dom_LS, - ®dom_LT, - ®dom_LU, - ®dom_LV, - ®dom_MA, - ®dom_MC, - ®dom_MD, - ®dom_ME, - ®dom_MF, - ®dom_MH, - ®dom_MK, - ®dom_MN, - ®dom_MO, - ®dom_MP, - ®dom_MQ, - ®dom_MR, - ®dom_MT, - ®dom_MU, - ®dom_MW, - ®dom_MX, - ®dom_MY, - ®dom_NI, - ®dom_NL, - ®dom_NO, - ®dom_NP, - ®dom_NZ, - ®dom_OM, - ®dom_PA, - ®dom_PE, - ®dom_PF, - ®dom_PG, - ®dom_PH, - ®dom_PK, - ®dom_PL, - ®dom_PM, - ®dom_PR, - ®dom_PT, - ®dom_PW, - ®dom_PY, - ®dom_QA, - ®dom_RE, - ®dom_RO, - ®dom_RS, - ®dom_RU, - ®dom_RW, - ®dom_SA, - ®dom_SE, - ®dom_SG, - ®dom_SI, - ®dom_SK, - ®dom_SN, - ®dom_SR, - ®dom_SV, - ®dom_SY, - ®dom_TC, - ®dom_TD, - ®dom_TG, - ®dom_TH, - ®dom_TN, - ®dom_TR, - ®dom_TT, - ®dom_TW, - ®dom_UA, - ®dom_UG, - ®dom_US, - ®dom_UY, - ®dom_UZ, - ®dom_VC, - ®dom_VE, - ®dom_VI, - ®dom_VN, - ®dom_VU, - ®dom_WF, - ®dom_YE, - ®dom_YT, - ®dom_ZA, - ®dom_ZW, - NULL, + ®dom_00, ®dom_AD, ®dom_AE, ®dom_AF, ®dom_AI, ®dom_AL, + ®dom_AM, ®dom_AN, ®dom_AR, ®dom_AS, ®dom_AT, ®dom_AU, + ®dom_AW, ®dom_AZ, ®dom_BA, ®dom_BB, ®dom_BD, ®dom_BE, + ®dom_BF, ®dom_BG, ®dom_BH, ®dom_BL, ®dom_BM, ®dom_BN, + ®dom_BO, ®dom_BR, ®dom_BS, ®dom_BT, ®dom_BY, ®dom_BZ, + ®dom_CA, ®dom_CF, ®dom_CH, ®dom_CI, ®dom_CL, ®dom_CN, + ®dom_CO, ®dom_CR, ®dom_CX, ®dom_CY, ®dom_CZ, ®dom_DE, + ®dom_DK, ®dom_DM, ®dom_DO, ®dom_DZ, ®dom_EC, ®dom_EE, + ®dom_EG, ®dom_ES, ®dom_ET, ®dom_FI, ®dom_FM, ®dom_FR, + ®dom_GB, ®dom_GD, ®dom_GE, ®dom_GF, ®dom_GH, ®dom_GL, + ®dom_GP, ®dom_GR, ®dom_GT, ®dom_GU, ®dom_GY, ®dom_HK, + ®dom_HN, ®dom_HR, ®dom_HT, ®dom_HU, ®dom_ID, ®dom_IE, + ®dom_IL, ®dom_IN, ®dom_IR, ®dom_IS, ®dom_IT, ®dom_JM, + ®dom_JO, ®dom_JP, ®dom_KE, ®dom_KH, ®dom_KN, ®dom_KP, + ®dom_KR, ®dom_KW, ®dom_KY, ®dom_KZ, ®dom_LB, ®dom_LC, + ®dom_LI, ®dom_LK, ®dom_LS, ®dom_LT, ®dom_LU, ®dom_LV, + ®dom_MA, ®dom_MC, ®dom_MD, ®dom_ME, ®dom_MF, ®dom_MH, + ®dom_MK, ®dom_MN, ®dom_MO, ®dom_MP, ®dom_MQ, ®dom_MR, + ®dom_MT, ®dom_MU, ®dom_MW, ®dom_MX, ®dom_MY, ®dom_NI, + ®dom_NL, ®dom_NO, ®dom_NP, ®dom_NZ, ®dom_OM, ®dom_PA, + ®dom_PE, ®dom_PF, ®dom_PG, ®dom_PH, ®dom_PK, ®dom_PL, + ®dom_PM, ®dom_PR, ®dom_PT, ®dom_PW, ®dom_PY, ®dom_QA, + ®dom_RE, ®dom_RO, ®dom_RS, ®dom_RU, ®dom_RW, ®dom_SA, + ®dom_SE, ®dom_SG, ®dom_SI, ®dom_SK, ®dom_SN, ®dom_SR, + ®dom_SV, ®dom_SY, ®dom_TC, ®dom_TD, ®dom_TG, ®dom_TH, + ®dom_TN, ®dom_TR, ®dom_TT, ®dom_TW, ®dom_UA, ®dom_UG, + ®dom_US, ®dom_UY, ®dom_UZ, ®dom_VC, ®dom_VE, ®dom_VI, + ®dom_VN, ®dom_VU, ®dom_WF, ®dom_YE, ®dom_YT, ®dom_ZA, + ®dom_ZW, ®dom_BW, ®dom_GI, ®dom_IQ, ®dom_KG, ®dom_LY, + ®dom_MV, ®dom_NA, ®dom_NG, ®dom_SM, ®dom_TJ, ®dom_TM, + ®dom_FK, ®dom_FO, ®dom_ZM, ®dom_CU, ®dom_TZ, ®dom_WS, + ®dom_WW, ®dom_XX, }; int reg_regdb_size = ARRAY_SIZE(reg_regdb); - - diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c index 4cef481..68ddcea 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_cmds.c @@ -19,6 +19,7 @@ #include "rwnx_strs.h" #include "rwnx_events.h" #include "aicwf_txrxif.h" +#include "rwnx_wakelock.h" #ifdef AICWF_SDIO_SUPPORT #include "aicwf_sdio.h" #else @@ -46,8 +47,8 @@ static void cmd_complete(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) //RWNX_DBG(RWNX_FN_ENTRY_STR); lockdep_assert_held(&cmd_mgr->lock); - list_del(&cmd->list); - cmd_mgr->queue_sz--; + //list_del(&cmd->list); + //cmd_mgr->queue_sz--; cmd->flags |= RWNX_CMD_FLAG_DONE; if (cmd->flags & RWNX_CMD_FLAG_NONBLOCK) { @@ -58,6 +59,10 @@ static void cmd_complete(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) complete(&cmd->complete); } } + + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_unlock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx); + } } int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) @@ -102,6 +107,9 @@ int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd init_completion(&cmd->complete); list_add_tail(&cmd->list, &cmd_mgr->cmds); + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_lock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx); + } cmd_mgr->queue_sz++; spin_unlock_bh(&cmd_mgr->lock); @@ -123,12 +131,33 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) struct aic_usb_dev *usbdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr); #endif bool defer_push = false; + u8_l empty = 0; //RWNX_DBG(RWNX_FN_ENTRY_STR); #ifdef CREATE_TRACE_POINTS trace_msg_send(cmd->id); #endif - spin_lock_bh(&cmd_mgr->lock); + if(cmd->e2a_msg != NULL) { + do { + if(cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) + break; + spin_lock_bh(&cmd_mgr->lock); + empty = list_empty(&cmd_mgr->cmds); + if(!empty) { + spin_unlock_bh(&cmd_mgr->lock); + if(in_softirq()) { + printk("in_softirq:check cmdqueue empty\n"); + mdelay(10); + } else { + printk("check cmdqueue empty\n"); + msleep(50); + } + } + } while(!empty);//wait for cmd queue empty + } else { + spin_lock_bh(&cmd_mgr->lock); + } + if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) { printk(KERN_CRIT"cmd queue crashed\n"); @@ -177,6 +206,9 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) init_completion(&cmd->complete); list_add_tail(&cmd->list, &cmd_mgr->cmds); + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_lock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx); + } cmd_mgr->queue_sz++; if(cmd->a2e_msg->id == ME_TRAFFIC_IND_REQ @@ -240,6 +272,13 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd) spin_unlock_bh(&cmd_mgr->lock); } else{ + spin_lock_bh(&cmd_mgr->lock); + list_del(&cmd->list); + cmd_mgr->queue_sz--; + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_tx); + } + spin_unlock_bh(&cmd_mgr->lock); rwnx_cmd_free(cmd);//kfree(cmd);AIDEN if(!list_empty(&cmd_mgr->cmds) && usbdev->state == USB_UP_ST) WAKE_CMD_WORK(cmd_mgr); @@ -350,8 +389,16 @@ void cmd_mgr_task_process(struct work_struct *work) cmd_complete(cmd_mgr, next); } spin_unlock_bh(&cmd_mgr->lock); - } else - rwnx_cmd_free(next);//kfree(next);AIDEN + } else { + spin_lock_bh(&cmd_mgr->lock); + list_del(&next->list); + cmd_mgr->queue_sz--; + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_tx); + } + spin_unlock_bh(&cmd_mgr->lock); + rwnx_cmd_free(next);//kfree(next);AIDEN + } } } @@ -460,11 +507,17 @@ static void cmd_mgr_drain(struct rwnx_cmd_mgr *cmd_mgr) spin_lock_bh(&cmd_mgr->lock); list_for_each_entry_safe(cur, nxt, &cmd_mgr->cmds, list) { list_del(&cur->list); - cmd_mgr->queue_sz--; + //cmd_mgr->queue_sz--; if (!(cur->flags & RWNX_CMD_FLAG_NONBLOCK)) complete(&cur->complete); } spin_unlock_bh(&cmd_mgr->lock); + #if 0 + if(cmd_mgr->queue_sz == 0){ + rwnx_wakeup_unlock(g_rwnx_plat->usbdev->rwnx_hw->ws_tx); + } + #endif + } void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr) @@ -506,6 +559,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) { u8 *buffer = NULL; u16 index = 0; + int ret = 0; #ifdef AICWF_SDIO_SUPPORT struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev; struct aicwf_bus *bus = sdiodev->bus_if; @@ -540,6 +594,9 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) index += 2; memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); - aicwf_bus_txmsg(bus, buffer, len + 8); + ret = aicwf_bus_txmsg(bus, buffer, len + 8); + if (ret == -EIO) { + ret = aicwf_bus_txmsg(bus, buffer, len + 8); + } } diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h index f088f9c..204561b 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_compat.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_compat.h @@ -244,9 +244,11 @@ enum ieee80211_radiotap_he_mu_bits { #define REGULATORY_IGNORE_STALE_KICKOFF 0 #else #define STA_TDLS_INITIATOR(sta) sta->tdls_initiator + #ifndef REGULATORY_IGNORE_STALE_KICKOFF #define REGULATORY_IGNORE_STALE_KICKOFF 0 #endif + #endif diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c index d1a2043..7d4c82e 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_debugfs.c @@ -200,11 +200,11 @@ DEBUGFS_READ_WRITE_FILE_OPS(stats); #endif /* CONFIG_RWNX_FULLMAC */ #define STA_HDR "** STA %d (%pM)\n" -#define STA_HDR_MAX_LEN sizeof("- STA xx (xx:xx:xx:xx:xx:xx)\n") + PS_HDR_MAX_LEN +#define STA_HDR_MAX_LEN (sizeof("- STA xx (xx:xx:xx:xx:xx:xx)\n") + PS_HDR_MAX_LEN) #ifdef CONFIG_RWNX_FULLMAC #define VIF_HDR "* VIF [%d] %s\n" -#define VIF_HDR_MAX_LEN sizeof(VIF_HDR) + IFNAMSIZ +#define VIF_HDR_MAX_LEN (sizeof(VIF_HDR) + IFNAMSIZ) #else #define VIF_HDR "* VIF [%d]\n" #define VIF_HDR_MAX_LEN sizeof(VIF_HDR) @@ -1261,6 +1261,12 @@ static ssize_t rwnx_dbgfs_regdbg_write(struct file *file, if(oper== 0) { ret = rwnx_send_dbg_mem_read_req(priv, addr, &mem_read_cfm); printk("[0x%x] = [0x%x]\n", mem_read_cfm.memaddr, mem_read_cfm.memdata); + } else if (oper == 1) { + ret = rwnx_send_dbg_mem_read_req(priv, addr, &mem_read_cfm); + printk("before write : [0x%x] = [0x%x]\n", mem_read_cfm.memaddr, mem_read_cfm.memdata); + ret = rwnx_send_dbg_mem_block_write_req(priv, addr, 4, &val); + ret = rwnx_send_dbg_mem_read_req(priv, addr, &mem_read_cfm); + printk("after write : [0x%x] = [0x%x]\n", mem_read_cfm.memaddr, mem_read_cfm.memdata); } return count; @@ -1274,7 +1280,7 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file, { struct rwnx_hw *priv = file->private_data; char buf[64]; - int32_t addr[13]; + int32_t addr[14]; int32_t addr_out[12]; u32_l hwconfig_id; size_t len = min_t(size_t,count,sizeof(buf)-1); @@ -1288,10 +1294,10 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file, } buf[len] = '\0'; - ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x", - &hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11]); - if(ret > 14) { - printk("param error > 14\n"); + ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", + &hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11], &addr[12], &addr[13]); + if(ret > 15) { + printk("param error > 15\n"); } else { switch(hwconfig_id) { @@ -1303,12 +1309,12 @@ static ssize_t rwnx_dbgfs_vendor_hwconfig_write(struct file *file, printk("ACS_TXOP_REQ bk:0x%x be:0x%x vi:0x%x vo:0x%x\n",addr[0], addr[1], addr[2], addr[3]); break; case 1: - if(ret != 14) { - printk("param error != 14\n"); + if(ret != 15) { + printk("param error != 15\n"); break;} ret = rwnx_send_vendor_hwconfig_req(priv, hwconfig_id, addr, NULL); - printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x\n", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12]); + printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x, remove_1m2m %x\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13]); break; case 2: if(ret != 7) { @@ -1456,6 +1462,216 @@ static ssize_t rwnx_dbgfs_vendor_swconfig_write(struct file *file, DEBUGFS_WRITE_FILE_OPS(vendor_swconfig); +static ssize_t rwnx_dbgfs_vendor_hwconfig_x2_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct rwnx_hw *priv = file->private_data; + char buf[64]; + int32_t addr[14]; + int32_t addr_out[12]; + u32_l hwconfig_id; + size_t len = min_t(size_t,count,sizeof(buf)-1); + int ret; + printk("%s\n",__func__); + //choose the type of write info by struct + //struct mm_set_vendor_trx_param_req trx_param; + + if(copy_from_user(buf,user_buf,len)) { + return -EFAULT; + } + + buf[len] = '\0'; + ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", + &hwconfig_id, &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5], &addr[6], &addr[7], &addr[8], &addr[9], &addr[10], &addr[11], &addr[12], &addr[13]); + if(ret > 15) { + printk("param error > 15\n"); + } else { + switch(hwconfig_id) + { + case 0: + if(ret != 5) { + printk("param error != 5\n"); + break;} + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, NULL); + printk("ACS_TXOP_REQ bk:0x%x be:0x%x vi:0x%x vo:0x%x\n",addr[0], addr[1], addr[2], addr[3]); + break; + case 1: + if(ret != 15) { + printk("param error != 15\n"); + break;} + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, NULL); + printk("CHANNEL_ACCESS_REQ edca:%x,%x,%x,%x, vif:%x, retry_cnt:%x, rts:%x, long_nav:%x, cfe:%x, rc_retry_cnt:%x:%x:%x ccademod_th %x remove_1m2m %x\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7], addr[8], addr[9], addr[10], addr[11], addr[12], addr[13]); + break; + case 2: + if(ret != 7) { + printk("param error != 7\n"); + break;} + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, NULL); + printk("MAC_TIMESCALE_REQ sifsA:%x,sifsB:%x,slot:%x,ofdm_delay:%x,long_delay:%x,short_delay:%x\n", + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + break; + case 3: + if(ret != 6) { + printk("param error != 6\n"); + break;} + addr[1] = ~addr[1] + 1; + addr[2] = ~addr[2] + 1; + addr[3] = ~addr[3] + 1; + addr[4] = ~addr[4] + 1; + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, NULL); + printk("CCA_THRESHOLD_REQ auto_cca:%d, cca20p_rise:%d cca20s_rise:%d cca20p_fail:%d cca20s_fail:%d\n", + addr[0], addr[1], addr[2], addr[3], addr[4]); + break; + case 4: // BWMODE_REQ + if (ret != 2) { + printk("param error != 2\n"); + } else { + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, NULL); + printk("BWMODE_REQ md=%d\n", addr[0]); + } + break; + case 5: // CHIP_TEMP_GET_REQ + if (ret != 1) { + printk("param error != 1\n"); + } else { + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, addr_out); + printk("CHIP_TEMP_GET_REQ degree=%d\n", addr_out[0]); + } + break; + case 6: // STBC_MCS_SET_REQ + if (ret != 3) { + printk("param error != 3\n"); + } else { + printk("ret=%d, id=%d, param=%x, %x\n", ret, hwconfig_id, addr[0], addr[1]); + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, addr_out); + } + break; + case 7: + printk("ret=%d, id=%d, param=%x, %x\n", ret, hwconfig_id, addr[0], addr[1]); + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, addr_out); + break; + case 8: + case 9: + case 10: + case 11: + case 12: + ret = rwnx_send_vendor_hwconfig_req_x2(priv, hwconfig_id, addr, addr_out); + break; + default: + printk("param error:%d\n", hwconfig_id); + break; + } + if(ret) { + printk("rwnx_send_vendor_hwconfig_req fail: %x\n", ret); + } + } + + return count; +} + +DEBUGFS_WRITE_FILE_OPS(vendor_hwconfig_x2); + +static ssize_t rwnx_dbgfs_vendor_swconfig_x2_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct rwnx_hw *priv = file->private_data; + char buf[64]; + int32_t addr[12]; + int32_t addr_out[12]; + u32_l swconfig_id; + size_t len = min_t(size_t, count, sizeof(buf) - 1); + int ret; + printk("%s\n", __func__); + + if (copy_from_user(buf, user_buf, len)) { + return -EFAULT; + } + + buf[len] = '\0'; + ret = sscanf(buf, "%x %x %x", &swconfig_id, &addr[0], &addr[1]); + if (ret > 3) { + printk("param error > 3\n"); + } else { + switch (swconfig_id) + { + case 0: // BCN_CFG_REQ + if (ret != 2) { + printk("param error != 2\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("BCN_CFG_REQ set_en=%d, get_en=%d\n", addr[0], addr_out[0]); + } + break; + + case 1: // TEMP_COMP_SET_REQ + if (ret != 3) { + printk("param error != 3\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("TEMP_COMP_SET_REQ set_en=%d, tmr=%dms, get_st=%d\n", + addr[0], addr[1], addr_out[0]); + } + break; + + case 2: // TEMP_COMP_GET_REQ + if (ret != 1) { + printk("param error != 1\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("TEMP_COMP_GET_REQ get_st=%d, degree=%d\n", addr_out[0], addr_out[1]); + } + break; + + case 3: // EXT_FLAGS_SET_REQ + if (ret != 2) { + printk("param error != 2\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("EXT_FLAGS_SET_REQ set ext_flags=0x%x, get ext_flags=0x%x\n", + addr[0], addr_out[0]); + } + break; + + case 4: // EXT_FLAGS_GET_REQ + if (ret != 1) { + printk("param error != 1\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("EXT_FLAGS_GET_REQ get ext_flags=0x%x\n", addr_out[0]); + } + break; + + case 5: // EXT_FLAGS_MASK_SET_REQ + if (ret != 3) { + printk("param error != 3\n"); + } else { + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("EXT_FLAGS_MASK_SET_REQ set ext_flags mask=0x%x, val=0x%x, get ext_flags=0x%x\n", + addr[0], addr[1], addr_out[0]); + } + break; + case 6: // TWO_ANT_RSSI_GET_REQ + ret = rwnx_send_vendor_swconfig_req_x2(priv, swconfig_id, addr, addr_out); + printk("2 ant rssi=%x\n", addr_out[0]); + break; + default: + printk("param error\n"); + break; + } + + if (ret) { + printk("rwnx_send_vendor_swconfig_req fail: %x\n", ret); + } + } + + return count; +} + +DEBUGFS_WRITE_FILE_OPS(vendor_swconfig_x2); + static ssize_t rwnx_dbgfs_agg_disable_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -2157,7 +2373,7 @@ static ssize_t rwnx_dbgfs_last_rx_read(struct file *file, nss = last_rx->ht.mcs / 8;; gi = last_rx->ht.short_gi; } else { - BUG_ON((mcs = legrates_lut[last_rx->leg_rate]) == -1); + BUG_ON((mcs = legrates_lut[last_rx->leg_rate].idx) == -1); nss = 0; gi = 0; } @@ -2436,6 +2652,8 @@ int rwnx_dbgfs_register(struct rwnx_hw *rwnx_hw, const char *name) DEBUGFS_ADD_FILE(regdbg, dir_drv, S_IWUSR); DEBUGFS_ADD_FILE(vendor_hwconfig, dir_drv,S_IWUSR); DEBUGFS_ADD_FILE(vendor_swconfig, dir_drv,S_IWUSR); + DEBUGFS_ADD_FILE(vendor_hwconfig_x2, dir_drv,S_IWUSR); + DEBUGFS_ADD_FILE(vendor_swconfig_x2, dir_drv,S_IWUSR); DEBUGFS_ADD_FILE(agg_disable, dir_drv,S_IWUSR); DEBUGFS_ADD_FILE(set_roc, dir_drv,S_IWUSR); DEBUGFS_ADD_FILE(dbg_level, dir_drv, S_IWUSR | S_IRUSR); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_defs.h b/drivers/aic8800/aic8800_fdrv/rwnx_defs.h index 8437fe8..643b45f 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_defs.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_defs.h @@ -33,6 +33,9 @@ #ifdef CONFIG_FILTER_TCP_ACK #include "aicwf_tcp_ack.h" #endif +#ifdef CONFIG_BAND_STEERING +#include "aicwf_steering.h" +#endif #ifdef AICWF_SDIO_SUPPORT #include "aicwf_sdio.h" @@ -73,6 +76,24 @@ #define HIGH_KERNEL_VERSION4 KERNEL_VERSION(6, 3, 0) #endif + + +#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION +#ifndef IEEE80211_MAX_AMPDU_BUF +#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE +#endif +#ifndef IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB +#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB +#endif +#ifndef IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB +#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB +#endif +#ifndef IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA +#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU +#endif +#endif + + #ifndef IEEE80211_MAX_AMPDU_BUF #define IEEE80211_MAX_AMPDU_BUF 0x100 #endif @@ -86,14 +107,6 @@ #define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40 #endif -#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION -#define IEEE80211_MAX_AMPDU_BUF IEEE80211_MAX_AMPDU_BUF_HE -#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB -#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB -#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU -#endif - - #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) enum nl80211_ac { NL80211_AC_VO, @@ -200,6 +213,38 @@ enum nl80211_mesh_power_mode { }; #endif +#ifdef CONFIG_BAND_STEERING +enum band_type { + BAND_ON_24G = 0, + BAND_ON_5G = 1, + BAND_ON_60G = 2, + BAND_ON_6G = 3, + BAND_MAX, +}; + +enum WIFI_FRAME_TYPE { + WIFI_MGT_TYPE = (0), +}; + +enum WIFI_FRAME_SUBTYPE { + WIFI_ASSOCREQ = (0 | WIFI_MGT_TYPE), + WIFI_PROBEREQ = (BIT(6) | WIFI_MGT_TYPE), + WIFI_AUTH = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE), +}; + +struct tmp_feature_sta { + u8_l sta_idx; + u8_l supported_band; +}; + +#define MAX_PENDING_PROBES 3 +struct ap_probe_rsp { + u8_l da[6]; + struct work_struct rsp_work; + bool in_use; +}; +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) #define NL80211_MESHCONF_POWER_MODE 26 @@ -217,6 +262,7 @@ enum nl80211_mesh_power_mode { #endif + /** * struct rwnx_bcn - Information of the beacon in used (AP mode) * @@ -356,7 +402,6 @@ struct rwnx_vif { struct rwnx_key key[6]; unsigned long drv_flags; atomic_t drv_conn_state; - u8 is_conn; u8 drv_vif_index; /* Identifier of the VIF in driver */ u8 vif_index; /* Identifier of the station in FW */ u8 ch_index; /* Channel context identifier */ @@ -407,6 +452,12 @@ struct rwnx_vif { bool create_path; /* Indicate if we are waiting for a MESH_CREATE_PATH_CFM message */ int generation; /* Increased each time the list of Mesh Paths is updated */ +#ifdef CONFIG_BAND_STEERING + u8_l tmp_sta_idx; + enum band_type band; + u32_l freq; + bool start; +#endif enum nl80211_mesh_power_mode mesh_pm; /* mesh power save mode currently set in firmware */ enum nl80211_mesh_power_mode next_mesh_pm; /* mesh power save mode for next peer */ } ap; @@ -435,6 +486,13 @@ struct rwnx_vif { struct br_ext_info ethBrExtInfo; #endif /* CONFIG_BR_SUPPORT */ +#ifdef CONFIG_BAND_STEERING + struct workqueue_struct *rsp_wq; + struct timer_list steer_timer; + struct work_struct steer_work; + struct b_steer_priv bsteerpriv; + struct ap_probe_rsp pb_pool[MAX_PENDING_PROBES]; +#endif }; @@ -479,10 +537,18 @@ struct rwnx_rx_rate_stats { * @rx_rate: Statistics of the received rates */ struct rwnx_sta_stats { -//#ifdef CONFIG_RWNX_DEBUGFS + u32 rx_pkts; + u32 tx_pkts; + u64 rx_bytes; + u64 tx_bytes; + unsigned long last_act; struct hw_vect last_rx; struct rwnx_rx_rate_stats rx_rate; -//#endif + u32 last_chan_time; + u32 last_chan_busy_time; + u32 tx_ack_succ_stat; + u32 tx_ack_fail_stat; + u32 last_chan_tx_busy_time; }; #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) @@ -490,6 +556,14 @@ struct aic_sta { u8 sta_idx; /* Identifier of the station */ bool he; /* Flag indicating if the station supports HE */ bool vht; /* Flag indicating if the station supports VHT */ + + struct ieee80211_he_cap_elem he_cap_elem; + struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL) + __le32 vht_cap_info; + struct ieee80211_vht_mcs_info supp_mcs; +#endif }; #endif @@ -537,6 +611,17 @@ struct rwnx_sta { struct rwnx_tdls tdls; /* TDLS station information */ struct rwnx_sta_stats stats; enum nl80211_mesh_power_mode mesh_pm; /* link-specific mesh power save mode */ +#ifdef CONFIG_DYNAMIC_PERPWR + s8_l rssi_save; + s8_l per_pwrloss; + struct work_struct per_pwr_work; + unsigned long last_jiffies; +#endif +#ifdef CONFIG_BAND_STEERING + u32_l link_time; + s8_l rssi; + u8_l support_band; +#endif }; static inline const u8 *rwnx_sta_addr(struct rwnx_sta *rwnx_sta) { @@ -620,13 +705,41 @@ struct rwnx_phy_info { bool limit_bw; }; +struct defrag_ctrl_info { + struct list_head list; + u8 sta_idx; + u8 tid; + u16 sn; + u8 next_fn; + u16 frm_len; + struct sk_buff *skb; + struct timer_list defrag_timer; + struct rwnx_hw *rwnx_hw; +}; + +struct amsdu_subframe_hdr { + u8 da[6]; + u8 sa[6]; + u16 sublen; +}; + /* rwnx driver status */ +void rwnx_set_conn_state(atomic_t *drv_conn_state, int state); enum rwnx_drv_connect_status { RWNX_DRV_STATUS_DISCONNECTED = 0, RWNX_DRV_STATUS_DISCONNECTING, RWNX_DRV_STATUS_CONNECTING, RWNX_DRV_STATUS_CONNECTED, + RWNX_DRV_STATUS_ROAMING, +}; + +static const char *const s_conn_state[] = { + "RWNX_DRV_STATUS_DISCONNECTED", + "RWNX_DRV_STATUS_DISCONNECTING", + "RWNX_DRV_STATUS_CONNECTING", + "RWNX_DRV_STATUS_CONNECTED", + "RWNX_DRV_STATUS_ROAMING", }; @@ -735,10 +848,19 @@ struct rwnx_hw { bool scanning; bool p2p_working; + struct list_head defrag_list; + spinlock_t defrag_lock; + struct work_struct apmStalossWork; struct workqueue_struct *apmStaloss_wq; u8 apm_vif_idx; u8 sta_mac_addr[6]; + + struct wakeup_source *ws_rx; + struct wakeup_source *ws_irqrx; + struct wakeup_source *ws_tx; + struct wakeup_source *ws_pwrctrl; + #ifdef CONFIG_SCHED_SCAN bool is_sched_scan; #endif//CONFIG_SCHED_SCAN @@ -760,9 +882,20 @@ struct rwnx_hw { bool wext_scan; struct completion wext_scan_com; struct list_head wext_scanre_list; - char wext_essid[32]; + char wext_essid[33]; int support_freqs[SCAN_CHANNEL_MAX]; int support_freqs_number; +#ifdef CONFIG_DYNAMIC_PWR + struct timer_list pwrloss_timer; + struct work_struct pwrloss_work; + struct rwnx_vif *read_rssi_vif; + s8 pwrloss_lvl; + u8 sta_rssi_idx; +#endif +#endif +#ifdef CONFIG_BAND_STEERING + u8_l iface_idx; + struct tmp_feature_sta feature_table[NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX]; #endif }; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.c b/drivers/aic8800/aic8800_fdrv/rwnx_main.c index 0315980..5962bcd 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.c @@ -43,7 +43,13 @@ #include "aicwf_txrxif.h" #include "aicwf_compat_8800dc.h" #include "aicwf_compat_8800d80.h" +#include "aicwf_compat_8800d80x2.h" #include "aic_priv_cmd.h" +#include "rwnx_wakelock.h" +#include "rwnx_msg_tx.h" +#ifdef CONFIG_BAND_STEERING +#include "aicwf_manager.h" +#endif #ifdef CONFIG_USE_WIRELESS_EXT #include "aicwf_wext_linux.h" @@ -61,6 +67,16 @@ #define RW_DRV_COPYRIGHT "Copyright(c) 2015-2017 RivieraWaves" #define RW_DRV_AUTHOR "RivieraWaves S.A.S" +#ifdef CONFIG_WOWLAN + //ff ff ff ff ff ff is magic package + u8_l wowlan_param1[] = {0x01,0x2a,0x06,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xff,0xff,0xff,0xff,0xff}; +#endif + +static char *wifi_mac_addr = 0; + +extern char country_code[]; + #define RWNX_PRINT_CFM_ERR(req) \ printk(KERN_CRIT "%s: Status Error(%d)\n", #req, (&req##_cfm)->status) @@ -525,6 +541,10 @@ atomic_t aicwf_deinit_atomic; int aicwf_dbg_level = LOGERROR|LOGINFO; module_param(aicwf_dbg_level, int, 0660); +#ifdef CONFIG_DYNAMIC_PWR +int dynamic_pwr = 1; +module_param(dynamic_pwr, int, 0660); +#endif int testmode = 0; char aic_fw_path[200]; @@ -1057,7 +1077,7 @@ static void rwnx_csa_finish(struct work_struct *ws) #endif } else { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) - wiphy_lock(rwnx_hw->wiphy); + wiphy_lock(rwnx_hw->wiphy); #else mutex_lock(&vif->wdev.mtx); __acquire(&vif->wdev.mtx); @@ -1072,16 +1092,16 @@ static void rwnx_csa_finish(struct work_struct *ws) rwnx_txq_vif_stop(vif, RWNX_TXQ_STOP_CHAN, rwnx_hw); spin_unlock_bh(&rwnx_hw->cb_lock); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0)) - cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); + cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); #elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION3) cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0, 0); -#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) +#elif (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION) cfg80211_ch_switch_notify(vif->ndev, &csa->chandef, 0); #else cfg80211_ch_switch_notify(vif->ndev, &csa->chandef); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0)) - wiphy_unlock(rwnx_hw->wiphy); + wiphy_unlock(rwnx_hw->wiphy); #else mutex_unlock(&vif->wdev.mtx); __release(&vif->wdev.mtx); @@ -1168,6 +1188,64 @@ void rwnx_update_mesh_power_mode(struct rwnx_vif *vif) vif->ap.mesh_pm = mesh_pm; } +#ifdef CONFIG_BAND_STEERING +void aicwf_steering_work(struct work_struct *work) +{ + struct rwnx_vif *rwnx_vif = container_of(work, struct rwnx_vif, steer_work); + struct rwnx_sta *sta; + + if (rwnx_vif->up == false) { + AICWFDBG(LOGERROR, "%s vif is down\n", __func__); + return; + } + + //printk("%s\n", __func__); + aicwf_nl_send_intf_rpt_msg(rwnx_vif); + aicwf_nl_send_time_tick_msg(rwnx_vif); + aicwf_band_steering_expire(rwnx_vif); + + spin_lock_bh(&rwnx_vif->rwnx_hw->cb_lock); + if(list_empty(&rwnx_vif->ap.sta_list)) { + spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); + goto finish; + } + list_for_each_entry(sta, &rwnx_vif->ap.sta_list, list) { + if (sta->valid) { + sta->link_time +=2; + aicwf_nl_send_sta_rpt_msg(rwnx_vif, sta); + } + } + spin_unlock_bh(&rwnx_vif->rwnx_hw->cb_lock); + +finish: + mod_timer(&rwnx_vif->steer_timer, jiffies + msecs_to_jiffies(STEER_UPFATE_TIME)); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) +void aicwf_steering_timeout(ulong data) +#else +void aicwf_steering_timeout(struct timer_list *t) +#endif +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)data; +#else + struct rwnx_vif *rwnx_vif = container_of(t, struct rwnx_vif, steer_timer); +#endif + + if (rwnx_vif->up == false) { + AICWFDBG(LOGERROR, "%s vif is down\n", __func__); + return; + } + + if (!work_pending(&rwnx_vif->steer_work)) + schedule_work(&rwnx_vif->steer_work); + + return; +} +#endif + + #ifdef CONFIG_BR_SUPPORT void netdev_br_init(struct net_device *netdev) { @@ -1209,6 +1287,18 @@ void netdev_br_init(struct net_device *netdev) } #endif /* CONFIG_BR_SUPPORT */ +void rwnx_set_conn_state(atomic_t *drv_conn_state, int state){ + + if((int)atomic_read(drv_conn_state) != state){ + AICWFDBG(LOGDEBUG, "%s drv_conn_state:%p %s --> %s \r\n", __func__, + drv_conn_state, + s_conn_state[(int)atomic_read(drv_conn_state)], + s_conn_state[state]); + + atomic_set(drv_conn_state, state); + } +} + /********************************************************************* * netdev callbacks @@ -1232,7 +1322,9 @@ static int rwnx_open(struct net_device *dev) int waiting_counter = 10; RWNX_DBG(RWNX_FN_ENTRY_STR); - +#ifdef CONFIG_WOWLAN + rwnx_send_set_pkt_filter_req(rwnx_hw, wowlan_param1); +#endif while(test_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags)){ msleep(100); AICWFDBG(LOGDEBUG, "%s waiting for rwnx_close \r\n", __func__); @@ -1255,20 +1347,19 @@ static int rwnx_open(struct net_device *dev) return error; } } +#ifdef CONFIG_COEX + if (testmode == 0) { + rwnx_send_coex_req(rwnx_hw, 0, 1); + } +#endif /* Device is now started */ } set_bit(RWNX_DEV_STARTED, &rwnx_vif->drv_flags); - atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); AICWFDBG(LOGDEBUG, "%s rwnx_vif->drv_flags:%d\r\n", __func__, (int)rwnx_vif->drv_flags); - if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) - { - #ifdef CONFIG_COEX - rwnx_send_coex_req(rwnx_hw, 1, 0); - #endif - } if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) { if (!rwnx_hw->is_p2p_alive) { @@ -1414,7 +1505,7 @@ static int rwnx_close(struct net_device *dev) test_counter--; if(test_counter == 0){ AICWFDBG(LOGERROR, "%s connecting or disconnecting, not finish\r\n", __func__); - WARN_ON(1); + //WARN_ON(1); break; } } @@ -1474,7 +1565,7 @@ static int rwnx_close(struct net_device *dev) RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT){ test_counter = waiting_counter; if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ - atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, 3); while (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING) { AICWFDBG(LOGDEBUG, "%s wifi is disconnecting, waiting 100ms for state to stable\r\n", __func__); @@ -1546,12 +1637,6 @@ static int rwnx_close(struct net_device *dev) if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MONITOR) rwnx_hw->monitor_vif = RWNX_INVALID_VIF; - if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_GO) - { - #ifdef CONFIG_COEX - rwnx_send_coex_req(rwnx_hw, 0, 1); - #endif - } rwnx_hw->vif_started--; if (rwnx_hw->vif_started == 0) { @@ -1560,21 +1645,24 @@ static int rwnx_close(struct net_device *dev) rwnx_ipc_tx_drain(rwnx_hw); #else #if defined(AICWF_USB_SUPPORT) - if (usbdev->bus_if->state != BUS_DOWN_ST && usbdev->state != USB_DOWN_ST) { + if (usbdev->bus_if->state != BUS_DOWN_ST && usbdev->state != USB_DOWN_ST) #else - if (sdiodev->bus_if->state != BUS_DOWN_ST) { + if (sdiodev->bus_if->state != BUS_DOWN_ST) #endif + { rwnx_send_reset(rwnx_hw); #if defined(AICWF_USB_SUPPORT) if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81)&& testmode == 0)) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)&& testmode == 0)) { #endif // Set parameters to firmware rwnx_send_me_config_req(rwnx_hw); // Set channel parameters to firmware - rwnx_send_me_chan_config_req(rwnx_hw); + rwnx_send_me_chan_config_req(rwnx_hw, country_code); #if defined(AICWF_USB_SUPPORT) } #endif @@ -1611,7 +1699,7 @@ static int rwnx_do_ioctl(struct net_device *net, struct ifreq *req, int cmd) break; case (SIOCDEVPRIVATE+1): AICWFDBG(LOGINFO, "IOCTL PRIVATE\n"); - android_priv_cmd(net, req, cmd); + ret = android_priv_cmd(net, req, cmd); break; default: ret = -EOPNOTSUPP; @@ -1694,6 +1782,11 @@ static const struct net_device_ops rwnx_netdev_ops = { static const struct net_device_ops rwnx_netdev_monitor_ops = { .ndo_open = rwnx_open, .ndo_stop = rwnx_close, + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0) + .ndo_siocdevprivate = rwnx_do_ioctl, + #else + .ndo_do_ioctl = rwnx_do_ioctl, + #endif #ifdef CONFIG_RWNX_MON_XMIT .ndo_start_xmit = rwnx_start_monitor_if_xmit, .ndo_select_queue = rwnx_select_queue, @@ -1909,7 +2002,7 @@ static struct rwnx_vif *rwnx_interface_add(struct rwnx_hw *rwnx_hw, #endif #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) if (cfg80211_register_netdevice(ndev)) #else if (register_netdevice(ndev)) @@ -1996,6 +2089,156 @@ void aicwf_p2p_alive_timeout(struct timer_list *t) spin_unlock_bh(&rwnx_hw->cb_lock); } +#ifdef CONFIG_DYNAMIC_PERPWR +void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi) +{ + int rssi_avg; + + rssi_avg = (sta->rssi_save + rssi) / 2; + sta->rssi_save = rssi_avg; + + //printk("New RSSI: %d, Average RSSI: %d\n", rssi, rssi_avg); + + if(rssi_avg > RSSI_THD_0) { + if (sta->per_pwrloss != PWR_LOSS_LVL0) { + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL0)) { + //printk("delay p1\n"); + return; + } + schedule_work(&sta->per_pwr_work); + sta->per_pwrloss = PWR_LOSS_LVL0; + sta->last_jiffies = jiffies; + } + } else if ((rssi_avg > RSSI_THD_1) && (rssi_avg <= RSSI_THD_0)) { + if (sta->per_pwrloss != PWR_LOSS_LVL1) { + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL1)) { + //printk("delay p2\n"); + return; + } + schedule_work(&sta->per_pwr_work); + sta->per_pwrloss = PWR_LOSS_LVL1; + sta->last_jiffies = jiffies; + } + } else if ((rssi_avg > RSSI_THD_2) && (rssi_avg <= RSSI_THD_1)) { + if (sta->per_pwrloss != PWR_LOSS_LVL2) { + if ((jiffies_to_msecs(jiffies - sta->last_jiffies) < PWR_DELAY_TIME) && (sta->per_pwrloss >= PWR_LOSS_LVL2)) { + //printk("delay p3\n"); + return; + } + schedule_work(&sta->per_pwr_work); + sta->per_pwrloss = PWR_LOSS_LVL2; + sta->last_jiffies = jiffies; + } + } else if (rssi_avg <= RSSI_THD_2) { + if (sta->per_pwrloss != PWR_LOSS_LVL3) { + schedule_work(&sta->per_pwr_work); + sta->per_pwrloss = PWR_LOSS_LVL3; + sta->last_jiffies = jiffies; + } + } +} + +void aicwf_txpwer_per_sta_worker(struct work_struct *work) +{ + struct rwnx_sta *sta; + sta = container_of(work, struct rwnx_sta, per_pwr_work); + + AICWFDBG(LOGINFO, "per_sta_worker: idx: %d\n", sta->sta_idx); + rwnx_send_txpwr_per_sta_req(g_rwnx_plat->usbdev->rwnx_hw, sta); +} +#endif + +#ifdef CONFIG_DYNAMIC_PWR +void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value) +{ + AICWFDBG(LOGINFO, "set_txpwrloss_ctrl: %d\n", value); + set_txpwr_loss_ofst(value); + if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW) { + rwnx_send_txpwr_lvl_req(rwnx_hw); + } else if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81)) { + rwnx_send_txpwr_lvl_v3_req(rwnx_hw); + } else if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) || + (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)) { + rwnx_send_txpwr_lvl_v4_req(rwnx_hw); + } +} + +void aicwf_pwrloss_worker(struct work_struct *work) +{ + struct rwnx_hw *rwnx_hw; + struct rwnx_vif *rwnx_vif; + struct mm_get_sta_info_cfm cfm; + int ret = 0; + s8 rssi; + + rwnx_hw = container_of(work, struct rwnx_hw, pwrloss_work); + rwnx_vif = rwnx_hw->read_rssi_vif; + if (!dynamic_pwr) { + if (rwnx_hw->pwrloss_lvl != 0) { + set_txpwrloss_ctrl(rwnx_hw, 0); + } + mod_timer(&rwnx_hw->pwrloss_timer, jiffies + msecs_to_jiffies(RSSI_GET_INTERVAL)); + return; + } + if(atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ + ret = rwnx_send_get_sta_info_req(rwnx_hw, rwnx_hw->sta_rssi_idx, &cfm); + if(ret < 0) { + AICWFDBG(LOGINFO, "rwnx_send_get_sta_info_req: %dn", ret); + return; + } + rssi = (s8)cfm.rssi; + AICWFDBG(LOGINFO, "%s: rssi:%d lvl : %d\n", __func__, rssi, rwnx_hw->pwrloss_lvl); + if(rssi > RSSI_THD_0) { + if (rwnx_hw->pwrloss_lvl != PWR_LOSS_LVL0) { + set_txpwrloss_ctrl(rwnx_hw, PWR_LOSS_LVL0); + rwnx_hw->pwrloss_lvl = PWR_LOSS_LVL0; + } + } else if ((rssi > RSSI_THD_1) && (rssi <= RSSI_THD_0)) { + if (rwnx_hw->pwrloss_lvl != PWR_LOSS_LVL1) { + set_txpwrloss_ctrl(rwnx_hw, PWR_LOSS_LVL1); + rwnx_hw->pwrloss_lvl = PWR_LOSS_LVL1; + } + } else if ((rssi > RSSI_THD_2) && (rssi <= RSSI_THD_1)) { + if (rwnx_hw->pwrloss_lvl != PWR_LOSS_LVL2) { + set_txpwrloss_ctrl(rwnx_hw, PWR_LOSS_LVL2); + rwnx_hw->pwrloss_lvl = PWR_LOSS_LVL2; + } + } else if (rssi <= RSSI_THD_2) { + if (rwnx_hw->pwrloss_lvl != PWR_LOSS_LVL3) { + set_txpwrloss_ctrl(rwnx_hw, PWR_LOSS_LVL3); + rwnx_hw->pwrloss_lvl = PWR_LOSS_LVL3; + } + } + } else if (atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTED){ + if (rwnx_hw->pwrloss_lvl != 0) { + set_txpwrloss_ctrl(rwnx_hw, 0); + rwnx_hw->pwrloss_lvl = 0; + } + } + mod_timer(&rwnx_hw->pwrloss_timer, jiffies + msecs_to_jiffies(RSSI_GET_INTERVAL)); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) +static void aicwf_pwrloss_timer(ulong data) +#else +static void aicwf_pwrloss_timer(struct timer_list *t) +#endif +{ + struct rwnx_hw *rwnx_hw; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + rwnx_vif = (struct rwnx_vif *)data; + rwnx_hw = rwnx_vif->rwnx_hw; +#else + rwnx_hw = from_timer(rwnx_hw, t, pwrloss_timer); +#endif + if (!work_pending(&rwnx_hw->pwrloss_work)) + schedule_work(&rwnx_hw->pwrloss_work); + return; + +} +#endif /********************************************************************* * Cfg80211 callbacks (and helper) @@ -2089,7 +2332,7 @@ static struct wireless_dev *rwnx_virtual_interface_add(struct rwnx_hw *rwnx_hw, * and a given role. */ -static struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw, +struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 *addr, __le16 fc, bool ap) { @@ -2191,11 +2434,7 @@ static int rwnx_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wde #if 0 if (rwnx_vif == rwnx_hw->p2p_dev_vif) { if (timer_pending(&rwnx_hw->p2p_alive_timer)) { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete_sync(&rwnx_hw->p2p_alive_timer); - #else - del_timer_sync(&rwnx_hw->p2p_alive_timer); - #endif + del_timer_sync(&rwnx_hw->p2p_alive_timer); } } #endif @@ -2215,7 +2454,7 @@ static int rwnx_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wde AICWFDBG(LOGINFO, "%s Remove Interface \r\n", dev->name); if (dev->reg_state == NETREG_REGISTERED) { /* Will call rwnx_close if interface is UP */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0) cfg80211_unregister_netdevice(dev); #else unregister_netdevice(dev); @@ -2255,12 +2494,6 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy, RWNX_DBG(RWNX_FN_ENTRY_STR); AICWFDBG(LOGINFO, "change_if: %d to %d, %d, %d\r\n", vif->wdev.iftype, type, NL80211_IFTYPE_P2P_CLIENT, NL80211_IFTYPE_STATION); -#ifdef CONFIG_COEX - if (type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_P2P_GO) - rwnx_send_coex_req(vif->rwnx_hw, 1, 0); - if (RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_AP || RWNX_VIF_TYPE(vif) == NL80211_IFTYPE_P2P_GO) - rwnx_send_coex_req(vif->rwnx_hw, 0, 1); -#endif #ifndef CONFIG_RWNX_MON_DATA if ((type == NL80211_IFTYPE_MONITOR) && (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_MONITOR)) { @@ -2444,11 +2677,7 @@ static void rwnx_cfgp2p_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev if (rwnx_vif == rwnx_hw->p2p_dev_vif) { rwnx_hw->is_p2p_alive = 0; if (timer_pending(&rwnx_hw->p2p_alive_timer)) { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - timer_delete_sync(&rwnx_hw->p2p_alive_timer); - #else - del_timer_sync(&rwnx_hw->p2p_alive_timer); - #endif + del_timer_sync(&rwnx_hw->p2p_alive_timer); } if (rwnx_vif->up) { rwnx_send_remove_if(rwnx_hw, rwnx_vif->vif_index, true); @@ -2753,12 +2982,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, RWNX_DBG(RWNX_FN_ENTRY_STR); #if 1 -#if 0 - if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED){ - AICWFDBG(LOGERROR, "%s driver was connected return it \r\n", __func__); - return -EALREADY; - } -#endif + if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTED) { AICWFDBG(LOGDEBUG, "%s this connection is roam \r\n", __func__); rwnx_vif->sta.is_roam = true; @@ -2769,11 +2993,16 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTING|| (int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_CONNECTING) { AICWFDBG(LOGERROR, "%s driver is disconnecting or connecting ,return it \r\n", __func__); - return -EALREADY; + return 0; } #endif - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING); + if(rwnx_vif->sta.is_roam){ + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_ROAMING); + }else{ + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTING); + } + if(is_wep) { if(sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { @@ -2872,54 +3101,42 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, RWNX_DBG(RWNX_FN_ENTRY_STR); AICWFDBG(LOGINFO, "%s drv_vif_index:%d disconnect reason:%d \r\n", __func__, rwnx_vif->drv_vif_index, reason_code); - rwnx_vif->is_conn = 0; -#if 0 - while(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING){ - AICWFDBG(LOGERROR, "%s driver connecting waiting 100ms \r\n", __func__); - msleep(100); - retry--; - if(retry == 0){ - break; - } - if(rwnx_hw->usbdev->state == USB_DOWN_ST){ - break; - } - } - if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){ - - atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); - } -#endif - if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING){ - AICWFDBG(LOGINFO, "%s call cfg80211_connect_result reason:%d \r\n", - __func__, reason_code); - rwnx_vif->is_conn = 1; - msleep(500); - } + if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTED) { + AICWFDBG(LOGERROR, "%s this\r\n",__func__); + WARN_ON(1); + return -EBUSY; + } + if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTING) { AICWFDBG(LOGERROR, "%s wifi is disconnecting, return it:%d \r\n", __func__, reason_code); return -EBUSY; } - if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED){ - atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); + if(atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTED|| + atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_CONNECTING|| + atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_ROAMING){ + + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTING); #ifdef CONFIG_USE_WIRELESS_EXT - memset(rwnx_hw->wext_essid, 0, 32); + memset(rwnx_hw->wext_essid, 0, 33); #endif key_flag = true; return(rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, reason_code)); - }else{ + } +#if 0 + else{ cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, reason_code?reason_code:WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC); - atomic_set(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); return 0; } - +#endif + return 0; } #ifdef CONFIG_SCHED_SCAN @@ -3106,6 +3323,13 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy, sta->acm = 0; sta->key.hw_idx = 0; +#ifdef CONFIG_DYNAMIC_PERPWR + sta->rssi_save = 0; + sta->per_pwrloss = 0; + sta->last_jiffies = jiffies; + INIT_WORK(&sta->per_pwr_work, aicwf_txpwer_per_sta_worker); +#endif + if (params->local_pm != NL80211_MESH_POWER_UNKNOWN) sta->mesh_pm = params->local_pm; else @@ -3145,6 +3369,19 @@ static int rwnx_cfg80211_add_station(struct wiphy *wiphy, #endif cfg80211_new_sta(rwnx_vif->ndev, sta->mac_addr, &sinfo, GFP_KERNEL); } + +#ifdef CONFIG_BAND_STEERING + struct tmp_feature_sta *f_sta = &rwnx_hw->feature_table[rwnx_vif->ap.tmp_sta_idx]; + AICWFDBG(LOGSTEER, "usb %s idx: %d, supp_band: %d\n ", __func__, rwnx_vif->ap.tmp_sta_idx, f_sta->supported_band); + if (rwnx_vif->ap.tmp_sta_idx < NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX) + rwnx_vif->ap.tmp_sta_idx++; + else + rwnx_vif->ap.tmp_sta_idx = 0; + + sta->support_band = f_sta->supported_band; + aicwf_nl_send_new_sta_msg(rwnx_vif, sta->mac_addr); +#endif + #ifdef CONFIG_RWNX_BFMER if (rwnx_hw->mod_params->bfmer) rwnx_send_bfmer_enable(rwnx_hw, sta, params->vht_capa); @@ -3204,13 +3441,11 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy, struct aicwf_rx_priv *rx_priv; #endif - //RWNX_DBG(RWNX_FN_ENTRY_STR); - AICWFDBG(LOGDEBUG ,"%s: %pM\n", __func__, mac); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0) if (params) mac = params->mac; #endif + AICWFDBG(LOGDEBUG ,"%s: %pM\n", __func__, mac); do { spin_lock_bh(&rwnx_hw->cb_lock); @@ -3276,6 +3511,18 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy, } #endif +#ifdef CONFIG_DYNAMIC_PERPWR + cur->rssi_save = 0; + cur->per_pwrloss = 0; + cur->last_jiffies = 0; + cancel_work_sync(&cur->per_pwr_work); +#endif +#ifdef CONFIG_BAND_STEERING + aicwf_nl_send_del_sta_msg(rwnx_vif, cur->mac_addr); + cur->link_time = 0; + cur->rssi = 0; + cur->support_band = 0; +#endif rwnx_txq_sta_deinit(rwnx_hw, cur); error = rwnx_send_me_sta_del(rwnx_hw, cur->sta_idx, false); if ((error != 0) && (error != -EPIPE)) @@ -3662,6 +3909,11 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) rwnx_vif->ap.aic_index = 0; #endif +#ifdef CONFIG_BAND_STEERING + rwnx_vif->ap.band = (enum band_type)((settings->chandef).chan)->band; + rwnx_vif->ap.freq = ((settings->chandef).chan)->center_freq; + rwnx_vif->ap.tmp_sta_idx = 0; +#endif sta = &rwnx_hw->sta_table[apm_start_cfm.bcmc_idx]; sta->valid = true; sta->aid = 0; @@ -3718,6 +3970,32 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev, ((settings->chandef).width)); } +#ifdef CONFIG_BAND_STEERING + if (!error) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + init_timer(&rwnx_vif->steer_timer); + rwnx_vif->steer_timer.data = (ulong)rwnx_vif; + rwnx_vif->steer_timer.function = aicwf_steering_timeout; +#else + timer_setup(&rwnx_vif->steer_timer, aicwf_steering_timeout, 0); +#endif + aicwf_nl_hook(rwnx_vif, rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx); + + INIT_WORK(&rwnx_vif->steer_work, aicwf_steering_work); + for (int i = 0; i < MAX_PENDING_PROBES; i++) { + rwnx_vif->pb_pool[i].in_use = false; + INIT_WORK(&rwnx_vif->pb_pool[i].rsp_work, rwnx_probersp_work); + } + rwnx_vif->rsp_wq = create_workqueue("aic_usb_rsp_wq"); + if (!rwnx_vif->rsp_wq) { + AICWFDBG(LOGERROR, "%s create rsp_wq fail\n", __func__); + return -ENOBUFS; + } + rwnx_vif->ap.start = true; + mod_timer(&rwnx_vif->steer_timer, jiffies + msecs_to_jiffies(STEER_UPFATE_TIME)); + } +#endif + end: //rwnx_ipc_elem_var_deallocs(rwnx_hw, &elem); @@ -3781,7 +4059,7 @@ static int rwnx_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *d /** * * @stop_ap: Stop being an AP, including stopping beaconing. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) +#if (LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION) static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, unsigned int link_id) #else static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) @@ -3797,6 +4075,21 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) netif_tx_stop_all_queues(dev); netif_carrier_off(dev); + /* delete any remaining STA*/ + while (!list_empty(&rwnx_vif->ap.sta_list)) { + rwnx_cfg80211_del_station_compat(wiphy, dev, NULL); + } + +#ifdef CONFIG_BAND_STEERING + rwnx_vif->ap.start = false; + aicwf_nl_hook_deinit(rwnx_vif->ap.band, rwnx_vif->rwnx_hw->iface_idx); + if (timer_pending(&rwnx_vif->steer_timer)) + del_timer_sync(&rwnx_vif->steer_timer); + cancel_work_sync(&rwnx_vif->steer_work); + flush_workqueue(rwnx_vif->rsp_wq); + destroy_workqueue(rwnx_vif->rsp_wq); +#endif + if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) rwnx_hw->is_p2p_connected = 0; rwnx_radar_cancel_cac(&rwnx_hw->radar); @@ -3805,17 +4098,11 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) rwnx_chanctx_unlink(rwnx_vif); spin_unlock_bh(&rwnx_hw->cb_lock); - /* delete any remaining STA*/ - while (!list_empty(&rwnx_vif->ap.sta_list)) { - rwnx_cfg80211_del_station_compat(wiphy, dev, NULL); - } - /* delete BC/MC STA */ sta = &rwnx_hw->sta_table[rwnx_vif->ap.bcmc_index]; rwnx_txq_vif_deinit(rwnx_hw, rwnx_vif); rwnx_del_bcn(&rwnx_vif->ap.bcn); rwnx_del_csa(rwnx_vif); - flush_workqueue(rwnx_vif->sta_probe.apmprobesta_wq); destroy_workqueue(rwnx_vif->sta_probe.apmprobesta_wq); @@ -3845,12 +4132,13 @@ cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1, } #endif -static int rwnx_cfg80211_set_monitor_channel( - struct wiphy *wiphy, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) - struct net_device *, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_chan_def *chandef) +#else +static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) #endif - struct cfg80211_chan_def *chandef) { struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_vif *rwnx_vif; @@ -3903,6 +4191,23 @@ static int rwnx_cfg80211_set_monitor_channel( return 0; } + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_chan_def *chandef) +{ + return rwnx_cfg80211_set_monitor_channel(wiphy, dev, chandef); +} +#else +int rwnx_cfg80211_set_monitor_channel_(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + return rwnx_cfg80211_set_monitor_channel(wiphy, chandef); +} +#endif + + /** * @probe_client: probe an associated client, must return a cookie that it * later passes to cfg80211_probe_status(). @@ -4359,7 +4664,7 @@ static int rwnx_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *net #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) static int rwnx_cfg80211_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2)) +#if LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION unsigned int link_id, #endif struct cfg80211_chan_def *chandef) @@ -4375,13 +4680,11 @@ static int rwnx_cfg80211_get_channel(struct wiphy *wiphy, if (rwnx_vif->vif_index == rwnx_hw->monitor_vif) { //retrieve channel from firmware - rwnx_cfg80211_set_monitor_channel( - wiphy, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) - NULL, -#endif - NULL - ); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0)) + rwnx_cfg80211_set_monitor_channel(wiphy, wdev->netdev, NULL); +#else + rwnx_cfg80211_set_monitor_channel(wiphy, NULL); +#endif } //Check if channel context is valid @@ -4476,6 +4779,16 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, break; } +#ifdef CONFIG_BAND_STEERING + if (ieee80211_is_assoc_resp(mgmt->frame_control)) { + AICWFDBG(LOGSTEER, "usb assoc_resp: da: %pM\n", mgmt->da); + if (aicwf_band_steering_block_chk(rwnx_vif, mgmt->da)) { + AICWFDBG(LOGSTEER, "[STEERING] usb assoc_rsp refuse temp, %pM\n", mgmt->da); + return 0; + } + } +#endif + /* Get STA on which management frame has to be sent */ rwnx_sta = rwnx_retrieve_sta(rwnx_hw, rwnx_vif, mgmt->da, mgmt->frame_control, ap); @@ -4565,17 +4878,17 @@ int rwnx_cfg80211_start_radar_detection(struct wiphy *wiphy, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) , u32 cac_time_ms #endif - #if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0)) , int link_id - #endif - - +#endif ) { struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_vif *rwnx_vif = netdev_priv(dev); struct apm_start_cac_cfm cfm; + printk("%s\n", __func__); + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) rwnx_radar_start_cac(&rwnx_hw->radar, cac_time_ms, rwnx_vif); #endif @@ -4719,11 +5032,10 @@ int rwnx_cfg80211_channel_switch(struct wiphy *wiphy, goto end; } else { INIT_WORK(&csa->work, rwnx_csa_finish); - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0) - cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); + cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); #elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION4 - cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0); + cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false, 0); #elif LINUX_VERSION_CODE >= HIGH_KERNEL_VERSION2 cfg80211_ch_switch_started_notify(dev, &csa->chandef, 0, params->count, false); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0) @@ -4734,6 +5046,11 @@ int rwnx_cfg80211_channel_switch(struct wiphy *wiphy, } +#ifdef CONFIG_BAND_STEERING + vif->ap.band = (enum band_type)((params->chandef).chan)->band; + vif->ap.freq = ((params->chandef).chan)->center_freq; +#endif + end: return error; } @@ -4992,71 +5309,203 @@ int rwnx_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev, return res; } -static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, - struct station_info *sinfo) -{ +enum { + PHYMODE_B, + PHYMODE_G, + PHYMODE_A, + PHYMODE_N, + PHYMODE_AC, + PHYMODE_AX +}; +static const u32 legacy_map_to_rate[12] = { //Kbps + 1000, 2000, 5500, 11000, 6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000 +}; + +static const u32 he_mcs_map_to_rate[2][3][3][12] = { //NSS/GI/BW/MCS + { //1ss + { //0.8us + { 8600, 17200, 25800, 34400, 51600, 68800, 77400, 86000, 103200, 114700, 129000, 143400}, + {17200, 34400, 51600, 68800, 103200, 137600, 154900, 172100, 206500, 229400, 258100, 286800}, + {36000, 72100, 108100, 144100, 216200, 288200, 324300, 360300, 432400, 480400, 540400, 600400}, + }, + { //1.6us + { 8100, 16300, 24400, 32500, 48800, 65000, 73100, 81300, 97500, 108300, 121900, 135400}, //20M, + {16300, 32500, 48800, 65000, 97500, 130000, 146300, 162500, 195000, 216700, 243800, 270800}, //40M, + {34000, 68100, 102100, 136100, 204200, 272200, 306300, 340300, 408300, 453700, 510400, 567100}, //80M, + }, + { //3.2us + { 7300, 14600, 21900, 29300, 43900, 58500, 65800, 73100, 87800, 97500, 109700, 121900}, + {14600, 29300, 43900, 58500, 87800, 117000, 131600, 146300, 175500, 195000, 219400, 243800}, + {30600, 61300, 91900, 122500, 183800, 245000, 275600, 306300, 367500, 408300, 459400, 510400}, + } + }, + { //2ss + { //0.8us + { 17200, 34400, 51600, 68800, 103200, 137600, 154900, 172100, 206500, 229400, 258100, 286800}, //242tone + { 34400, 68800, 103200, 137600, 206500, 275300, 309700, 344100, 412900, 458800, 516200, 573500}, //484tone + { 72100, 144100, 216200, 288200, 432400, 576500, 648500, 720600, 864700, 960700, 1080900, 1201000}, //996tone + }, + { // 1.6us + { 16300, 32500, 48800, 65000, 97500, 130000, 146300, 162500, 195000, 216700, 243800, 270800}, + { 32500, 65000, 97500, 130000, 195000, 260000, 292500, 325000, 390000, 433300, 487500, 541700}, + { 68100, 136100, 204200, 272200, 408300, 544400, 612500, 680600, 816700, 907400, 1020800, 1134200}, + }, + { // 3.2us + { 14600, 29300, 43900, 58500, 87800, 117000, 131600, 146300, 175500, 195000, 219400, 243800}, + { 29300, 58500, 87800, 117000, 175500, 234000, 263300, 292500, 351000, 390000, 438800, 487500}, + { 61300, 122500, 183800, 245000, 367500, 490000, 551300, 612500, 735000, 816600, 918800, 1020800} + } + } +}; + + +static const u32 vht_mcs_map_to_rate[2][2][3][10] = { //NSS//GI/BW/MCS + { // 1ss + { //LONG GI + { 6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000, 78000}, //20M + { 13500, 27000, 40500, 54000, 81000, 108000, 121500, 135000, 162000, 180000}, //40M + { 29300, 58500, 87800, 117000, 175500, 234000, 263300, 292500, 251000, 390000}, //80M + + }, + + { //SHORT GI + { 7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200, 86700}, + { 15000, 30000, 45000, 60000, 90000, 120000, 135000, 150000, 180000, 200000}, + { 32500, 65000, 97500, 130000, 195000, 260000, 292500, 325000, 390000, 433300}, + + } + }, + { //2ss + { //LONG GI + { 13000, 26000, 39000, 52000, 78000, 104000, 117000, 130000, 156000}, //20M + { 27000, 54000, 81000, 108000, 162000, 216000, 243000, 270000, 324000, 360000}, //40M + { 58500, 117000, 175500, 234000, 351000, 468000, 526500, 585000, 702000, 780000}, //80M + }, + { //SHORT GI + { 14400, 28900, 43300, 57800, 86700, 115600, 130000, 144400, 173300}, //20M + { 30000, 60000, 90000, 120000, 180000, 240000, 270000, 300000, 360000, 400000}, //40M + { 65000, 130000, 195000, 260000, 390000, 520000, 585000, 650000, 780000, 866700}, //80M + } + } +}; + + +static const u32 ht_mcs_map_to_rate[2][2][3][8] = { //NSS//GI/BW/MCS + { // 1SS + { //LONG GI + {6500, 13000, 19500, 26000, 39000, 52000, 58500, 65000}, //20M + {13500, 27000, 40500, 54000, 81000, 108000, 121500, 135000}, //40M + }, + { //SHORT GI + {7200, 14400, 21700, 28900, 43300, 57800, 65000, 72200}, + {15000, 30000, 45000, 60000, 90000, 120000, 135000, 150000}, + } + }, + { // 2SS + { //LONG GI + { 13000, 26000, 39000, 52000, 78000, 104000, 117000, 130000}, //20M + { 27000, 54000, 81000, 108000, 162000, 216000, 243000, 270000}, //40M + }, + { //SHORT GI + { 14400, 28900, 43300, 57800, 86700, 115600, 130000, 144400}, //20M + { 30000, 60000, 90000, 120000, 180000, 240000, 270000, 300000}, //40M + } + + }, +}; + + +int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, + struct station_info *sinfo, u8 *phymode, u32 *tx_phyrate, u32 *rx_phyrate) +{ struct rwnx_sta_stats *stats = &sta->stats; struct rx_vector_1 *rx_vect1 = &stats->last_rx.rx_vect1; union rwnx_rate_ctrl_info *rate_info; struct mm_get_sta_info_cfm cfm; + u8 phymode_local = 0, mcs; + u32 tx_phyrate_local = 0; + u32 rx_phyrate_local = 0; rwnx_send_get_sta_info_req(vif->rwnx_hw, sta->sta_idx, &cfm); sinfo->tx_failed = cfm.txfailed; rate_info = (union rwnx_rate_ctrl_info *)&cfm.rate_info; - - AICWFDBG(LOGDEBUG, "%s ModTx(%d):%d TxIndex:%d ModRx(%d):%d RxHTIndex:%d RxVHTIndex:%d RxHEIndex:%d RSSI:%d \r\n", __func__, - rate_info->bwTx, - rate_info->formatModTx, - rate_info->mcsIndexTx, - rx_vect1->ch_bw, - rx_vect1->format_mod, - rx_vect1->ht.mcs, - rx_vect1->vht.mcs, - rx_vect1->he.mcs, - (s8)cfm.rssi); - + //printk("chan time=%d, busy=%d, tx succ=%d, tx_fail=%d\n", cfm.chan_busy_time, cfm.chan_time, cfm.ack_succ_stat, cfm.ack_fail_stat); + stats->last_chan_busy_time = cfm.chan_busy_time; + stats->last_chan_time = cfm.chan_time; + stats->tx_ack_succ_stat = cfm.ack_succ_stat; + stats->tx_ack_fail_stat = cfm.ack_fail_stat; + stats->last_chan_tx_busy_time = cfm.chan_tx_busy_time; switch (rate_info->formatModTx) { case FORMATMOD_NON_HT: + sinfo->txrate.flags = 0; + sinfo->txrate.legacy = tx_legrates_lut_rate[rate_info->mcsIndexTx]; + sinfo->txrate.nss = 1; + tx_phyrate_local = legacy_map_to_rate[rate_info->mcsIndexTx]; + if(sta->band == NL80211_BAND_2GHZ) + phymode_local = PHYMODE_B; + break; case FORMATMOD_NON_HT_DUP_OFDM: sinfo->txrate.flags = 0; sinfo->txrate.legacy = tx_legrates_lut_rate[rate_info->mcsIndexTx]; + sinfo->txrate.nss = 1; + tx_phyrate_local = legacy_map_to_rate[rate_info->mcsIndexTx]; + if(sta->band == NL80211_BAND_2GHZ) + phymode_local = PHYMODE_G; + else + phymode_local = PHYMODE_A; break; case FORMATMOD_HT_MF: case FORMATMOD_HT_GF: sinfo->txrate.flags = RATE_INFO_FLAGS_MCS; - sinfo->txrate.mcs = rate_info->mcsIndexTx; + sinfo->txrate.mcs = rate_info->mcsIndexTx & 0x7; + sinfo->txrate.nss = ((rate_info->mcsIndexTx >> 3) & 0x7) + 1; + phymode_local = PHYMODE_N; + + tx_phyrate_local = ht_mcs_map_to_rate[sinfo->txrate.nss - 1][rate_info->giAndPreTypeTx][rate_info->bwTx][sinfo->txrate.mcs]; break; case FORMATMOD_VHT: sinfo->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - sinfo->txrate.mcs = rate_info->mcsIndexTx; + sinfo->txrate.mcs = rate_info->mcsIndexTx & 0xF; + sinfo->txrate.nss = ((rate_info->mcsIndexTx >> 4) & 0x7) + 1; + tx_phyrate_local = vht_mcs_map_to_rate[sinfo->txrate.nss - 1][rate_info->giAndPreTypeTx][rate_info->bwTx][sinfo->txrate.mcs]; + //printk("phyrate: %d,%d,%d,%d\n", sinfo->txrate.nss - 1, rate_info->giAndPreTypeTx, rate_info->bwTx, sinfo->txrate.mcs); + phymode_local = PHYMODE_AC; break; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) case FORMATMOD_HE_MU: case FORMATMOD_HE_SU: case FORMATMOD_HE_ER: sinfo->txrate.flags = RATE_INFO_FLAGS_HE_MCS; - sinfo->txrate.mcs = rate_info->mcsIndexTx; + sinfo->txrate.mcs = rate_info->mcsIndexTx & 0xF; + sinfo->txrate.nss = ((rate_info->mcsIndexTx >> 4) & 0x7) + 1; + tx_phyrate_local = he_mcs_map_to_rate[sinfo->txrate.nss - 1][rate_info->giAndPreTypeTx][rate_info->bwTx][sinfo->txrate.mcs]; + phymode_local = PHYMODE_AX; + //printk("phyrate: %d,%d,%d,%d\n", sinfo->txrate.nss - 1, rate_info->giAndPreTypeTx, rate_info->bwTx, sinfo->txrate.mcs); break; #else - //kernel not support he case FORMATMOD_HE_MU: case FORMATMOD_HE_SU: case FORMATMOD_HE_ER: sinfo->txrate.flags = RATE_INFO_FLAGS_VHT_MCS; - if(rate_info->mcsIndexTx > 9){ - sinfo->txrate.mcs = 9; - }else{ - sinfo->txrate.mcs = rate_info->mcsIndexTx; - } + sinfo->txrate.mcs = ((rate_info->mcsIndexTx & 0xF) > 9 ? 9 : (rate_info->mcsIndexTx & 0xF)); + sinfo->txrate.nss = ((rate_info->mcsIndexTx >> 4) & 0x7) + 1; + tx_phyrate_local = he_mcs_map_to_rate[sinfo->txrate.nss - 1][rate_info->giAndPreTypeTx][rate_info->bwTx][sinfo->txrate.mcs]; + phymode_local = PHYMODE_AX; break; #endif default: return -EINVAL; } + if(phymode) + *phymode = phymode_local; + if(tx_phyrate) { + *tx_phyrate = tx_phyrate_local; + AICWFDBG(LOGINFO, "phyrate=%d\n", *tx_phyrate); + } #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) switch (rate_info->bwTx) { case PHY_CHNL_BW_20: @@ -5081,18 +5530,16 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, } #endif - sinfo->txrate.nss = 1; + //sinfo->txrate.nss = 1; sinfo->filled |= (BIT(NL80211_STA_INFO_TX_BITRATE) | BIT(NL80211_STA_INFO_TX_FAILED)); - sinfo->inactive_time = jiffies_to_msecs(jiffies - vif->rwnx_hw->stats.last_tx); sinfo->rx_bytes = vif->net_stats.rx_bytes; sinfo->tx_bytes = vif->net_stats.tx_bytes; sinfo->tx_packets = vif->net_stats.tx_packets; sinfo->rx_packets = vif->net_stats.rx_packets; sinfo->signal = (s8)cfm.rssi; - sinfo->rxrate.nss = 1; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) switch (rx_vect1->ch_bw) { case PHY_CHNL_BW_20: sinfo->rxrate.bw = RATE_INFO_BW_20; @@ -5107,20 +5554,22 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, sinfo->rxrate.bw = RATE_INFO_BW_160; break; default: -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) sinfo->rxrate.bw = RATE_INFO_BW_HE_RU; -#else + #else sinfo->rxrate.bw = RATE_INFO_BW_20; -#endif + #endif break; } -#endif + #endif switch (rx_vect1->format_mod) { case FORMATMOD_NON_HT: case FORMATMOD_NON_HT_DUP_OFDM: sinfo->rxrate.flags = 0; - sinfo->rxrate.legacy = legrates_lut_rate[legrates_lut[rx_vect1->leg_rate]]; + sinfo->rxrate.legacy = legrates_lut[rx_vect1->leg_rate].rate; + sinfo->rxrate.nss = 1; + rx_phyrate_local = legrates_lut[rx_vect1->leg_rate].rate; break; case FORMATMOD_HT_MF: case FORMATMOD_HT_GF: @@ -5128,12 +5577,29 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, if (rx_vect1->ht.short_gi) sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; sinfo->rxrate.mcs = rx_vect1->ht.mcs; + sinfo->rxrate.nss = rx_vect1->ht.num_extn_ss + 1; + + if(rx_vect1->ht.mcs == 32) {//mcs 32 + if(rx_vect1->vht.short_gi) + rx_phyrate_local = 6700; + else + rx_phyrate_local = 6000; + } else { + if(sinfo->rxrate.mcs >= 8) + mcs = sinfo->rxrate.mcs - 8; + else + mcs = sinfo->rxrate.mcs; + rx_phyrate_local = ht_mcs_map_to_rate[rx_vect1->ht.num_extn_ss][rx_vect1->ht.short_gi][rx_vect1->ch_bw][mcs]; + } break; case FORMATMOD_VHT: sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; if (rx_vect1->vht.short_gi) sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; sinfo->rxrate.mcs = rx_vect1->vht.mcs; + sinfo->rxrate.nss = rx_vect1->vht.nss + 1; + rx_phyrate_local = vht_mcs_map_to_rate[rx_vect1->vht.nss][rx_vect1->vht.short_gi][rx_vect1->ch_bw][sinfo->rxrate.mcs]; + //printk("rx:%d,%d,%d,%d\n", rx_vect1->vht.nss, rx_vect1->vht.short_gi, rx_vect1->ch_bw, sinfo->rxrate.mcs); break; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) case FORMATMOD_HE_MU: @@ -5143,7 +5609,11 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, sinfo->rxrate.flags = RATE_INFO_FLAGS_HE_MCS; sinfo->rxrate.mcs = rx_vect1->he.mcs; sinfo->rxrate.he_gi = rx_vect1->he.gi_type; + if (rx_vect1->he.gi_type) + sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI; sinfo->rxrate.he_dcm = rx_vect1->he.dcm; + sinfo->rxrate.nss = rx_vect1->he.nss + 1; + rx_phyrate_local = he_mcs_map_to_rate[rx_vect1->he.nss][rx_vect1->he.gi_type][rx_vect1->ch_bw][sinfo->rxrate.mcs]; break; #else //kernel not support he @@ -5151,17 +5621,18 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, case FORMATMOD_HE_SU: case FORMATMOD_HE_ER: sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS; - if(rx_vect1->he.mcs > 9){ - sinfo->rxrate.mcs = 9; - }else{ - sinfo->rxrate.mcs = rx_vect1->he.mcs; - } + sinfo->rxrate.mcs = (rx_vect1->he.mcs > 9 ? 9 : rx_vect1->he.mcs); + sinfo->rxrate.nss = rx_vect1->he.nss + 1; break; #endif default: return -EINVAL; } + if(rx_phyrate) { + *rx_phyrate = rx_phyrate_local; + AICWFDBG(LOGINFO, "rx_phyrate=%d\n", *rx_phyrate); + } #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) sinfo->filled |= (STATION_INFO_INACTIVE_TIME | @@ -5185,6 +5656,7 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, } + /** * @get_station: get station information for the station identified by @mac */ @@ -5221,7 +5693,7 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy, } if (sta) - return rwnx_fill_station_info(sta, vif, sinfo); + return rwnx_fill_station_info(sta, vif, sinfo, NULL, NULL, NULL); return -ENOENT; } @@ -5234,13 +5706,19 @@ static int rwnx_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *de int idx, u8 *mac, struct station_info *sinfo) { struct rwnx_vif *rwnx_vif = netdev_priv(dev); - struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); + //struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy); struct rwnx_sta *sta_iter, *sta = NULL; - struct mesh_peer_info_cfm peer_info_cfm; + //struct mesh_peer_info_cfm peer_info_cfm; int i = 0; - if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT) + AICWFDBG(LOGDEBUG, "%s enter \r\n", __func__); + +#if 0 + if (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_MESH_POINT){ + AICWFDBG(LOGERROR, "%s NOTSUPP \r\n", __func__); return -ENOTSUPP; + } +#endif list_for_each_entry(sta_iter, &rwnx_vif->ap.sta_list, list) { if (i < idx) { @@ -5255,6 +5733,10 @@ static int rwnx_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *de if (sta == NULL) return -ENOENT; + /* Copy peer MAC address */ + memcpy(mac, &sta->mac_addr, ETH_ALEN); + +#if 0 /* Forward the information to the UMAC */ if (rwnx_send_mesh_peer_info_req(rwnx_hw, rwnx_vif, sta->sta_idx, &peer_info_cfm)) @@ -5286,6 +5768,11 @@ static int rwnx_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *de BIT(NL80211_STA_INFO_PEER_PM) | BIT(NL80211_STA_INFO_NONPEER_PM)); #endif +#endif + + if (sta){ + rwnx_fill_station_info(sta, rwnx_vif, sinfo, NULL, NULL, NULL); + } return 0; } @@ -5792,14 +6279,21 @@ static void rwnx_reg_notifier(struct wiphy *wiphy, printk("%s Enter\r\n", __func__); // For now trust all initiator - rwnx_radar_set_domain(&rwnx_hw->radar, request->dfs_region); +#ifdef CONFIG_RADAR_OR_IR_DETECT + if(request->dfs_region != 0) + rwnx_radar_set_domain(&rwnx_hw->radar, request->dfs_region); +#else + rwnx_radar_set_domain(&rwnx_hw->radar, request->dfs_region); +#endif - if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || - ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81) && testmode == 0)){ - rwnx_send_me_chan_config_req(rwnx_hw); - } + if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || + ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)){ + rwnx_send_me_chan_config_req(rwnx_hw, &request->alpha2[0]); + } } static void rwnx_enable_mesh(struct rwnx_hw *rwnx_hw) @@ -7846,7 +8340,7 @@ static int start_from_bootrom(struct rwnx_hw *rwnx_hw) */ -#ifdef CONFIG_GPIO_WAKEUP + #if defined CONFIG_GPIO_WAKEUP || defined CONFIG_WOWLAN static const struct wiphy_wowlan_support aic_wowlan_support = { .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_MAGIC_PKT, }; @@ -7948,6 +8442,12 @@ int rwnx_ic_system_init(struct rwnx_hw *rwnx_hw){ #ifdef CONFIG_POWER_LIMIT rwnx_plat_powerlimit_load_8800d80(rwnx_hw); #endif + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + rwnx_plat_userconfig_load_8800d80x2(rwnx_hw); + #ifdef CONFIG_POWER_LIMIT + rwnx_plat_powerlimit_load_8800d80x2(rwnx_hw); + #endif } return 0; @@ -7983,6 +8483,10 @@ int rwnx_ic_rf_init(struct rwnx_hw *rwnx_hw){ }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ if ((ret = aicwf_set_rf_config_8800d80(rwnx_hw, &cfm))) return -1; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + if ((ret = aicwf_set_rf_config_8800d80x2(rwnx_hw, &cfm))) + return -1; } #ifdef CONFIG_5M10M rwnx_send_vendor_hwconfig_req(rwnx_hw, hwconfig_id, param, NULL); @@ -7993,19 +8497,20 @@ void aic_ipc_setting(struct rwnx_vif *rwnx_vif){ struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; uint32_t hw_edca = 1; uint32_t hw_cca = 3; - int32_t param[13]; + int32_t param[14]; int32_t cca[5]= {0x10, 0, 0, 0, 0}; - param[0] = 0; param[1] = 0x5e222; param[2] = 0; param[3] = 0; + param[0] = 0xFA522; param[1] = 0xFA522; param[2] = 0xFA522; param[3] = 0xFA522; param[4] = rwnx_vif->vif_index; - param[5] = 0x1e; param[6] = 0; param[7] = 0; param[8] =0;param[9] = 0x5;param[10] = 0x5;param[11] = 0x5;param[12] = 0; + param[5] = 0x1e; param[6] = 0; param[7] = 0; param[8] =0;param[9] = 0x2;param[10] = 0x2;param[11] = 0x7;param[12] = 0;;param[13] = 1; rwnx_send_vendor_hwconfig_req(rwnx_hw, hw_edca, param, NULL); rwnx_send_vendor_hwconfig_req(rwnx_hw, hw_cca, cca, NULL); } - +extern int get_adap_test(void); extern void *aicwf_prealloc_txq_alloc(size_t size); extern int aicwf_vendor_init(struct wiphy *wiphy); +extern char default_ccode[]; int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data) { struct rwnx_hw *rwnx_hw; @@ -8017,6 +8522,7 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data) u8 dflt_mac[ETH_ALEN] = { 0x88, 0x00, 0x33, 0x77, 0x10, 0x99}; struct mm_get_fw_version_cfm fw_version; u8_l mac_addr_efuse[ETH_ALEN]; + u8 mac_addr[ETH_ALEN]; #ifndef USE_5G struct aic_feature_t feature; #endif @@ -8026,7 +8532,6 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data) #endif int nx_remote_sta_max = NX_REMOTE_STA_MAX; - RWNX_DBG(RWNX_FN_ENTRY_STR); @@ -8042,6 +8547,9 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || get_random_bytes(&dflt_mac[4], 2); #endif //#endif +#ifdef CONFIG_POWER_LIMIT + memcpy(country_code, default_ccode, 4); +#endif /* create a new wiphy for use with cfg80211 */ AICWFDBG(LOGINFO, "%s sizeof(struct rwnx_hw):%d \r\n", __func__, (int)sizeof(struct rwnx_hw)); wiphy = wiphy_new(&rwnx_cfg80211_ops, sizeof(struct rwnx_hw)); @@ -8073,6 +8581,8 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || rwnx_hw->is_sched_scan = false; #endif//CONFIG_SCHED_SCAN + aicwf_wakeup_lock_init(rwnx_hw); + rwnx_init_aic(rwnx_hw); /* set device pointer for wiphy */ set_wiphy_dev(wiphy, rwnx_hw->dev); @@ -8098,6 +8608,12 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || } #else memcpy(init_conf.mac_addr, dflt_mac, ETH_ALEN); + + if(wifi_mac_addr != 0){ + sscanf(wifi_mac_addr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",&mac_addr[0],&mac_addr[1],&mac_addr[2],&mac_addr[3],&mac_addr[4],&mac_addr[5]); + if (mac_addr[0] | mac_addr[1] | mac_addr[2] | mac_addr[3]) + memcpy(init_conf.mac_addr, mac_addr, ETH_ALEN); + } #endif rwnx_hw->vif_started = 0; @@ -8128,6 +8644,8 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || rwnx_hw->roc_cookie_cnt = 1; INIT_LIST_HEAD(&rwnx_hw->vifs); + INIT_LIST_HEAD(&rwnx_hw->defrag_list); + spin_lock_init(&rwnx_hw->defrag_lock); mutex_init(&rwnx_hw->mutex); mutex_init(&rwnx_hw->dbgdump_elem.mutex); spin_lock_init(&rwnx_hw->tx_lock); @@ -8162,7 +8680,9 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), rwnx_hw->fwlog_en, &set_start_cfm); } #else - if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ + if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, 0, CO_BIT(5), rwnx_hw->fwlog_en, &set_start_cfm); } else { ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, get_hardware_info(), feature.hwinfo, rwnx_hw->fwlog_en, &set_start_cfm); @@ -8199,7 +8719,7 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || #endif BIT(NL80211_IFTYPE_MONITOR); -#ifdef CONFIG_GPIO_WAKEUP +#if defined CONFIG_GPIO_WAKEUP || defined CONFIG_WOWLAN /* Set WoWLAN flags */ printk("%s Wowlan support\r\n", __func__); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) @@ -8309,12 +8829,18 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || rwnx_enable_mesh(rwnx_hw); rwnx_radar_detection_init(&rwnx_hw->radar); +#ifdef CONFIG_RADAR_OR_IR_DETECT + rwnx_radar_set_domain(&rwnx_hw->radar, NL80211_DFS_FCC); +#endif + /* Set parameters to firmware */ if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81) && testmode == 0)) { + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)) { rwnx_send_me_config_req(rwnx_hw); } @@ -8331,17 +8857,22 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || goto err_register_wiphy; } + if ((rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x001f) + || (rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x0020)) { + rwnx_send_pwm_init_req(rwnx_hw, 8, 1, 1, 400000, 400000, 100, 1, 1, 1); + rwnx_send_pwm_deinit_req(rwnx_hw, 8, 1, 1, 1); + } + /* Update regulatory (if needed) and set channel parameters to firmware (must be done after WiPHY registration) */ rwnx_custregd(rwnx_hw, wiphy); if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801 || ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81) && testmode == 0)) { - rwnx_send_me_chan_config_req(rwnx_hw); - #ifdef CONFIG_COEX - rwnx_send_coex_req(rwnx_hw, 0, 1); - #endif + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && testmode == 0)) { + rwnx_send_me_chan_config_req(rwnx_hw, default_ccode); } *platform_data = rwnx_hw; @@ -8406,8 +8937,34 @@ if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || rwnx_hw->is_p2p_connected = 0; atomic_set(&rwnx_hw->p2p_alive_timer_count, 0); #endif + +#ifdef CONFIG_DYNAMIC_PWR + rwnx_hw->pwrloss_lvl = 0; + rwnx_hw->sta_rssi_idx = 0; + rwnx_hw->read_rssi_vif = vif; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) + init_timer(&rwnx_hw->pwrloss_timer); + rwnx_hw->pwrloss_timer.data = (ulong) vif; + rwnx_hw->pwrloss_timer.function = aicwf_pwrloss_timer; +#else + timer_setup(&rwnx_hw->pwrloss_timer, aicwf_pwrloss_timer, 0); +#endif + INIT_WORK(&rwnx_hw->pwrloss_work, aicwf_pwrloss_worker); + mod_timer(&rwnx_hw->pwrloss_timer, jiffies + msecs_to_jiffies(RSSI_GET_INTERVAL)); +#endif + #ifdef CONFIG_FOR_IPCAM - aic_ipc_setting(vif); + if(!testmode && !get_adap_test()) { + aic_ipc_setting(vif); + } +#endif +#ifdef CONFIG_WOWLAN + rwnx_send_set_pkt_filter_req(rwnx_hw, wowlan_param1); +#endif + +#ifdef CONFIG_BAND_STEERING + rwnx_hw->iface_idx = CONFIG_IFACE_NUMBER - 1; + aicwf_nl_init(); #endif return 0; @@ -8431,6 +8988,7 @@ err_lmac_reqs: //err_platon: //err_config: err_cache: + aicwf_wakeup_lock_deinit(rwnx_hw); wiphy_free(wiphy); err_out: return ret; @@ -8443,6 +9001,7 @@ err_out: void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw) { struct mm_set_stack_start_cfm set_start_cfm; + struct defrag_ctrl_info *defrag_ctrl = NULL; RWNX_DBG(RWNX_FN_ENTRY_STR); @@ -8452,6 +9011,33 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw) rwnx_hw->scanning = 0; rwnx_hw->p2p_working = 0; +#ifdef CONFIG_BAND_STEERING + aicwf_nl_deinit(); +#endif + +#ifdef CONFIG_DYNAMIC_PWR + if(timer_pending(&rwnx_hw->pwrloss_timer)){ + del_timer_sync(&rwnx_hw->pwrloss_timer);} + cancel_work_sync(&rwnx_hw->pwrloss_work); +#endif + + if ((rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x001f) + || (rwnx_hw->usbdev->vid == 0x2604 && rwnx_hw->usbdev->pid == 0x0020)) { + rwnx_set_pwm_tbl(rwnx_hw); + } + + spin_lock_bh(&rwnx_hw->defrag_lock); + if (!list_empty(&rwnx_hw->defrag_list)) { + list_for_each_entry(defrag_ctrl, &rwnx_hw->defrag_list, list) { + list_del_init(&defrag_ctrl->list); + if (timer_pending(&defrag_ctrl->defrag_timer)) + del_timer_sync(&defrag_ctrl->defrag_timer); + dev_kfree_skb(defrag_ctrl->skb); + kfree(defrag_ctrl); + } + } + spin_unlock_bh(&rwnx_hw->defrag_lock); + #ifdef CONFIG_DEBUG_FS rwnx_dbgfs_unregister(rwnx_hw); #endif @@ -8469,6 +9055,8 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw) #ifdef CONFIG_FILTER_TCP_ACK tcp_ack_deinit(rwnx_hw); #endif + aicwf_wakeup_lock_deinit(rwnx_hw); + if(rwnx_hw->wiphy){ wiphy_free(rwnx_hw->wiphy); } @@ -8555,7 +9143,8 @@ static void __exit rwnx_mod_exit(void) rwnx_free_cmd_array(); AICWFDBG(LOGINFO, "%s exit\r\n", __func__); } - +module_param(wifi_mac_addr,charp, 0); +MODULE_PARM_DESC(wifi_mac_addr, "Configures mac addr."); module_init(rwnx_mod_init); module_exit(rwnx_mod_exit); #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 13, 0) diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_main.h b/drivers/aic8800/aic8800_fdrv/rwnx_main.h index 7d06691..ad4e2fc 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_main.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_main.h @@ -15,6 +15,9 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data); void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw); +int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif, + struct station_info *sinfo, u8 *phymode, u32 *tx_phyrate, u32 *rx_phyrate); + extern int testmode; extern u8 chip_id; extern u8 chip_sub_id; @@ -23,4 +26,40 @@ extern u8 chip_mcu_id; #define CHIP_ID_H_MASK 0xC0 #define IS_CHIP_ID_H() ((chip_id & CHIP_ID_H_MASK) == CHIP_ID_H_MASK) +#define RSSI_GET_INTERVAL (10 * 1000) //time interval +#define RSSI_THD_0 (-20) //rssi 0 (dBm) +#define RSSI_THD_1 (-30) //rssi 1 (dBm) +#define RSSI_THD_2 (-75) //rssi 2 (dBm) + +#define PWR_LOSS_LVL0 (-10) //RSSI > RSSI_THD_0 +#define PWR_LOSS_LVL1 (-5 ) //RSSI_THD_1 < RSSI alpha2[0] == alpha2[0]) && (reg_regdb[idx]->alpha2[1] == alpha2[1])){ memcpy(country_code, alpha2, 2); @@ -718,6 +720,9 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) return; } + if(rwnx_hw->usbdev->chipid <= PRODUCT_ID_AIC8800D81) + nss = 1; + rwnx_hw->vht_cap_2G.vht_supported = true; if (rwnx_hw->mod_params->sgi80) rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; @@ -733,9 +738,11 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) rwnx_hw->vht_cap_2G.cap |= 3 << 13; #endif } - if (nss > 1) + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) rwnx_hw->vht_cap_2G.cap |= IEEE80211_VHT_CAP_TXSTBC; - + } // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) rwnx_hw->vht_cap_2G.cap |= rwnx_hw->mod_params->amsdu_rx_max; @@ -782,7 +789,7 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { rwnx_hw->vht_cap_2G.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); rwnx_hw->vht_cap_2G.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; } for (; i < 8; i++) { rwnx_hw->vht_cap_2G.vht_mcs.rx_mcs_map |= cpu_to_le16( @@ -794,8 +801,8 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { rwnx_hw->vht_cap_2G.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); rwnx_hw->vht_cap_2G.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, - IEEE80211_VHT_MCS_SUPPORT_0_8); + //mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, + // IEEE80211_VHT_MCS_SUPPORT_0_9); } for (; i < 8; i++) { rwnx_hw->vht_cap_2G.vht_mcs.tx_mcs_map |= cpu_to_le16( @@ -828,8 +835,11 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) rwnx_hw->vht_cap_5G.cap |= 3 << 13; #endif } - if (nss > 1) - rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_TXSTBC; + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_TXSTBC; + } // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) rwnx_hw->vht_cap_5G.cap |= rwnx_hw->mod_params->amsdu_rx_max; @@ -877,7 +887,7 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { rwnx_hw->vht_cap_5G.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); rwnx_hw->vht_cap_5G.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; } for (; i < 8; i++) { rwnx_hw->vht_cap_5G.vht_mcs.rx_mcs_map |= cpu_to_le16( @@ -889,8 +899,8 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { rwnx_hw->vht_cap_5G.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); rwnx_hw->vht_cap_5G.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, - IEEE80211_VHT_MCS_SUPPORT_0_8); + //mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, + // IEEE80211_VHT_MCS_SUPPORT_0_9); } for (; i < 8; i++) { rwnx_hw->vht_cap_5G.vht_mcs.tx_mcs_map |= cpu_to_le16( @@ -903,6 +913,8 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) #endif rwnx_hw->vht_cap_5G.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_80; } + + rwnx_hw->vht_cap_5G.cap |= IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK; } #endif return; @@ -923,6 +935,10 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) return; } + if(rwnx_hw->usbdev->chipid <= PRODUCT_ID_AIC8800D81){ + nss = 1; + } + band_2GHz->vht_cap.vht_supported = true; if (rwnx_hw->mod_params->sgi80) band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80; @@ -938,9 +954,11 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) band_2GHz->vht_cap.cap |= 3 << 13; #endif } - if (nss > 1) + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) band_2GHz->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; - + } // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) band_2GHz->vht_cap.cap |= rwnx_hw->mod_params->amsdu_rx_max; @@ -987,7 +1005,7 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { band_2GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); band_2GHz->vht_cap.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; } for (; i < 8; i++) { band_2GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16( @@ -999,8 +1017,8 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { band_2GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); band_2GHz->vht_cap.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, - IEEE80211_VHT_MCS_SUPPORT_0_8); + //mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, + // IEEE80211_VHT_MCS_SUPPORT_0_9); } for (; i < 8; i++) { band_2GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16( @@ -1032,8 +1050,12 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) band_5GHz->vht_cap.cap |= 3 << 13; #endif } - if (nss > 1) - band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + band_5GHz->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC; + } // Update the AMSDU max RX size (not shifted as located at offset 0 of the VHT cap) band_5GHz->vht_cap.cap |= rwnx_hw->mod_params->amsdu_rx_max; @@ -1081,7 +1103,7 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); band_5GHz->vht_cap.vht_mcs.rx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9; } for (; i < 8; i++) { band_5GHz->vht_cap.vht_mcs.rx_mcs_map |= cpu_to_le16( @@ -1093,8 +1115,8 @@ static void rwnx_set_vht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) for (i = 0; i < nss; i++) { band_5GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16(mcs_map << (i*2)); band_5GHz->vht_cap.vht_mcs.tx_highest = MAX_VHT_RATE(mcs_map, nss, bw_max); - mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, - IEEE80211_VHT_MCS_SUPPORT_0_8); + //mcs_map = min_t(int, rwnx_hw->mod_params->mcs_map, + // IEEE80211_VHT_MCS_SUPPORT_0_9); } for (; i < 8; i++) { band_5GHz->vht_cap.vht_mcs.tx_mcs_map |= cpu_to_le16( @@ -1131,6 +1153,9 @@ static void rwnx_set_ht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) return; } + if(rwnx_hw->usbdev->chipid <= PRODUCT_ID_AIC8800D81) + nss = 1; + if (rwnx_hw->mod_params->stbc_on) band_2GHz->ht_cap.cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT; if (rwnx_hw->mod_params->ldpc_on) @@ -1142,8 +1167,12 @@ static void rwnx_set_ht_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) } else { band_2GHz->ht_cap.mcs.rx_highest = cpu_to_le16(65 * nss); } - if (nss > 1) - band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + band_2GHz->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC; + } // Update the AMSDU max RX size if (rwnx_hw->mod_params->amsdu_rx_max) @@ -1182,6 +1211,9 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) int nss = rwnx_hw->mod_params->nss; int mcs_map; + if(rwnx_hw->usbdev->chipid <= PRODUCT_ID_AIC8800D81) + nss = 1; + he_cap = (struct ieee80211_sta_he_cap *) &rwnx_he_capa.he_cap; he_cap->has_he = true; he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; @@ -1193,8 +1225,14 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) if (rwnx_hw->mod_params->use_80) { he_cap->ppe_thres[0] |= 0x20; he_cap->ppe_thres[2] |= 0xc0; - he_cap->ppe_thres[3] |= 0x07; + he_cap->ppe_thres[3] |= 0x01; } + if (nss == 2) { + he_cap->ppe_thres[0] |= 0x01; + he_cap->ppe_thres[3] |= 0x70; + he_cap->ppe_thres[4] |= 0x1c; + he_cap->ppe_thres[5] |= 0x07; + } //if (rwnx_hw->mod_params->use_80) { he_cap->he_cap_elem.phy_cap_info[0] |= @@ -1222,6 +1260,13 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) #endif if (rwnx_hw->mod_params->stbc_on) he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ; + } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | @@ -1253,7 +1298,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; #endif - he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; + //he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB; @@ -1265,7 +1310,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; - mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1279,8 +1324,8 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; - mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, - IEEE80211_HE_MCS_SUPPORT_0_7); + //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, + // IEEE80211_HE_MCS_SUPPORT_0_7); } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1312,6 +1357,10 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) //#endif return; } + + if(rwnx_hw->usbdev->chipid <= PRODUCT_ID_AIC8800D81) + nss = 1; + he_cap = (struct ieee80211_sta_he_cap *) &band_2GHz->iftype_data->he_cap; he_cap->has_he = true; he_cap->he_cap_elem.mac_cap_info[2] |= IEEE80211_HE_MAC_CAP2_ALL_ACK; @@ -1323,8 +1372,14 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) if (rwnx_hw->mod_params->use_80) { he_cap->ppe_thres[0] |= 0x20; he_cap->ppe_thres[2] |= 0xc0; - he_cap->ppe_thres[3] |= 0x07; + he_cap->ppe_thres[3] |= 0x01; } + if (nss == 2) { + he_cap->ppe_thres[0] |= 0x01; + he_cap->ppe_thres[3] |= 0x70; + he_cap->ppe_thres[4] |= 0x1c; + he_cap->ppe_thres[5] |= 0x07; + } //if (rwnx_hw->mod_params->use_80) { he_cap->he_cap_elem.phy_cap_info[0] |= @@ -1352,6 +1407,13 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) #endif if (rwnx_hw->mod_params->stbc_on) he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ; + } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | @@ -1383,7 +1445,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; #endif - he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; + //he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | @@ -1401,7 +1463,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; - mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1415,8 +1477,8 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; - mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, - IEEE80211_HE_MCS_SUPPORT_0_7); + //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, + // IEEE80211_HE_MCS_SUPPORT_0_7); } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1438,8 +1500,14 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) if (rwnx_hw->mod_params->use_80) { he_cap->ppe_thres[0] |= 0x20; he_cap->ppe_thres[2] |= 0xc0; - he_cap->ppe_thres[3] |= 0x07; + he_cap->ppe_thres[3] |= 0x01; } + if (nss == 2) { + he_cap->ppe_thres[0] |= 0x01; + he_cap->ppe_thres[3] |= 0x70; + he_cap->ppe_thres[4] |= 0x1c; + he_cap->ppe_thres[5] |= 0x07; + } //if (rwnx_hw->mod_params->use_80) { he_cap->he_cap_elem.phy_cap_info[0] |= @@ -1466,6 +1534,13 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) #endif if (rwnx_hw->mod_params->stbc_on) he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ; + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2) && + rwnx_hw->mod_params->stbc_on == true){ //if (nss > 1) + he_cap->he_cap_elem.phy_cap_info[2] |= IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ; + } + #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0) he_cap->he_cap_elem.phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM | IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 | @@ -1497,7 +1572,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT | IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO; #endif - he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; + //he_cap->he_cap_elem.phy_cap_info[7] |= IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI; he_cap->he_cap_elem.phy_cap_info[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G; #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0) he_cap->he_cap_elem.phy_cap_info[9] |= IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB | @@ -1515,7 +1590,7 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.rx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.rx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.rx_mcs_80p80 |= unsup_for_ss; - mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; + //mcs_map = IEEE80211_HE_MCS_SUPPORT_0_7; } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1529,8 +1604,8 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) he_cap->he_mcs_nss_supp.tx_mcs_80 |= cpu_to_le16(mcs_map << (i*2)); he_cap->he_mcs_nss_supp.tx_mcs_160 |= unsup_for_ss; he_cap->he_mcs_nss_supp.tx_mcs_80p80 |= unsup_for_ss; - mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, - IEEE80211_HE_MCS_SUPPORT_0_7); + //mcs_map = min_t(int, rwnx_hw->mod_params->he_mcs_map, + // IEEE80211_HE_MCS_SUPPORT_0_7); } for (; i < 8; i++) { __le16 unsup_for_ss = cpu_to_le16(IEEE80211_HE_MCS_NOT_SUPPORTED << (i*2)); @@ -1703,21 +1778,33 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy) #endif //check he_mcs max - if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && + if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && rwnx_hw->mod_params->he_mcs_map > IEEE80211_HE_MCS_SUPPORT_0_9){ rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_9; + } else { + rwnx_hw->mod_params->he_mcs_map = IEEE80211_HE_MCS_SUPPORT_0_11; } //check use_80 support if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && rwnx_hw->mod_params->use_80 == true){ rwnx_hw->mod_params->use_80 = false; + } else { + rwnx_hw->mod_params->use_80 = true; } //check sgi80 support if(rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D81X2 && + rwnx_hw->usbdev->chipid != PRODUCT_ID_AIC8800D89X2 && rwnx_hw->mod_params->sgi80 == true){ rwnx_hw->mod_params->sgi80 = false; + } else { + rwnx_hw->mod_params->sgi80 = true; } #ifdef CONFIG_5M10M rwnx_hw->mod_params->he_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_7; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h index 99d3883..64aa62d 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_mod_params.h @@ -66,5 +66,11 @@ int rwnx_handle_dynparams(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy); void rwnx_custregd(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy); void rwnx_enable_wapi(struct rwnx_hw *rwnx_hw); void rwnx_enable_mfp(struct rwnx_hw *rwnx_hw); +struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy, + char *alpha2); + +struct ieee80211_regdomain *getRegdomainFromRwnxDBIndex(struct wiphy *wiphy, + int index); + #endif /* _RWNX_MOD_PARAM_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c b/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c index fb19bf4..3402681 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_rx.c @@ -396,6 +396,40 @@ static inline int rwnx_rx_pktloss_notify_ind(struct rwnx_hw *rwnx_hw, return 0; } +static inline int rwnx_radar_detect_ind(struct rwnx_hw *rwnx_hw, + struct rwnx_cmd *cmd, + struct ipc_e2a_msg *msg) +{ + struct radar_pulse_array_desc *pulses = (struct radar_pulse_array_desc *)msg->param; + int i; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + //printk("%s\n", __func__); + + if(pulses->cnt == 0) { + printk("cnt error\n"); + return -1; + } + + if(rwnx_radar_detection_is_enable(&rwnx_hw->radar, pulses->idx)) { + for(i=0; icnt; i++) { + struct rwnx_radar_pulses *p = &rwnx_hw->radar.pulses[pulses->idx]; + + p->buffer[p->index] = pulses->pulse[i]; + p->index = (p->index + 1)%RWNX_RADAR_PULSE_MAX; + if(p->count < RWNX_RADAR_PULSE_MAX) + p->count++; + //printk("pulse=%x\n", pulses->pulse[i]); + } + + if(!work_pending(&rwnx_hw->radar.detection_work)) + schedule_work(&rwnx_hw->radar.detection_work); + } else + printk("not enable\n"); + + return 0; +} + static inline int rwnx_apm_staloss_ind(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd, struct ipc_e2a_msg *msg) @@ -681,6 +715,11 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, struct ieee80211_channel *chan; struct scanu_result_ind *ind = (struct scanu_result_ind *)msg->param; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)ind->payload; + u64 tsf; + u8 *ie; + size_t ielen; + u16 capability, beacon_interval; + u16 len = ind->length; #if 0 const u8 *ie = mgmt->u.beacon.variable; @@ -699,20 +738,34 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq); if (chan != NULL) { - #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) - //ktime_t ts; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0) struct timespec ts; - get_monotonic_boottime(&ts); - //ts = ktime_get_real(); + get_monotonic_boottime(&ts); + tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) + ts.tv_nsec/1000; - #else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) + struct timespec ts; + ts = ktime_to_timespec(ktime_get_boottime()); + tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); + mgmt->u.probe_resp.timestamp = tsf; +#else struct timespec64 ts; - ktime_get_real_ts64(&ts); - mgmt->u.probe_resp.timestamp = ((u64)ts.tv_sec*1000000) + ts.tv_nsec/1000; - #endif - bss = cfg80211_inform_bss_frame(rwnx_hw->wiphy, chan, - (struct ieee80211_mgmt *)ind->payload, - ind->length, ind->rssi * 100, GFP_ATOMIC); + ts = ktime_to_timespec64(ktime_get_boottime()); + tsf = (u64)ts.tv_sec * 1000000 + div_u64(ts.tv_nsec, 1000); + mgmt->u.probe_resp.timestamp = tsf; +#endif + ie = mgmt->u.probe_resp.variable; + ielen = len - offsetof(struct ieee80211_mgmt, u.probe_resp.variable); + beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); + capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); + /* framework use system bootup time */ + bss = cfg80211_inform_bss(rwnx_hw->wiphy, chan, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)) + CFG80211_BSS_FTYPE_UNKNOWN, +#endif + mgmt->bssid, tsf, capability, beacon_interval, + ie, ielen, ind->rssi * 100, GFP_ATOMIC); + #if 0 //print scan result info start if(ie != NULL && bss != NULL){ @@ -737,7 +790,12 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, #ifdef CONFIG_USE_WIRELESS_EXT if(rwnx_hw->wext_scan){ - + list_for_each_entry(scan_re_wext, &rwnx_hw->wext_scanre_list, scanu_re_list) { + if (!memcmp(scan_re_wext->bss->bssid, bss->bssid, ETH_ALEN)) { + AICWFDBG(LOGDEBUG, "%s: BSSID already exists, no need to add again\r\n", __func__); + goto putbss; + } + } scan_re_wext = (struct scanu_result_wext *)vmalloc(sizeof(struct scanu_result_wext)); scan_re_wext->ind = (struct scanu_result_ind *)vmalloc(sizeof(struct scanu_result_ind)); scan_re_wext->payload = (u32_l *)vmalloc(sizeof(u32_l) * ind->length); @@ -757,7 +815,7 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw, #endif } - +putbss: if (bss != NULL) #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0) cfg80211_put_bss(bss); @@ -840,6 +898,7 @@ static inline void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, } } #endif + static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd, struct ipc_e2a_msg *msg) @@ -851,9 +910,9 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, const u8 *extcap_ie; const struct ieee_types_extcap *extcap; struct ieee80211_channel *chan; - struct cfg80211_bss *bss = NULL; + //struct cfg80211_bss *bss = NULL; struct wireless_dev *wdev = NULL; - int retry_counter = 10; + //int retry_counter = 10; RWNX_DBG(RWNX_FN_ENTRY_STR); @@ -931,6 +990,13 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, AICWFDBG(LOGDEBUG, "sta idx %d fc error %d\n", sta->sta_idx, atomic_read(&rwnx_hw->sta_flowctrl[sta->sta_idx].tx_pending_cnt)); } +#ifdef CONFIG_RADAR_OR_IR_DETECT + if (chan->flags & IEEE80211_CHAN_RADAR) + rwnx_radar_detection_enable(&rwnx_hw->radar, + RWNX_RADAR_DETECT_REPORT, + RWNX_RADAR_RIU); +#endif + if (rwnx_vif->wep_enabled) rwnx_vif->wep_auth_err = false; @@ -977,9 +1043,9 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, rwnx_vif->wep_auth_err = true; AICWFDBG(LOGINFO, "con ind wep_auth_err %d\n", rwnx_vif->wep_auth_err); } - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); }else{ - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); } @@ -989,84 +1055,21 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, ind->status_code, (int)atomic_read(&rwnx_vif->drv_conn_state)); - do { - bss = cfg80211_get_bss(wdev->wiphy, NULL, rwnx_vif->sta.bssid, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) - wdev->u.client.ssid, wdev->u.client.ssid_len, -#else - wdev->ssid, wdev->ssid_len, -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) - wdev->conn_bss_type, - IEEE80211_PRIVACY_ANY); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) - IEEE80211_BSS_TYPE_ESS, - IEEE80211_PRIVACY_ANY); -#else - WLAN_CAPABILITY_ESS, - WLAN_CAPABILITY_PRIVACY); -#endif + if(ind->status_code == 0 && (int)atomic_read(&rwnx_vif->drv_conn_state) == RWNX_DRV_STATUS_DISCONNECTING){ + AICWFDBG(LOGINFO, "%s the disconnection has been requested, return it\r\n", __func__); + goto exit; + } - if (!bss) { - printk("%s bss is NULL \r\n", __func__); - - printk("%s bss ssid(%d):%s conn_bss_type:%d bss2 ssid(%d):%s conn_bss_type:%d\r\n", - __func__, - (int)rwnx_vif->sta.ssid_len, - rwnx_vif->sta.ssid, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) - IEEE80211_BSS_TYPE_ESS, -#else - WLAN_CAPABILITY_ESS, -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) - (int)wdev->u.client.ssid_len, - wdev->u.client.ssid, -#else - (int)wdev->ssid_len, - wdev->ssid, -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) - wdev->conn_bss_type -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) - IEEE80211_BSS_TYPE_ESS -#else - WLAN_CAPABILITY_ESS -#endif - ); - - printk("%s rwnx_vif->sta.bssid %02x %02x %02x %02x %02x %02x \r\n", __func__, - rwnx_vif->sta.bssid[0], rwnx_vif->sta.bssid[1], rwnx_vif->sta.bssid[2], - rwnx_vif->sta.bssid[3], rwnx_vif->sta.bssid[4], rwnx_vif->sta.bssid[5]); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2) - wdev->u.client.ssid_len = (int)rwnx_vif->sta.ssid_len; - memcpy(wdev->u.client.ssid, rwnx_vif->sta.ssid, wdev->u.client.ssid_len); -#else - wdev->ssid_len = (int)rwnx_vif->sta.ssid_len; - memcpy(wdev->ssid, rwnx_vif->sta.ssid, wdev->ssid_len); -#endif - msleep(100); - retry_counter--; - if(retry_counter == 0){ - printk("%s bss recover fail \r\n", __func__); - break; - } - } - } while (!bss); - if (!ind->roamed) {//not roaming - if (rwnx_vif->is_conn == 0) { cfg80211_connect_result(dev, (const u8 *)ind->bssid.array, req_ie, ind->assoc_req_ie_len, rsp_ie, ind->assoc_rsp_ie_len, ind->status_code, GFP_ATOMIC); - } if (ind->status_code == 0) { - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); } else { - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); } AICWFDBG(LOGINFO, "%s cfg80211_connect_result pass, rwnx_vif->drv_conn_state:%d\r\n", __func__, (int)atomic_read(&rwnx_vif->drv_conn_state)); @@ -1075,7 +1078,7 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, if(ind->status_code != 0){ AICWFDBG(LOGINFO, "%s roaming fail to notify disconnect \r\n", __func__); cfg80211_disconnected(dev, 0, NULL, 0,1, GFP_ATOMIC); - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); rwnx_external_auth_disable(rwnx_vif); }else{ #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) @@ -1099,7 +1102,6 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, info.resp_ie_len = ind->assoc_rsp_ie_len; AICWFDBG(LOGINFO, "%s roaming success to notify roam \r\n", __func__); cfg80211_roamed(dev, &info, GFP_ATOMIC); - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); #else chan = ieee80211_get_channel(rwnx_hw->wiphy, ind->center_freq); AICWFDBG(LOGINFO, "%s roaming success to notify roam \r\n", __func__); @@ -1114,11 +1116,21 @@ static inline int rwnx_rx_sm_connect_ind(struct rwnx_hw *rwnx_hw, , ind->assoc_rsp_ie_len , GFP_ATOMIC); #endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/ - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_CONNECTED); } + rwnx_vif->sta.is_roam = false; } - netif_tx_start_all_queues(dev); - netif_carrier_on(dev); + + if (ind->status_code == 0) { + netif_tx_start_all_queues(dev); + netif_carrier_on(dev); + } + +exit: + rwnx_vif->sta.is_roam = false; +#ifdef CONFIG_DYNAMIC_PWR + rwnx_hw->sta_rssi_idx = ind->ap_idx; +#endif return 0; } @@ -1167,7 +1179,8 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw, struct aicwf_rx_priv *rx_priv; #endif - RWNX_DBG(RWNX_FN_ENTRY_STR); + //RWNX_DBG(RWNX_FN_ENTRY_STR); + AICWFDBG(LOGINFO, "%s reason code:%d \r\n", __func__, ind->reason_code); if((int)atomic_read(&rwnx_vif->drv_conn_state) == (int)RWNX_DRV_STATUS_DISCONNECTED){ AICWFDBG(LOGINFO, "%s, is already disconnected, drop disconnect ind", __func__); return 0; @@ -1187,6 +1200,10 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw, AICWFDBG(LOGINFO, "%s roaming no rwnx_cfg80211_unlink_bss \r\n", __func__); } +#ifdef CONFIG_DEBUG_FS + rwnx_dbgfs_unregister_rc_stat(rwnx_hw, rwnx_vif->sta.ap); +#endif + #ifdef CONFIG_BR_SUPPORT struct rwnx_vif *vif = netdev_priv(dev); /* clear bridge database */ @@ -1245,7 +1262,10 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw, rwnx_chanctx_unlink(rwnx_vif); //msleep(200); - atomic_set(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + if (rwnx_vif->sta.is_roam == false) { + rwnx_set_conn_state(&rwnx_vif->drv_conn_state, (int)RWNX_DRV_STATUS_DISCONNECTED); + } + return 0; } @@ -1265,6 +1285,8 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw, RWNX_DBG(RWNX_FN_ENTRY_STR); + memset((void*)¶ms, 0, sizeof(struct cfg80211_external_auth_params)); + params.action = NL80211_EXTERNAL_AUTH_START; memcpy(params.bssid, ind->bssid.array, ETH_ALEN); params.ssid.ssid_len = ind->ssid.length; @@ -1282,13 +1304,6 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw, } AICWFDBG(LOGINFO, "%s wdev->conn_owner_nlportid:%d \r\n", __func__, (int)wdev->conn_owner_nlportid); - if (wdev->conn_owner_nlportid != 0) { - rwnx_vif->sta.conn_owner_nlportid = wdev->conn_owner_nlportid; - } else { - AICWFDBG(LOGINFO, "%s try to recover conn_owner_nlportid\r\n", __func__); - wdev->conn_owner_nlportid = rwnx_vif->sta.conn_owner_nlportid; - } - if ((ind->vif_idx > NX_VIRT_DEV_MAX) || !rwnx_vif->up || (RWNX_VIF_TYPE(rwnx_vif) != NL80211_IFTYPE_STATION) || (ret = cfg80211_external_auth_request(dev, ¶ms, GFP_ATOMIC))) { @@ -1579,6 +1594,7 @@ static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = { [MSG_I(MM_RSSI_STATUS_IND)] = rwnx_rx_rssi_status_ind, [MSG_I(MM_PKTLOSS_IND)] = rwnx_rx_pktloss_notify_ind, [MSG_I(MM_APM_STALOSS_IND)] = rwnx_apm_staloss_ind, + [MSG_I(MM_RADAR_DETECT_IND)] = rwnx_radar_detect_ind, }; static msg_cb_fct scan_hdlrs[MSG_I(SCANU_MAX)] = { diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c index 278e53f..91b2a14 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.c @@ -22,6 +22,10 @@ #include "aicwf_txrxif.h" #include "rwnx_strs.h" +#ifdef RF_WRITE_FILE +#include +#endif + const struct mac_addr mac_addr_bcst = {{0xFFFF, 0xFFFF, 0xFFFF}}; @@ -67,7 +71,7 @@ const int chnl2bw[] = { [PHY_CHNL_BW_80P80] = NL80211_CHAN_WIDTH_80P80, }; -#define RWNX_CMD_ARRAY_SIZE 20 +#define RWNX_CMD_ARRAY_SIZE 40 #define RWNX_CMD_HIGH_WATER_SIZE RWNX_CMD_ARRAY_SIZE/2 //#define RWNX_MSG_ARRAY_SIZE 20 @@ -131,7 +135,7 @@ static inline bool is_non_blocking_msg(int id) static inline u8_l get_chan_flags(uint32_t flags) { u8_l chan_flags = 0; -#ifdef RADAR_OR_IR_DETECT +#ifdef CONFIG_RADAR_OR_IR_DETECT #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) if (flags & IEEE80211_CHAN_PASSIVE_SCAN) #else @@ -386,7 +390,6 @@ static int rwnx_send_msg(struct rwnx_hw *rwnx_hw, const void *msg_params, struct rwnx_cmd *cmd; bool nonblock; int ret = 0; - u8_l empty = 0; //RWNX_DBG(RWNX_FN_ENTRY_STR); AICWFDBG(LOGDEBUG, "%s (%d)%s reqcfm:%d in_softirq:%d in_atomic:%d\r\n", @@ -444,7 +447,7 @@ static int rwnx_send_msg(struct rwnx_hw *rwnx_hw, const void *msg_params, cmd->flags = RWNX_CMD_FLAG_NONBLOCK; if (reqcfm) cmd->flags |= RWNX_CMD_FLAG_REQ_CFM; - +#if 0 if(cfm != NULL) { do { if(rwnx_hw->cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) @@ -468,7 +471,7 @@ static int rwnx_send_msg(struct rwnx_hw *rwnx_hw, const void *msg_params, } } while(!empty);//wait for cmd queue empty } - +#endif if(reqcfm) { cmd->flags &= ~RWNX_CMD_FLAG_WAIT_ACK; // we don't need ack any more ret = rwnx_hw->cmd_mgr->queue(rwnx_hw->cmd_mgr, cmd); @@ -1139,7 +1142,7 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l * rf_config_req->table_num = 16; rf_config_req->deft_page = 0; - memcpy(rf_config_req->data, tbl, len); + memcpy(rf_config_req->data, tbl, len); /* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */ error = rwnx_send_msg(rwnx_hw, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL); @@ -1147,54 +1150,320 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw, u8_l ofst, u8_l sel, u8_l * return (error); } +#ifdef RF_WRITE_FILE + +#define FW_PATH_MAX_LEN_RF 200 +extern char aic_fw_path[FW_PATH_MAX_LEN_RF]; + +int rwnx_rf_write_file(void *buf, int buf_len) +{ + int sum = 0, len = 0; + char *path = NULL; + struct file *fp = NULL; + loff_t pos = 0; +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0) + mm_segment_t fs; +#endif + + AICWFDBG(LOGINFO, "%s\n", __func__); + path = __getname(); + if (!path) { + AICWFDBG(LOGINFO, "get path fail\n"); + return -1; + } + + len = snprintf(path, FW_PATH_MAX_LEN_RF, "%s/%s", aic_fw_path, FW_RF_CALIB_FILE); + AICWFDBG(LOGINFO, "%s: path=%s\n", __func__,path); + + fp = filp_open(path, O_RDWR | O_CREAT, 0644); + if (IS_ERR(fp)) { + AICWFDBG(LOGINFO, "fp open fial\n"); + __putname(path); + fp = NULL; + return -2; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0) + fs = get_fs(); + set_fs(KERNEL_DS); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + sum = kernel_write(fp, buf, buf_len, &pos); +#else LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + sum = kernel_write(fp, (char *)buf, buf_len, pos); +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 10, 0) + set_fs(fs); +#endif + + __putname(path); + filp_close(fp, NULL); + fp = NULL; + + return 0; + +} + +int is_file_exist_rf(char* name) +{ + char *path = NULL; + struct file *fp = NULL; + int len; + + path = __getname(); + if (!path) { + AICWFDBG(LOGINFO, "%s getname fail\n", __func__); + return -1; + } + + len = snprintf(path, FW_PATH_MAX_LEN_RF, "%s/%s", aic_fw_path, name); + + fp = filp_open(path, O_RDONLY, 0); + if (IS_ERR(fp)) { + __putname(path); + fp = NULL; + return 0; + } else { + __putname(path); + filp_close(fp, NULL); + fp = NULL; + return 1; + } +} +#endif + extern void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap); int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm) { - struct mm_set_rf_calib_req *rf_calib_req; - xtal_cap_conf_t xtal_cap = {0,}; + xtal_cap_conf_t xtal_cap = {0,}; int error; RWNX_DBG(RWNX_FN_ENTRY_STR); + AICWFDBG(LOGINFO, "%s in,chipid=%d\n", __func__,rwnx_hw->usbdev->chipid); + + if((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2) ||(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2)) + { + struct mm_set_rf_calib_req_v2 *rf_calib_req; + struct mm_set_rf_calib_cfm_v2 cfm2; - /* Build the MM_SET_RF_CALIB_REQ message */ - rf_calib_req = rwnx_msg_zalloc(MM_SET_RF_CALIB_REQ, TASK_MM, DRV_TASK_ID, - sizeof(struct mm_set_rf_calib_req)); + /* Build the MM_SET_RF_CALIB_REQ message */ + rf_calib_req = rwnx_msg_zalloc(MM_SET_RF_CALIB_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_rf_calib_req_v2)); - if (!rf_calib_req) { - return -ENOMEM; - } + if (!rf_calib_req) { + return -ENOMEM; + } - if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801){ - rf_calib_req->cal_cfg_24g = 0xbf; - rf_calib_req->cal_cfg_5g = 0x3f; - }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || - rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ - rf_calib_req->cal_cfg_24g = 0x0f8f; - rf_calib_req->cal_cfg_5g = 0; - }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ - rf_calib_req->cal_cfg_24g = 0x0f8f; - rf_calib_req->cal_cfg_5g = 0x0f0f; - } + if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801){ + rf_calib_req->cal_cfg_24g = 0xbf; + rf_calib_req->cal_cfg_5g = 0x3f; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; + } - rf_calib_req->param_alpha = 0x0c34c008; - rf_calib_req->bt_calib_en = 0; - rf_calib_req->bt_calib_param = 0x264203; + rf_calib_req->param_alpha = 0x0c34c008; + rf_calib_req->bt_calib_en = 0; + rf_calib_req->bt_calib_param = 0x264203; - get_userconfig_xtal_cap(&xtal_cap); + get_userconfig_xtal_cap(&xtal_cap); - if (xtal_cap.enable) { - AICWFDBG(LOGINFO, "user xtal cap: %d, cap_fine: %d\n", xtal_cap.xtal_cap, xtal_cap.xtal_cap_fine); - rf_calib_req->xtal_cap = xtal_cap.xtal_cap; - rf_calib_req->xtal_cap_fine = xtal_cap.xtal_cap_fine; - } else { - rf_calib_req->xtal_cap = 0; - rf_calib_req->xtal_cap_fine = 0; + if (xtal_cap.enable) { + AICWFDBG(LOGINFO, "user xtal cap: %d, cap_fine: %d\n", xtal_cap.xtal_cap, xtal_cap.xtal_cap_fine); + rf_calib_req->xtal_cap = xtal_cap.xtal_cap; + rf_calib_req->xtal_cap_fine = xtal_cap.xtal_cap_fine; + } else { + rf_calib_req->xtal_cap = 0; + rf_calib_req->xtal_cap_fine = 0; + } + +#ifdef RF_WRITE_FILE + if(is_file_exist_rf(FW_RF_CALIB_FILE) == 1) + { + void *buffer = NULL; + char *path = NULL; + struct file *fp = NULL; + int size = 0, len = 0;// i = 0; + ssize_t rdlen = 0; + unsigned char decrypt[16]; + //u32 **fw_buf =NULL; + //struct kstat stat; + + + AICWFDBG(LOGINFO, "%s: file exist in\n", __func__); + path = __getname(); + if (!path) + { + return -1; + } + len = snprintf(path, FW_PATH_MAX_LEN_RF, "%s/%s", aic_fw_path, FW_RF_CALIB_FILE); + AICWFDBG(LOGINFO, "%s: path=%s\n", __func__,path); + + if (len >= FW_PATH_MAX_LEN_RF) + { + AICWFDBG(LOGERROR, "%s: %s file's path too long\n", __func__, FW_RF_CALIB_FILE); + __putname(path); + return -2; + } + + fp = filp_open(path, O_RDONLY, 0); + if (IS_ERR_OR_NULL(fp)) + { + AICWFDBG(LOGERROR, "%s: %s file failed to open\n", __func__, FW_RF_CALIB_FILE); + __putname(path); + fp = NULL; + return -3; + } + + //vfs_stat(path, &stat); + size =(int)fp->f_inode->i_size; + AICWFDBG(LOGINFO, "%s: file is %d bytes\n", __func__,size); + buffer = vmalloc(size); + if (!buffer) + { + __putname(path); + filp_close(fp, NULL); + fp = NULL; + return -4; + } + + #if LINUX_VERSION_CODE > KERNEL_VERSION(4, 13, 16) + rdlen = kernel_read(fp, buffer, size, &fp->f_pos); + #else + rdlen = kernel_read(fp, fp->f_pos, buffer, size); + #endif + //rwnx_data_dump("cal_res.res_data",buffer,size); + + if (size != rdlen) + { + AICWFDBG(LOGERROR, "%s: %s file rdlen invalid %d\n", __func__, FW_RF_CALIB_FILE, (int)rdlen); + __putname(path); + filp_close(fp, NULL); + fp = NULL; + vfree(buffer); + buffer = NULL; + return -5; + } + + if (rdlen > 0) + { + fp->f_pos += rdlen; + } + + __putname(path); + filp_close(fp, NULL); + fp = NULL; + + if(rdlen == sizeof(rf_calib_req->cal_res.res_data)) + { + memcpy((u8 *)rf_calib_req->cal_res.res_data,buffer,rdlen); + //SET Demo + rf_calib_req->cal_res.magic_num = DRIVER_SET_WIFI_CALRES_MAGIC_NUM; + rf_calib_req->cal_res.info_flag = 0x4F; + rf_calib_req->cal_res.calib_flag = 0x00; + // before req, write testmode rf calib reg->cal res.res_data[], data read from file + } + else + { + AICWFDBG(LOGERROR, "%s: %s file rdlen %d is not equal rf_calib_req \n", __func__, FW_RF_CALIB_FILE, (int)rdlen); + vfree(buffer); + return -6; + } + vfree(buffer); + } + else +#endif + { + AICWFDBG(LOGINFO, "%s: file not exist in\n", __func__); + //GET Demo + rf_calib_req->cal_res.magic_num = DRIVER_GET_WIFI_CALRES_MAGIC_NUM; + rf_calib_req->cal_res.info_flag = 0x00; + rf_calib_req->cal_res.calib_flag = 0x4F; + // after req, read mm_set_rf_calib_cfm.cal_res.res data[] + // save the data into file + } + /* Send the MM_SET_RF_CALIB_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, rf_calib_req, 1, MM_SET_RF_CALIB_CFM, &cfm2); + +#ifdef RF_WRITE_FILE + if(is_file_exist_rf(FW_RF_CALIB_FILE) != 1) + { + void *buffer = NULL; + int buf_len = sizeof(cfm2.cal_res.res_data); + + AICWFDBG(LOGINFO, "%s: file not exist in2,buf_len=%d\n", __func__,buf_len); + buffer = vmalloc(buf_len); + if (!buffer) + { + return -4; + } + memcpy(buffer,cfm2.cal_res.res_data,buf_len); + //rwnx_data_dump("cal_res.res_data",buffer,buf_len); + rwnx_rf_write_file(buffer,buf_len); + vfree(buffer); + } +#endif + cfm->rxgain_24g_addr = cfm2.rxgain_24g_addr; + cfm->rxgain_5g_addr = cfm2.rxgain_5g_addr; + cfm->txgain_24g_addr = cfm2.txgain_24g_addr; + cfm->txgain_5g_addr = cfm2.txgain_5g_addr; } + else + { + struct mm_set_rf_calib_req *rf_calib_req; + /* Build the MM_SET_RF_CALIB_REQ message */ + rf_calib_req = rwnx_msg_zalloc(MM_SET_RF_CALIB_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_rf_calib_req)); - /* Send the MM_SET_RF_CALIB_REQ message to UMAC FW */ - error = rwnx_send_msg(rwnx_hw, rf_calib_req, 1, MM_SET_RF_CALIB_CFM, cfm); + if (!rf_calib_req) { + return -ENOMEM; + } + if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8801){ + rf_calib_req->cal_cfg_24g = 0xbf; + rf_calib_req->cal_cfg_5g = 0x3f; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + rf_calib_req->cal_cfg_24g = 0x0f8f; + rf_calib_req->cal_cfg_5g = 0x0f0f; + } + + rf_calib_req->param_alpha = 0x0c34c008; + rf_calib_req->bt_calib_en = 0; + rf_calib_req->bt_calib_param = 0x264203; + + get_userconfig_xtal_cap(&xtal_cap); + + if (xtal_cap.enable) { + AICWFDBG(LOGINFO, "user xtal cap: %d, cap_fine: %d\n", xtal_cap.xtal_cap, xtal_cap.xtal_cap_fine); + rf_calib_req->xtal_cap = xtal_cap.xtal_cap; + rf_calib_req->xtal_cap_fine = xtal_cap.xtal_cap_fine; + } else { + rf_calib_req->xtal_cap = 0; + rf_calib_req->xtal_cap_fine = 0; + } + /* Send the MM_SET_RF_CALIB_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, rf_calib_req, 1, MM_SET_RF_CALIB_CFM, cfm); + } + return (error); }; @@ -1366,8 +1635,9 @@ int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, req1->rc_retry_cnt[1] = param[10]; req1->rc_retry_cnt[2] = param[11]; req1->ccademod_th = param[12]; - printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d\n", - req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th); + req1->remove_1m2m = param[13]; + printk("set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d remove_1m2m = %d\n", + req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th, req1->remove_1m2m); /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ error = rwnx_send_msg(rwnx_hw, req1, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); break; @@ -1559,6 +1829,391 @@ int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, return error; } +int rwnx_send_vendor_hwconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out) +{ + struct mm_set_acs_txop_req *req0; + struct mm_set_channel_access_req *req1; + struct mm_set_mac_timescale_req *req2; + struct mm_set_cca_threshold_req *req3; + struct mm_set_bwmode_req *req4; + + int error = 0; + + switch (hwconfig_id) + { + case ACS_TXOP_REQ_X2: + /* Build the ACS_TXOP_REQ message */ + req0= rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_acs_txop_req) ); + if (!req0) + return -ENOMEM; + req0->hwconfig_id = hwconfig_id; + req0->txop_be = param[0]; + req0->txop_bk = param[1]; + req0->txop_vi = param[2]; + req0->txop_vo = param[3]; + AICWFDBG(LOGINFO, "set_acs_txop_req: be: %x,bk: %x,vi: %x,vo: %x\n", + req0->txop_be, req0->txop_bk, req0->txop_vi, req0->txop_vo); + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req0, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + break; + + case CHANNEL_ACCESS_REQ_X2: + /* Build the CHANNEL_ACCESS_REQ message */ + req1 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_channel_access_req)); + if (!req1) + return -ENOMEM; + req1->hwconfig_id = hwconfig_id; + req1->edca[0] = param[0]; + req1->edca[1] = param[1]; + req1->edca[2] = param[2]; + req1->edca[3] = param[3]; + req1->vif_idx = param[4]; + req1->retry_cnt = param[5]; + req1->rts_en = param[6]; + req1->long_nav_en = param[7]; + req1->cfe_en = param[8]; + req1->rc_retry_cnt[0] = param[9]; + req1->rc_retry_cnt[1] = param[10]; + req1->rc_retry_cnt[2] = param[11]; + req1->ccademod_th = param[12]; + req1->remove_1m2m = param[13]; + AICWFDBG(LOGINFO, "set_channel_access_req:edca[]= %x %x %x %x\nvif_idx: %x, retry_cnt: %x, rts_en: %x, long_nav_en: %x, cfe_en: %x, rc_retry_cnt: %x:%x:%x, ccademod_th = %d remove_1m2m = %x\n", + req1->edca[0], req1->edca[1], req1->edca[2], req1->edca[3], req1->vif_idx, req1->retry_cnt, req1->rts_en, req1->long_nav_en, req1->cfe_en, req1->rc_retry_cnt[0],req1->rc_retry_cnt[1], req1->rc_retry_cnt[2], req1->ccademod_th, req1->remove_1m2m); + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req1, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + break; + + case MAC_TIMESCALE_REQ_X2: + /* Build the MAC_TIMESCALE_REQ message */ + req2 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_mac_timescale_req)); + if (!req2) + return -ENOMEM; + req2->hwconfig_id = hwconfig_id; + req2->sifsA_time = param[0]; + req2->sifsB_time = param[1]; + req2->slot_time = param[2]; + req2->rx_startdelay_ofdm = param[3]; + req2->rx_startdelay_long = param[4]; + req2->rx_startdelay_short = param[5]; + AICWFDBG(LOGINFO, "set_mac_timescale_req:sifsA_time: %x, sifsB_time: %x, slot_time: %x, rx_startdelay ofdm:%x long %x short %x\n", + req2->sifsA_time, req2->sifsB_time, req2->slot_time, req2->rx_startdelay_ofdm, req2->rx_startdelay_long, req2->rx_startdelay_short); + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req2, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + break; + + case CCA_THRESHOLD_REQ_X2: + /* Build the CCA_THRESHOLD_REQ message */ + req3 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_cca_threshold_req)); + if (!req3) + return -ENOMEM; + req3->hwconfig_id = hwconfig_id; + req3->auto_cca_en = param[0]; + req3->cca20p_rise_th = param[1]; + req3->cca20s_rise_th = param[2]; + req3->cca20p_fall_th = param[3]; + req3->cca20s_fall_th = param[4]; + AICWFDBG(LOGINFO, "cca_threshold_req: auto_cca_en:%d\ncca20p_rise_th = %d\ncca20s_rise_th = %d\ncca20p_fall_th = %d\ncca20s_fall_th = %d\n", + req3->auto_cca_en, req3->cca20p_rise_th, req3->cca20s_rise_th, req3->cca20p_fall_th, req3->cca20s_fall_th); + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req3, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + break; + + case BWMODE_REQ_X2: + /* Build the SET_BWMODE_REQ message */ + req4 = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_bwmode_req)); + if (!req4) + return -ENOMEM; + req4->hwconfig_id = hwconfig_id; + req4->bwmode = param[0]; + AICWFDBG(LOGINFO, "bwmode :%d\n", req4->bwmode); + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req4, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + break; + case CHIP_TEMP_GET_REQ_X2: + //if ((rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DC) || + // (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800DW)) + { + struct mm_get_chip_temp_req *req; + struct mm_set_vendor_hwconfig_cfm cfm = {0,}; + /* Build the CHIP_TEMP_GET_REQ message */ + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_chip_temp_req)); + if (!req) + return -ENOMEM; + req->hwconfig_id = hwconfig_id; + /* Send the MM_SET_VENDOR_HWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, &cfm); + if (!error) { + if (param_out) { + param_out[0] = (int32_t)cfm.chip_temp_cfm.degree; + } + AICWFDBG(LOGINFO, "get_chip_temp degree=%d\n", cfm.chip_temp_cfm.degree); + } else { + AICWFDBG(LOGERROR, "get_chip_temp err=%d\n", error); + } + } + break; + + case STBC_MCS_SET_REQ_X2: + { + struct mm_get_stbc_msc_req *req; + + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_get_stbc_msc_req)); + if (!req) + return -ENOMEM; + req->hwconfig_id = hwconfig_id; + req->enable = (u8)param[0]; + req->mcs_thresh = (u8)param[1]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set_stbc_err =%d\n", error); + } + } + break; + case MAX_AGG_TX_CNT_REQ_X2: + { + struct mm_set_max_tx_agg_cnt_req *req; + + if((u8)param[0] > 1 || (u8)param[1] > 11) { + AICWFDBG(LOGERROR, "hwvendor max_agg_cnt param error:%x,%x\n", (u8)param[0], (u8)param[1]); + break; + } + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_max_tx_agg_cnt_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enale = (u8)param[0]; + req->mcs_thresh = (u8)param[1]; + req->max_agg_cnt[0] = (u8)param[2]; + req->max_agg_cnt[1] = (u8)param[3]; + req->max_agg_cnt[2] = (u8)param[4]; + req->max_agg_cnt[3] = (u8)param[5]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set agg max cnt err=%d\n", error); + } + AICWFDBG(LOGINFO, "hwvendor max_aggr_cnt:en=%d, mcs_thresh=%d, 0x%x, 0x%x, 0x%x, 0x%x\n", req->enale, req->mcs_thresh, req->max_agg_cnt[0], + req->max_agg_cnt[1], req->max_agg_cnt[2], req->max_agg_cnt[3]); + } + break; + case MAX_BW_MCS_THRESH_SET_REQ_X2: + { + struct mm_set_max_bw_mcs_thresh_req *req; + if((u8)param[0] > 1 || (u8)param[1] > 11) { + AICWFDBG(LOGERROR, "hwvendor max_bw_mcs param error:%x,%x\n", (u8)param[0], (u8)param[1]); + break; + } + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_max_bw_mcs_thresh_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enale = (u8)param[0]; + req->max_bw_mcs_thresh = (u8)param[1]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set max_bw_mcs err=%d\n", error); + } + AICWFDBG(LOGINFO, "set max_bw_mcs: enable=%d, thresh=%d\n", (u8)param[0], (u8)param[1]); + } + break; + case DCM_FORCE_EN_REQ_X2: + { + struct mm_set_dcm_force_en_req *req; + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_dcm_force_en_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enable = (u8)param[0]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set dcm_force_en err=%d\n", error); + } + AICWFDBG(LOGINFO, "set dcm_force_en: enable=%d\n", (u8)param[0]); + } + break; + case AUTO_CCA_EN_REQ_X2: + { + struct mm_set_auto_cca_en_req *req; + + if((u8)param[0] > 1 || (int8_t)param[1] > 0 || (u8)param[2] > 1 || (int8_t)param[3]>0) { + AICWFDBG(LOGERROR, "hwvendor auto_cca_en param error:%x,%d,%x,%d\n", (u8)param[0], (int8_t)param[1], + (u8)param[2], (int8_t)param[3]); + break; + } + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_auto_cca_en_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enable = (u8)param[0]; + req->max_cca_thresh = (int8_t)param[1]; + req->default_cca_set = (u8)param[2]; + req->default_cca_thresh = (int8_t)param[3]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set auto cca en err=%d\n", error); + } + AICWFDBG(LOGINFO, "set auto cca en: enable=%d, thresh=%d, default_set=%d, default_thresh=%d\n", + (u8)param[0], (int8_t)param[1], (u8)param[2], (int8_t)param[3]); + } + break; + case NSS_1T2R_REQ_X2: + { + struct mm_set_nss_1t2r_req *req; + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_nss_1t2r_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enable = (u8)param[0]; + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set nss 1t2r err=%d\n", error); + } + AICWFDBG(LOGINFO, "set nss 1t2r: enable=%d\n", (u8)param[0]); + } + break; + case ON_AIR_DUTY_CYCLE_REQ_X2: + { + struct mm_set_on_air_duty_cycle_req *req; + if((u8)param[1]<1 || (u8)param[1] > 100) { + AICWFDBG(LOGERROR, "hwvendor on_air_duty_cycle param error:%x,%x\n", (u8)param[0], (u8)param[1]); + break; + } + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_on_air_duty_cycle_req)); + if (!req) + return -ENOMEM; + + req->hwconfig_id = hwconfig_id; + req->enable = (u8)param[0]; + req->percent = (u8)param[1]; + + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (error) { + AICWFDBG(LOGERROR, "set on_air duty cycle err=%d\n", error); + } + AICWFDBG(LOGINFO, "set on_air duty cycle: enable=%d, percent=%d\n", (u8)param[0], (u8)param[1]); + } + break; + default: + return -ENOMEM; + } + return error; +} + +int rwnx_send_vendor_swconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out) +{ + struct mm_set_vendor_swconfig_req *req; + struct mm_set_vendor_swconfig_cfm cfm = {0,}; + int error; + + req = rwnx_msg_zalloc(MM_SET_VENDOR_SWCONFIG_REQ, TASK_MM, DRV_TASK_ID, sizeof(struct mm_set_vendor_swconfig_req)); + if (!req) { + return -ENOMEM; + } + req->swconfig_id = swconfig_id; + + switch (swconfig_id) + { + case BCN_CFG_REQ_X2: + /* Build the BCN_CFG_REQ message */ + req->bcn_cfg_req.tim_bcmc_ignored_enable = (bool_l)param_in[0]; + AICWFDBG(LOGINFO, "bcn_cfg_req: tim_bcmc_ignd=%d\n", req->bcn_cfg_req.tim_bcmc_ignored_enable); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (int32_t)cfm.bcn_cfg_cfm.tim_bcmc_ignored_status; + AICWFDBG(LOGINFO, "status=%d\n", cfm.bcn_cfg_cfm.tim_bcmc_ignored_status); + } + break; + + case TEMP_COMP_SET_REQ_X2: + /* Build the TEMP_COMP_SET_REQ message */ + req->temp_comp_set_req.enable = (u8_l)param_in[0]; + req->temp_comp_set_req.tmr_period_ms = (u32_l)param_in[1]; + AICWFDBG(LOGINFO, "temp_comp_set_req: en=%d, tmr=%x\n", + req->temp_comp_set_req.enable, req->temp_comp_set_req.tmr_period_ms); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (int32_t)cfm.temp_comp_set_cfm.status; + AICWFDBG(LOGINFO, "status=%d\n", cfm.temp_comp_set_cfm.status); + } + break; + + case TEMP_COMP_GET_REQ_X2: + AICWFDBG(LOGTRACE, "temp_comp_get_req\n"); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (int32_t)cfm.temp_comp_get_cfm.status; + param_out[1] = (int32_t)cfm.temp_comp_get_cfm.degree; + AICWFDBG(LOGINFO, "status=%d, degree=%d\n", + cfm.temp_comp_get_cfm.status, cfm.temp_comp_get_cfm.degree); + } + break; + + case EXT_FLAGS_SET_REQ_X2: + /* Build the EXT_FLAGS_SET_REQ message */ + req->ext_flags_set_req.user_flags = (u32_l)param_in[0]; + AICWFDBG(LOGINFO, "ext_flags_set_req: flags=%x\n", + req->ext_flags_set_req.user_flags); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (uint32_t)cfm.ext_flags_set_cfm.user_flags; + AICWFDBG(LOGINFO, "cfm flags=%x\n", cfm.ext_flags_set_cfm.user_flags); + } + break; + + case EXT_FLAGS_GET_REQ_X2: + /* Build the EXT_FLAGS_GET_REQ message */ + AICWFDBG(LOGTRACE, "ext_flags_get_req\n"); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (uint32_t)cfm.ext_flags_get_cfm.user_flags; + AICWFDBG(LOGINFO, "cfm flags=%x\n", cfm.ext_flags_get_cfm.user_flags); + } + break; + + case EXT_FLAGS_MASK_SET_REQ_X2: + /* Build the EXT_FLAGS_MASK_SET_REQ message */ + req->ext_flags_mask_set_req.user_flags_mask = (u32_l)param_in[0]; + req->ext_flags_mask_set_req.user_flags_val = (u32_l)param_in[1]; + AICWFDBG(LOGINFO, "ext_flags_mask_set_req: flags mask=0x%x, val=0x%x\n", + req->ext_flags_mask_set_req.user_flags_mask, req->ext_flags_mask_set_req.user_flags_val); + /* Send the MM_SET_VENDOR_SWCONFIG_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if (!error) { + param_out[0] = (uint32_t)cfm.ext_flags_mask_set_cfm.user_flags; + AICWFDBG(LOGINFO, "cfm flags=%x\n", cfm.ext_flags_mask_set_cfm.user_flags); + } + break; + case TWO_ANT_RSSI_GET_REQ_X2: + AICWFDBG(LOGINFO, "get 2 ant rssi:\n"); + error = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_SWCONFIG_CFM, &cfm); + if(error) { + AICWFDBG(LOGINFO, "get 2 ant rssi fail\n"); + } else + param_out[0] = *((u32 *)&cfm + 1); + break; + default: + error = -ENOMEM; + break; + } + + return error; +} + + int rwnx_send_mask_set_ext_flags_req(struct rwnx_hw *rwnx_hw, uint32_t flags_mask, uint32_t flags_val, struct mm_set_vendor_swconfig_cfm *cfm) { struct mm_set_vendor_swconfig_req *req; @@ -1675,7 +2330,7 @@ int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw) txpwr_lvl_v2 = &txpwr_lvl_v2_tmp; txpwr_loss = &txpwr_loss_tmp; - txpwr_loss->loss_enable = 0; + txpwr_loss->loss_enable_2g4 = 0; get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_v2); get_userconfig_txpwr_loss(txpwr_loss); @@ -1719,16 +2374,18 @@ int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw) AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[10]); AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v2->pwrlvl_11ax_2g4[11]); - if (txpwr_loss->loss_enable == 1) { - AICWFDBG(LOGINFO, "%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value); + if (txpwr_loss->loss_enable_2g4 == 1) { + AICWFDBG(LOGINFO, "%s:loss_value_2g4: %d\r\n", __func__, + txpwr_loss->loss_value_2g4); + + for (i = 0; i <= 11; i++) + txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 9; i++) + txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 11; i++) + txpwr_lvl_v2->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4; + } - for (i = 0; i <= 11; i++) - txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[i] += txpwr_loss->loss_value; - for (i = 0; i <= 9; i++) - txpwr_lvl_v2->pwrlvl_11n_11ac_2g4[i] += txpwr_loss->loss_value; - for (i = 0; i <= 11; i++) - txpwr_lvl_v2->pwrlvl_11ax_2g4[i] += txpwr_loss->loss_value; - } if ((testmode == 0) && (chip_sub_id == 0)) { txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable; txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M @@ -1771,30 +2428,38 @@ int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw) return -ENOMEM; } - txpwr_lvl_v3 = &txpwr_lvl_v3_tmp; - txpwr_loss = &txpwr_loss_tmp; - txpwr_loss->loss_enable = 0; + txpwr_lvl_v3 = &txpwr_lvl_v3_tmp; + txpwr_loss = &txpwr_loss_tmp; + txpwr_loss->loss_enable_2g4 = 0; + txpwr_loss->loss_enable_5g = 0; - get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_v3); + get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_v3); get_userconfig_txpwr_loss(txpwr_loss); - if (txpwr_loss->loss_enable == 1) { - AICWFDBG(LOGINFO, "%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value); - - for (i = 0; i <= 11; i++) - txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[i] += txpwr_loss->loss_value; - for (i = 0; i <= 9; i++) - txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[i] += txpwr_loss->loss_value; - for (i = 0; i <= 11; i++) - txpwr_lvl_v3->pwrlvl_11ax_2g4[i] += txpwr_loss->loss_value; + if (txpwr_loss->loss_enable_2g4 == 1) { + AICWFDBG(LOGINFO, "%s:loss_value_2g4: %d\r\n", __func__, + txpwr_loss->loss_value_2g4); for (i = 0; i <= 11; i++) - txpwr_lvl_v3->pwrlvl_11a_5g[i] += txpwr_loss->loss_value; - for (i = 0; i <= 9; i++) - txpwr_lvl_v3->pwrlvl_11n_11ac_5g[i] += txpwr_loss->loss_value; - for (i = 0; i <= 11; i++) - txpwr_lvl_v3->pwrlvl_11ax_5g[i] += txpwr_loss->loss_value; - } + txpwr_lvl_v3->pwrlvl_11b_11ag_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 9; i++) + txpwr_lvl_v3->pwrlvl_11n_11ac_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 11; i++) + txpwr_lvl_v3->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4; + } + + if (txpwr_loss->loss_enable_5g == 1) { + AICWFDBG(LOGINFO, "%s:loss_value_5g: %d\r\n", __func__, + txpwr_loss->loss_value_5g); + + for (i = 0; i <= 11; i++) + txpwr_lvl_v3->pwrlvl_11a_5g[i] -= txpwr_loss->loss_value_5g; + for (i = 0; i <= 9; i++) + txpwr_lvl_v3->pwrlvl_11n_11ac_5g[i] -= txpwr_loss->loss_value_5g; + for (i = 0; i <= 11; i++) + txpwr_lvl_v3->pwrlvl_11ax_5g[i] -= txpwr_loss->loss_value_5g; + } + if (txpwr_lvl_v3->enable == 0) { rwnx_msg_free(rwnx_hw, txpwr_lvl_req); @@ -1880,6 +2545,168 @@ int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw) } } +int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw) +{ + struct mm_set_txpwr_lvl_req *txpwr_lvl_req; + txpwr_lvl_conf_v4_t txpwr_lvl_v4_tmp; + txpwr_lvl_conf_v4_t *txpwr_lvl_v4; + txpwr_loss_conf_t txpwr_loss_tmp; + txpwr_loss_conf_t *txpwr_loss; + int error; + int i; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_TXPWR_LVL_REQ message */ + txpwr_lvl_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_txpwr_lvl_req)); + + if (!txpwr_lvl_req) { + return -ENOMEM; + } + + txpwr_lvl_v4 = &txpwr_lvl_v4_tmp; + txpwr_loss = &txpwr_loss_tmp; + txpwr_loss->loss_enable_2g4 = 0; + txpwr_loss->loss_enable_5g = 0; + + get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_v4); + get_userconfig_txpwr_loss(txpwr_loss); + + if (txpwr_loss->loss_enable_2g4 == 1) { + AICWFDBG(LOGINFO, "%s:loss_value_2g4: %d\r\n", __func__, + txpwr_loss->loss_value_2g4); + + for (i = 0; i <= 11; i++) + txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 9; i++) + txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[i] -= txpwr_loss->loss_value_2g4; + for (i = 0; i <= 11; i++) + txpwr_lvl_v4->pwrlvl_11ax_2g4[i] -= txpwr_loss->loss_value_2g4; + } + + if (txpwr_loss->loss_enable_5g == 1) { + AICWFDBG(LOGINFO, "%s:loss_value_5g: %d\r\n", __func__, + txpwr_loss->loss_value_5g); + + for (i = 0; i <= 7; i++) + txpwr_lvl_v4->pwrlvl_11a_5g[i] -= txpwr_loss->loss_value_5g; + for (i = 0; i <= 9; i++) + txpwr_lvl_v4->pwrlvl_11n_11ac_5g[i] -= txpwr_loss->loss_value_5g; + for (i = 0; i <= 11; i++) + txpwr_lvl_v4->pwrlvl_11ax_5g[i] -= txpwr_loss->loss_value_5g; + } + + + if (txpwr_lvl_v4->enable == 0) { + rwnx_msg_free(rwnx_hw, txpwr_lvl_req); + return 0; + } else { + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v4->enable); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[10]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[11]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[10]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[11]); + + AICWFDBG(LOGINFO, "%s:lvl_11a_6m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11a_9m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11a_12m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11a_18m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11a_24m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11a_36m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11a_48m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11a_54m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[8]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[8]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[10]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[11]); + + txpwr_lvl_req->txpwr_lvl_v4 = *txpwr_lvl_v4; + + /* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, txpwr_lvl_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL); + + return (error); + } +} + +#ifdef CONFIG_DYNAMIC_PERPWR +int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta) +{ + struct mm_set_txpwr_lvl_per_sta_req *req; + int ret; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + req = rwnx_msg_zalloc(MM_SET_TXPWR_PER_STA_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_txpwr_lvl_per_sta_req)); + if (!req) { + AICWFDBG(LOGERROR, "%s msg alloc fail\n", __func__); + return -ENOMEM; + } + + AICWFDBG(LOGINFO, "sta_idx: %d, per_pwrloss: %d\r\n", sta->sta_idx, sta->per_pwrloss); + + req->sta_idx = sta->sta_idx; + req->tx_pwr_offset = sta->per_pwrloss; + + AICWFDBG(LOGDEBUG, "per_pwrloss: %d\n", req->tx_pwr_offset); + + ret = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_TXPWR_PER_STA_CFM, NULL); + + return ret; +} + +#endif + int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw) { struct mm_set_txpwr_lvl_adj_req *txpwr_lvl_adj_req; @@ -2009,6 +2836,9 @@ int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw) } if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); + } else if (rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x); } if (txpwr_ofst2x->enable){ AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x->enable); @@ -2040,6 +2870,58 @@ int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw) return (error); } +int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw) +{ + struct mm_set_txpwr_ofst_req *txpwr_ofst_req; + txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2; + int error = 0; + int type, ch_grp; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the MM_SET_TXPWR_OFST_REQ message */ + txpwr_ofst_req = rwnx_msg_zalloc(MM_SET_TXPWR_OFST_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_txpwr_ofst_req)); + + if (!txpwr_ofst_req) { + return -ENOMEM; + } + + txpwr_ofst2x_v2 = &txpwr_ofst_req->txpwr_ofst2x_v2; + txpwr_ofst2x_v2->enable = 0; + + get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_v2); + + if (txpwr_ofst2x_v2->enable){ + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_ofst2x_v2->enable); + AICWFDBG(LOGINFO, "pwrofst2x 2.4g(ant0/ant1): [0]:11b, [1]:ofdm_highrate\n" + " chan=" "\t1-4" "\t5-9" "\t10-13"); + for (type = 0; type < 2; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 3; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d/%d", txpwr_ofst2x_v2->pwrofst2x_tbl_2g4_ant0[ch_grp][type], txpwr_ofst2x_v2->pwrofst2x_tbl_2g4_ant1[ch_grp][type]); + } + } + AICWFDBG(LOGINFO, "\npwrofst2x 5g(ant0/ant1): [0]:ofdm_highrate\n" + " chan=" "\t36-50" "\t51-64" "\t98-114" "\t115-130" "\t131-146" "\t147-166"); + for (type = 0; type < 1; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 6; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d/%d", txpwr_ofst2x_v2->pwrofst2x_tbl_5g_ant0[ch_grp][type], txpwr_ofst2x_v2->pwrofst2x_tbl_5g_ant1[ch_grp][type]); + } + } + AICWFDBG(LOGINFO, "\n"); + + /* Send the MM_SET_TXPWR_OFST_REQ message to UMAC FW */ + error = rwnx_send_msg(rwnx_hw, txpwr_ofst_req, 1, MM_SET_TXPWR_OFST_CFM, NULL); + }else{ + AICWFDBG(LOGINFO, "%s:Do not use txpwr_ofst2x_v2\r\n", __func__); + rwnx_msg_free(rwnx_hw, txpwr_ofst_req); + } + + return (error); +} + int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter) { struct mm_set_filter_req *set_filter_req_param; @@ -2259,11 +3141,18 @@ int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw) /* Send the ME_CONFIG_REQ message to LMAC FW */ return rwnx_send_msg(rwnx_hw, req, 1, ME_CONFIG_CFM, NULL); } -int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw) + +int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw, char *ccode) { struct me_chan_config_req *req; struct wiphy *wiphy = rwnx_hw->wiphy; int i; +#ifdef CONFIG_POWER_LIMIT + int8_t max_pwr; + uint8_t r_idx; + txpwr_loss_conf_t txpwr_loss_tmp; + txpwr_loss_conf_t *txpwr_loss; +#endif RWNX_DBG(RWNX_FN_ENTRY_STR); @@ -2273,6 +3162,21 @@ int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw) if (!req) return -ENOMEM; + +#ifdef CONFIG_POWER_LIMIT + txpwr_loss = &txpwr_loss_tmp; + get_userconfig_txpwr_loss(txpwr_loss); + + if (txpwr_loss->loss_enable_2g4 == 1) + AICWFDBG(LOGINFO, "%s:loss_value_2g4: %d\r\n", __func__, + txpwr_loss->loss_value_2g4); + if (txpwr_loss->loss_enable_5g == 1) + AICWFDBG(LOGINFO, "%s:loss_value_5g: %d\r\n", __func__, + txpwr_loss->loss_value_5g); + + r_idx = get_ccode_region(ccode); +#endif + req->chan2G4_cnt= 0; if (wiphy->bands[NL80211_BAND_2GHZ] != NULL) { struct ieee80211_supported_band *b = wiphy->bands[NL80211_BAND_2GHZ]; @@ -2286,7 +3190,9 @@ int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw) req->chan2G4[req->chan2G4_cnt].tx_power = chan_to_fw_pwr(b->channels[i].max_power); #ifdef CONFIG_POWER_LIMIT { - int8_t max_pwr = get_powerlimit_by_freq(PHY_BAND_2G4, req->chan2G4[req->chan2G4_cnt].freq); + max_pwr = get_powerlimit_by_freq(PHY_BAND_2G4, req->chan2G4[req->chan2G4_cnt].freq, r_idx); + if (txpwr_loss->loss_enable_2g4 == 1) + max_pwr -= txpwr_loss->loss_value_2g4; if (req->chan2G4[req->chan2G4_cnt].tx_power > max_pwr) { req->chan2G4[req->chan2G4_cnt].tx_power = max_pwr; } @@ -2311,7 +3217,9 @@ int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw) req->chan5G[req->chan5G_cnt].tx_power = chan_to_fw_pwr(b->channels[i].max_power); #ifdef CONFIG_POWER_LIMIT { - int8_t max_pwr = get_powerlimit_by_freq(PHY_BAND_5G, req->chan5G[req->chan5G_cnt].freq); + max_pwr = get_powerlimit_by_freq(PHY_BAND_5G, req->chan5G[req->chan5G_cnt].freq, r_idx); + if (txpwr_loss->loss_enable_5g == 1) + max_pwr -= txpwr_loss->loss_value_5g; if (req->chan5G[req->chan5G_cnt].tx_power > max_pwr) { req->chan5G[req->chan5G_cnt].tx_power = max_pwr; } @@ -2378,6 +3286,15 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par #endif RWNX_DBG(RWNX_FN_ENTRY_STR); +#ifdef CONFIG_RADAR_OR_IR_DETECT + if((rwnx_hw->radar.sta_num == 0) && (rwnx_hw->radar.status != RWNX_RADAR_INSERVICE_BUSY)) + rwnx_hw->radar.status = RWNX_RADAR_INSERVICE_BUSY; + + AICWFDBG(LOGINFO, "DFS: assoc add num %d, %d\n", rwnx_hw->radar.sta_num, rwnx_hw->radar.status); + if(rwnx_hw->radar.sta_num < 0x0FFF) + rwnx_hw->radar.sta_num++; +#endif + /* Build the MM_STA_ADD_REQ message */ req = rwnx_msg_zalloc(ME_STA_ADD_REQ, TASK_ME, DRV_TASK_ID, sizeof(struct me_sta_add_req)); @@ -2419,17 +3336,19 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par } #elif defined(CONFIG_VHT_FOR_OLD_KERNEL) if (sta->vht) { - const struct ieee80211_vht_cap *vht_capa = rwnx_vht_capa; + //const struct ieee80211_vht_cap *vht_capa = rwnx_vht_capa; req->flags |= STA_VHT_CAPA; - req->vht_cap.vht_capa_info = cpu_to_le32(vht_capa->vht_cap_info); - req->vht_cap.rx_highest = cpu_to_le16(vht_capa->supp_mcs.rx_highest); - req->vht_cap.rx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.rx_mcs_map); - req->vht_cap.tx_highest = cpu_to_le16(vht_capa->supp_mcs.tx_highest); - req->vht_cap.tx_mcs_map = cpu_to_le16(vht_capa->supp_mcs.tx_mcs_map); + req->vht_cap.vht_capa_info = cpu_to_le32(rwnx_vht_capa->cap); + req->vht_cap.rx_highest = sta->supp_mcs.rx_highest;//cpu_to_le16(rwnx_vht_capa->vht_mcs.rx_highest); + req->vht_cap.rx_mcs_map = sta->supp_mcs.rx_mcs_map;//cpu_to_le16(rwnx_vht_capa->vht_mcs.rx_mcs_map); + req->vht_cap.tx_highest = sta->supp_mcs.tx_highest;//cpu_to_le16(rwnx_vht_capa->vht_mcs.tx_highest); + req->vht_cap.tx_mcs_map = sta->supp_mcs.tx_mcs_map;//cpu_to_le16(rwnx_vht_capa->vht_mcs.tx_mcs_map); } #endif + AICWFDBG(LOGDEBUG,"rx map %x rx high %x tx map %x tx high %x \n",req->vht_cap.rx_mcs_map,req->vht_cap.rx_highest,req->vht_cap.tx_mcs_map,req->vht_cap.tx_highest); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) if (link_sta_params->he_capa) { #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 20, 0) @@ -2462,13 +3381,13 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par (struct ieee80211_he_mcs_nss_supp *)(he_capa + 1); req->flags |= STA_HE_CAPA; for (i = 0; i < ARRAY_SIZE(he_capa->mac_cap_info); i++) { - req->he_cap.mac_cap_info[i] = he_capa->mac_cap_info[i]; + req->he_cap.mac_cap_info[i] = sta->he_cap_elem.mac_cap_info[i];//he_capa->mac_cap_info[i]; } for (i = 0; i < ARRAY_SIZE(he_capa->phy_cap_info); i++) { - req->he_cap.phy_cap_info[i] = he_capa->phy_cap_info[i]; + req->he_cap.phy_cap_info[i] = sta->he_cap_elem.phy_cap_info[i];//he_capa->phy_cap_info[i]; } - req->he_cap.mcs_supp.rx_mcs_80 = mcs_nss_supp->rx_mcs_80; - req->he_cap.mcs_supp.tx_mcs_80 = mcs_nss_supp->tx_mcs_80; + req->he_cap.mcs_supp.rx_mcs_80 = sta->he_mcs_nss_supp.rx_mcs_80;//mcs_nss_supp->rx_mcs_80; + req->he_cap.mcs_supp.tx_mcs_80 = sta->he_mcs_nss_supp.tx_mcs_80;//mcs_nss_supp->tx_mcs_80; req->he_cap.mcs_supp.rx_mcs_160 = mcs_nss_supp->rx_mcs_160; req->he_cap.mcs_supp.tx_mcs_160 = mcs_nss_supp->tx_mcs_160; req->he_cap.mcs_supp.rx_mcs_80p80 = mcs_nss_supp->rx_mcs_80p80; @@ -2477,6 +3396,9 @@ int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *par #endif #endif + AICWFDBG(LOGDEBUG,"rwnx sta add he mcs/nss rx mcs 80 0x%04x \n",le16_to_cpu(req->he_cap.mcs_supp.rx_mcs_80)); + AICWFDBG(LOGDEBUG,"rwnx sta add he mcs/nss tx mcs 80 0x%04x \n",le16_to_cpu(req->he_cap.mcs_supp.tx_mcs_80)); + if (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME)) req->flags |= STA_QOS_CAPA; @@ -2527,6 +3449,15 @@ int rwnx_send_me_sta_del(struct rwnx_hw *rwnx_hw, u8 sta_idx, bool tdls_sta) req->sta_idx = sta_idx; req->tdls_sta = tdls_sta; +#ifdef CONFIG_RADAR_OR_IR_DETECT + if((rwnx_hw->radar.sta_num == 1) && (rwnx_hw->radar.status == RWNX_RADAR_INSERVICE_BUSY)) + rwnx_hw->radar.status = RWNX_RADAR_INSERVICE_DONE; + + AICWFDBG(LOGINFO, "DFS: assoc del num %d, %d\n", rwnx_hw->radar.sta_num, rwnx_hw->radar.status); + if(rwnx_hw->radar.sta_num > 0) + rwnx_hw->radar.sta_num--; +#endif + /* Send the ME_STA_DEL_REQ message to LMAC FW */ return rwnx_send_msg(rwnx_hw, req, 1, ME_STA_DEL_CFM, NULL); } @@ -2743,7 +3674,7 @@ int rwnx_send_sm_connect_req(struct rwnx_hw *rwnx_hw, rwnx_vif->last_auth_type = sme->auth_type; } #ifdef CONFIG_USE_WIRELESS_EXT - memset(rwnx_hw->wext_essid, 0, 32); + memset(rwnx_hw->wext_essid, 0, 33); memcpy(rwnx_hw->wext_essid, sme->ssid, (int)sme->ssid_len); #endif @@ -2887,7 +3818,14 @@ int rwnx_send_apm_start_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, req->chan.band = settings->chandef.chan->band; req->chan.freq = settings->chandef.chan->center_freq; #endif - req->chan.flags = 0; + +#ifdef CONFIG_RADAR_OR_IR_DETECT + req->chan.flags = get_chan_flags(settings->chandef.chan->flags); +#else + req->chan.flags = 0; +#endif + printk("chan.flags %u \n",req->chan.flags); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0) req->chan.tx_power = chan_to_fw_pwr(settings->chandef.chan->max_power); req->center_freq1 = settings->chandef.center_freq1; @@ -3028,7 +3966,7 @@ int rwnx_send_scanu_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, req->bssid = mac_addr_bcst; req->no_cck = param->no_cck; -#ifdef RADAR_OR_IR_DETECT +#ifdef CONFIG_RADAR_OR_IR_DETECT if (req->ssid_cnt == 0) chan_flags |= CHAN_NO_IR; #endif @@ -3171,14 +4109,18 @@ int rwnx_send_apm_start_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif, return -ENOMEM; /* Set parameters for the APM_START_CAC_REQ message */ - req->vif_idx = vif->vif_index; - req->chan.band = chandef->chan->band; - req->chan.freq = chandef->chan->center_freq; - req->chan.flags = 0; - req->center_freq1 = chandef->center_freq1; - req->center_freq2 = chandef->center_freq2; - req->ch_width = bw2chnl[chandef->width]; - + req->vif_idx = vif->vif_index; + req->chan.band = chandef->chan->band; + req->chan.type = bw2chnl[chandef->width]; + req->chan.prim20_freq = chandef->chan->center_freq; + req->chan.center1_freq = chandef->center_freq1; + req->chan.center2_freq = chandef->center_freq2; + req->chan.tx_power = 20; + req->chan.flags = get_chan_flags(chandef->chan->flags); +#ifdef CONFIG_RADAR_OR_IR_DETECT + rwnx_hw->radar.status = RWNX_RADAR_CAC_BUSY; + AICWFDBG(LOGINFO, "DFS: radar st = %d\n", rwnx_hw->radar.status); +#endif /* Send the APM_START_CAC_REQ message to LMAC FW */ return rwnx_send_msg(rwnx_hw, req, 1, APM_START_CAC_CFM, cfm); } @@ -3199,6 +4141,10 @@ int rwnx_send_apm_stop_cac_req(struct rwnx_hw *rwnx_hw, struct rwnx_vif *vif) req->vif_idx = vif->vif_index; /* Send the APM_STOP_CAC_REQ message to LMAC FW */ +#ifdef CONFIG_RADAR_OR_IR_DETECT + rwnx_hw->radar.status = RWNX_RADAR_CAC_DONE; + AICWFDBG(LOGINFO, "DFS: radar st = %d\n", rwnx_hw->radar.status); +#endif return rwnx_send_msg(rwnx_hw, req, 1, APM_STOP_CAC_CFM, NULL); } @@ -3932,6 +4878,27 @@ int rwnx_send_dbg_mem_block_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, return rwnx_send_msg(rwnx_hw, mem_blk_write_req, 1, DBG_MEM_BLOCK_WRITE_CFM, NULL); } +int rwnx_send_dbg_mem_block_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, + u32 mem_size, struct dbg_mem_block_read_cfm *cfm) +{ + struct dbg_mem_block_read_req *mem_blk_read_req; + + //RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the DBG_MEM_BLOCK_READ_REQ message */ + mem_blk_read_req = rwnx_msg_zalloc(DBG_MEM_BLOCK_READ_REQ, TASK_DBG, DRV_TASK_ID, + sizeof(struct dbg_mem_block_read_req)); + if (!mem_blk_read_req) + return -ENOMEM; + + /* Set parameters for the DBG_MEM_BLOCK_READ_REQ message */ + mem_blk_read_req->memaddr = mem_addr; + mem_blk_read_req->memsize = mem_size; + + /* Send the DBG_MEM_BLOCK_READ_REQ message to LMAC FW */ + return rwnx_send_msg(rwnx_hw, mem_blk_read_req, 1, DBG_MEM_BLOCK_READ_CFM, cfm); +} + int rwnx_send_dbg_start_app_req(struct rwnx_hw *rwnx_hw, u32 boot_addr, u32 boot_type) { @@ -4004,6 +4971,49 @@ int rwnx_send_dbg_gpio_init_req(struct rwnx_hw *rwnx_hw, u8_l gpio_idx, u8_l gpi return rwnx_send_msg(rwnx_hw, gpio_init_req, 1, DBG_GPIO_INIT_CFM, NULL); } +#ifdef CONFIG_WOWLAN +int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param) +{ + struct mm_set_wakeup_info_req *req; + int i, err; + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + /* Build the WAKEUP_INFO_REQ message */ + if (param[2] == 0) + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_wakeup_info_req)); + else + req = rwnx_msg_zalloc(MM_SET_VENDOR_HWCONFIG_REQ, TASK_MM, DRV_TASK_ID, + sizeof(struct mm_set_wakeup_info_req) + + 2 * param[2] - 1); + if (!req) + return -ENOMEM; + + req->hwconfig_id = WAKEUP_INFO_REQ; + req->code = (u16_l)param[0]; + req->offset = (u16_l)param[1]; + req->length = (u16_l)param[2]; + AICWFDBG(LOGINFO, + "set_wakeup_info_req: id: 0x%x, offset: 0x%x, length: 0x%x\n", + req->code, req->offset, req->length); + // AICWFDBG(LOG_INFO, "set_wakeup_info_req mask_pattern:\n"); + for (i = 0; i < 2 * req->length; i++) { + req->mask_and_pattern[i] = param[3 + i]; + // AICWFDBG(LOG_INFO, KERN_CONT"%02x ", req->mask_and_pattern[i]); + } + + /* Send the MM_SET_VENDOR_HWCONFIG_CFM message to UMAC FW */ + err = rwnx_send_msg(rwnx_hw, req, 1, MM_SET_VENDOR_HWCONFIG_CFM, NULL); + if (err) { + AICWFDBG(LOGINFO, "%s msg_fail\n", __func__); + return err; + } + + return err; +} +#endif + int rwnx_send_cfg_rssi_req(struct rwnx_hw *rwnx_hw, u8 vif_index, int rssi_thold, u32 rssi_hyst) { struct mm_cfg_rssi_req *req; @@ -4039,4 +5049,78 @@ int rwnx_send_reboot(struct rwnx_hw *rwnx_hw) ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, HOST_START_APP_REBOOT); return ret; } + +int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt, + u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val) +{ + struct dbg_pwm_init_req *pwm_init_req; + + pwm_init_req = rwnx_msg_zalloc(DBG_PWM_INIT_REQ, TASK_DBG, DRV_TASK_ID, + sizeof(struct dbg_pwm_init_req)); + if (!pwm_init_req) + return -ENOMEM; + + pwm_init_req->pwm_gpidx = pwm_gpidx; + pwm_init_req->mode = mode; + pwm_init_req->run = run; + pwm_init_req->tmr_cnt = tmr_cnt; + pwm_init_req->dty_cnt = dty_cnt; + pwm_init_req->step_val = step_val; + pwm_init_req->gpio_en = gpio_en; + pwm_init_req->gpio_dir = gpio_dir; + pwm_init_req->gpio_val = gpio_val; + + + return rwnx_send_msg(rwnx_hw, pwm_init_req, 1, DBG_PWM_INIT_CFM, NULL); +} + +int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val) +{ + struct dbg_pwm_deinit_req *pwm_deinit_req; + + pwm_deinit_req = rwnx_msg_zalloc(DBG_PWM_DEINIT_REQ, TASK_DBG, DRV_TASK_ID, + sizeof(struct dbg_pwm_deinit_req)); + if (!pwm_deinit_req) + return -ENOMEM; + + pwm_deinit_req->pwm_gpidx = pwm_gpidx; + pwm_deinit_req->gpio_en = gpio_en; + pwm_deinit_req->gpio_dir = gpio_dir; + pwm_deinit_req->gpio_val = gpio_val; + + return rwnx_send_msg(rwnx_hw, pwm_deinit_req, 1, DBG_PWM_DEINIT_CFM, NULL); +} + +u32 pwm_tbl[][2] = { + {0x40504088, 4}, +}; + +void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw) +{ + int patch_num = 0; + int cnt = 0; + int ret = 0; + + patch_num = sizeof(pwm_tbl) / sizeof(u32) / 2; + for (cnt = 0; cnt < patch_num; cnt++) { + ret = rwnx_send_dbg_mem_write_req(rwnx_hw, pwm_tbl[cnt][0], pwm_tbl[cnt][1]); + if (ret) { + break; + } + } +} + + //#endif // CONFIG_USB_BT +#ifdef CONFIG_WOWLAN +int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw) +{ + int ret = 0; + u32 delay = 2 *1000; //1s + + RWNX_DBG(RWNX_FN_ENTRY_STR); + + ret = rwnx_send_dbg_start_app_req(rwnx_hw, delay, 6); + return ret; +} +#endif diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h index 5533c52..99277dc 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_msg_tx.h @@ -15,6 +15,11 @@ #include "rwnx_defs.h" +#ifdef RF_WRITE_FILE +#define FW_RF_CALIB_FILE "aic_rf_calib.bin" +#endif + + int rwnx_send_reset(struct rwnx_hw *rwnx_hw); int rwnx_send_start(struct rwnx_hw *rwnx_hw); int rwnx_send_version_req(struct rwnx_hw *rwnx_hw, struct mm_version_cfm *cfm); @@ -67,7 +72,7 @@ int rwnx_send_get_macaddr_req(struct rwnx_hw *rwnx_hw, struct mm_get_mac_addr_cf #ifdef CONFIG_RWNX_FULLMAC int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw); -int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw); +int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw, char *ccode); int rwnx_send_me_set_control_port_req(struct rwnx_hw *rwnx_hw, bool opened, u8 sta_idx); int rwnx_send_me_sta_add(struct rwnx_hw *rwnx_hw, struct station_parameters *params, @@ -153,6 +158,8 @@ int rwnx_send_dbg_get_sys_stat_req(struct rwnx_hw *rwnx_hw, struct dbg_get_sys_stat_cfm *cfm); int rwnx_send_dbg_mem_block_write_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, u32 mem_size, u32 *mem_data); +int rwnx_send_dbg_mem_block_read_req(struct rwnx_hw *rwnx_hw, u32 mem_addr, + u32 mem_size, struct dbg_mem_block_read_cfm *cfm); int rwnx_send_dbg_start_app_req(struct rwnx_hw *rwnx_hw, u32 boot_addr, u32 boot_type); int rwnx_send_dbg_gpio_write_req(struct rwnx_hw *rwnx_hw, u8_l gpio_idx, u8_l gpio_val); @@ -169,19 +176,35 @@ int rwnx_send_set_temp_comp_req(struct rwnx_hw *rwnx_hw, struct mm_set_vendor_sw int rwnx_send_vendor_hwconfig_req(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out); int rwnx_send_vendor_swconfig_req(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out); int rwnx_send_mask_set_ext_flags_req(struct rwnx_hw *rwnx_hw, uint32_t flags_mask, uint32_t flags_val, struct mm_set_vendor_swconfig_cfm *cfm); +int rwnx_send_vendor_hwconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t hwconfig_id, int32_t *param, int32_t *param_out); +int rwnx_send_vendor_swconfig_req_x2(struct rwnx_hw *rwnx_hw, uint32_t swconfig_id, int32_t *param_in, int32_t *param_out); int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_version_cfm *cfm); int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_ofst2x_req(struct rwnx_hw *rwnx_hw); +int rwnx_send_txpwr_ofst2x_v2_req(struct rwnx_hw *rwnx_hw); int rwnx_send_set_filter(struct rwnx_hw *rwnx_hw, uint32_t filter); int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_v3_req(struct rwnx_hw *rwnx_hw); +int rwnx_send_txpwr_lvl_v4_req(struct rwnx_hw *rwnx_hw); int rwnx_send_txpwr_lvl_adj_req(struct rwnx_hw *rwnx_hw); +#ifdef CONFIG_WOWLAN +int rwnx_send_set_pkt_filter_req(struct rwnx_hw *rwnx_hw, u8_l *param); +int rwnx_send_dummy_reboot(struct rwnx_hw *rwnx_hw); +#endif +#ifdef CONFIG_DYNAMIC_PERPWR +int rwnx_send_txpwr_per_sta_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta); +#endif + //#ifdef CONFIG_USB_BT int rwnx_send_reboot(struct rwnx_hw *rwnx_hw); //#endif // CONFIG_USB_BT +int rwnx_send_pwm_init_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 mode, u8 run, u32 tmr_cnt, + u32 dty_cnt, u32 step_val, u8 gpio_en, u8 gpio_dir, u8 gpio_val); +int rwnx_send_pwm_deinit_req(struct rwnx_hw *rwnx_hw, u8 pwm_gpidx, u8 gpio_en, u8 gpio_dir, u8 gpio_val); +void rwnx_set_pwm_tbl(struct rwnx_hw *rwnx_hw); #endif /* _RWNX_MSG_TX_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_platform.c b/drivers/aic8800/aic8800_fdrv/rwnx_platform.c index 97851f9..0392d4c 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_platform.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_platform.c @@ -33,6 +33,7 @@ #include "md5.h" #include "aicwf_compat_8800dc.h" #include "aicwf_compat_8800d80.h" +#include "aicwf_compat_8800d80x2.h" #ifdef CONFIG_USE_FW_REQUEST #include #endif @@ -55,18 +56,6 @@ extern char aic_fw_path[FW_PATH_MAX_LEN]; #define PRINT 2 #define GET_VALUE 3 -typedef struct -{ - txpwr_lvl_conf_t txpwr_lvl; - txpwr_lvl_conf_v2_t txpwr_lvl_v2; - txpwr_lvl_conf_v3_t txpwr_lvl_v3; - txpwr_lvl_adj_conf_t txpwr_lvl_adj; - txpwr_loss_conf_t txpwr_loss; - txpwr_ofst_conf_t txpwr_ofst; - txpwr_ofst2x_conf_t txpwr_ofst2x; - xtal_cap_conf_t xtal_cap; -} userconfig_info_t; - userconfig_info_t userconfig_info = { .txpwr_lvl = { .enable = 1, @@ -113,9 +102,32 @@ userconfig_info_t userconfig_info = { //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 { 20, 20, 20, 20, 18, 18, 16, 16, 16, 15, 14, 14}, }, + .txpwr_lvl_v4 = { + .enable = 1, + .pwrlvl_11b_11ag_2g4 = + //1M, 2M, 5M5, 11M, 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M + { 20, 20, 20, 20, 20, 20, 20, 20, 18, 18, 16, 16}, + .pwrlvl_11n_11ac_2g4 = + //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9 + { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16}, + .pwrlvl_11ax_2g4 = + //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 + { 20, 20, 20, 20, 18, 18, 16, 16, 16, 16, 15, 15}, + .pwrlvl_11a_5g = + //6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M + { 20, 20, 20, 20, 18, 18, 16, 16}, + .pwrlvl_11n_11ac_5g = + //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9 + { 20, 20, 20, 20, 18, 18, 16, 16, 16, 15}, + .pwrlvl_11ax_5g = + //MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10,MCS11 + { 20, 20, 20, 20, 18, 18, 16, 16, 16, 15, 14, 14}, + }, .txpwr_loss = { - .loss_enable = 1, - .loss_value = 0, + .loss_enable_2g4 = 0, + .loss_value_2g4 = 0, + .loss_enable_5g = 0, + .loss_value_5g = 0, }, .txpwr_ofst = { .enable = 1, @@ -142,6 +154,42 @@ userconfig_info_t userconfig_info = { { 0, 0, 0, 0, 0, 0 }, // ofdm_midrate }, }, + .txpwr_ofst2x_v2 = { + .enable = 0, + .pwrofst_flags = 0, + .pwrofst2x_tbl_2g4_ant0 = + { // 11b, ofdm_highrate, ofdm_lowrate + { 0, 0, 0 }, // ch1-4 + { 0, 0, 0 }, // ch5-9 + { 0, 0, 0 }, // ch10-13 + }, + .pwrofst2x_tbl_2g4_ant1 = + { // 11b, ofdm_highrate, ofdm_lowrate + { 0, 0, 0 }, // ch1-4 + { 0, 0, 0 }, // ch5-9 + { 0, 0, 0 }, // ch10-13 + }, + .pwrofst2x_tbl_5g_ant0 = + { // ofdm_highrate, ofdm_lowrate, ofdm_midrate + { 0, 0, 0 }, // ch42 + { 0, 0, 0 }, // ch58 + { 0, 0, 0 }, // ch106 + { 0, 0, 0 }, // ch122 + { 0, 0, 0 }, // ch138 + { 0, 0, 0 }, // ch155 + }, + .pwrofst2x_tbl_5g_ant1 = + { // ofdm_highrate, ofdm_lowrate, ofdm_midrate + { 0, 0, 0 }, // ch42 + { 0, 0, 0 }, // ch58 + { 0, 0, 0 }, // ch106 + { 0, 0, 0 }, // ch122 + { 0, 0, 0 }, // ch138 + { 0, 0, 0 }, // ch155 + }, + .pwrofst2x_tbl_6g_ant0 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 + .pwrofst2x_tbl_6g_ant1 = { 0, }, // ofdm_highrate: 6e_ch7 ~ 6e_ch229 + }, .xtal_cap = { .enable = 0, .xtal_cap = 24, @@ -149,25 +197,257 @@ userconfig_info_t userconfig_info = { }, }; +typedef struct { + char ccode[3]; + Regions_code region; +} reg_table; + +/* If the region conflicts with the kernel, the actual authentication standard prevails */ +reg_table reg_tables[] = { + {.ccode = "CN", .region = REGIONS_SRRC}, + {.ccode = "US", .region = REGIONS_FCC}, + {.ccode = "DE", .region = REGIONS_ETSI}, + {.ccode = "00", .region = REGIONS_DEFAULT}, + {.ccode = "WW", .region = REGIONS_DEFAULT}, + {.ccode = "XX", .region = REGIONS_DEFAULT}, + {.ccode = "JP", .region = REGIONS_JP}, + {.ccode = "AD", .region = REGIONS_ETSI}, + {.ccode = "AE", .region = REGIONS_ETSI}, + {.ccode = "AF", .region = REGIONS_ETSI}, + {.ccode = "AI", .region = REGIONS_ETSI}, + {.ccode = "AL", .region = REGIONS_ETSI}, + {.ccode = "AM", .region = REGIONS_ETSI}, + {.ccode = "AN", .region = REGIONS_ETSI}, + {.ccode = "AR", .region = REGIONS_FCC}, + {.ccode = "AS", .region = REGIONS_FCC}, + {.ccode = "AT", .region = REGIONS_ETSI}, + {.ccode = "AU", .region = REGIONS_ETSI}, + {.ccode = "AW", .region = REGIONS_ETSI}, + {.ccode = "AZ", .region = REGIONS_ETSI}, + {.ccode = "BA", .region = REGIONS_ETSI}, + {.ccode = "BB", .region = REGIONS_FCC}, + {.ccode = "BD", .region = REGIONS_JP}, + {.ccode = "BE", .region = REGIONS_ETSI}, + {.ccode = "BF", .region = REGIONS_FCC}, + {.ccode = "BG", .region = REGIONS_ETSI}, + {.ccode = "BH", .region = REGIONS_ETSI}, + {.ccode = "BL", .region = REGIONS_ETSI}, + {.ccode = "BM", .region = REGIONS_FCC}, + {.ccode = "BN", .region = REGIONS_JP}, + {.ccode = "BO", .region = REGIONS_JP}, + {.ccode = "BR", .region = REGIONS_FCC}, + {.ccode = "BS", .region = REGIONS_FCC}, + {.ccode = "BT", .region = REGIONS_ETSI}, + {.ccode = "BW", .region = REGIONS_ETSI}, + {.ccode = "BY", .region = REGIONS_ETSI}, + {.ccode = "BZ", .region = REGIONS_JP}, + {.ccode = "CA", .region = REGIONS_FCC}, + {.ccode = "CF", .region = REGIONS_FCC}, + {.ccode = "CH", .region = REGIONS_ETSI}, + {.ccode = "CI", .region = REGIONS_FCC}, + {.ccode = "CL", .region = REGIONS_ETSI}, + {.ccode = "CO", .region = REGIONS_FCC}, + {.ccode = "CR", .region = REGIONS_FCC}, + {.ccode = "CX", .region = REGIONS_FCC}, + {.ccode = "CY", .region = REGIONS_ETSI}, + {.ccode = "CZ", .region = REGIONS_ETSI}, + {.ccode = "DK", .region = REGIONS_ETSI}, + {.ccode = "DM", .region = REGIONS_FCC}, + {.ccode = "DO", .region = REGIONS_FCC}, + {.ccode = "DZ", .region = REGIONS_JP}, + {.ccode = "EC", .region = REGIONS_FCC}, + {.ccode = "EE", .region = REGIONS_ETSI}, + {.ccode = "EG", .region = REGIONS_ETSI}, + {.ccode = "ES", .region = REGIONS_ETSI}, + {.ccode = "ET", .region = REGIONS_ETSI}, + {.ccode = "FI", .region = REGIONS_ETSI}, + {.ccode = "FM", .region = REGIONS_FCC}, + {.ccode = "FR", .region = REGIONS_ETSI}, + {.ccode = "GB", .region = REGIONS_ETSI}, + {.ccode = "GD", .region = REGIONS_FCC}, + {.ccode = "GE", .region = REGIONS_ETSI}, + {.ccode = "GF", .region = REGIONS_ETSI}, + {.ccode = "GH", .region = REGIONS_FCC}, + {.ccode = "GI", .region = REGIONS_ETSI}, + {.ccode = "GL", .region = REGIONS_ETSI}, + {.ccode = "GP", .region = REGIONS_ETSI}, + {.ccode = "GR", .region = REGIONS_ETSI}, + {.ccode = "GT", .region = REGIONS_FCC}, + {.ccode = "GU", .region = REGIONS_FCC}, + {.ccode = "GY", .region = REGIONS_DEFAULT}, + {.ccode = "HK", .region = REGIONS_ETSI}, + {.ccode = "HN", .region = REGIONS_FCC}, + {.ccode = "HR", .region = REGIONS_ETSI}, + {.ccode = "HT", .region = REGIONS_FCC}, + {.ccode = "HU", .region = REGIONS_ETSI}, + {.ccode = "ID", .region = REGIONS_ETSI}, + {.ccode = "IE", .region = REGIONS_ETSI}, + {.ccode = "IL", .region = REGIONS_ETSI}, + {.ccode = "IN", .region = REGIONS_ETSI}, + {.ccode = "IQ", .region = REGIONS_ETSI}, + {.ccode = "IR", .region = REGIONS_JP}, + {.ccode = "IS", .region = REGIONS_ETSI}, + {.ccode = "IT", .region = REGIONS_ETSI}, + {.ccode = "JM", .region = REGIONS_FCC}, + {.ccode = "JO", .region = REGIONS_ETSI}, + {.ccode = "KE", .region = REGIONS_ETSI}, + {.ccode = "KG", .region = REGIONS_ETSI}, + {.ccode = "KH", .region = REGIONS_ETSI}, + {.ccode = "KN", .region = REGIONS_ETSI}, + {.ccode = "KP", .region = REGIONS_JP}, + {.ccode = "KR", .region = REGIONS_ETSI}, + {.ccode = "KW", .region = REGIONS_ETSI}, + {.ccode = "KY", .region = REGIONS_FCC}, + {.ccode = "KZ", .region = REGIONS_DEFAULT}, + {.ccode = "LB", .region = REGIONS_ETSI}, + {.ccode = "LC", .region = REGIONS_ETSI}, + {.ccode = "LI", .region = REGIONS_ETSI}, + {.ccode = "LK", .region = REGIONS_FCC}, + {.ccode = "LS", .region = REGIONS_ETSI}, + {.ccode = "LT", .region = REGIONS_ETSI}, + {.ccode = "LU", .region = REGIONS_ETSI}, + {.ccode = "LV", .region = REGIONS_ETSI}, + {.ccode = "LY", .region = REGIONS_ETSI}, + {.ccode = "MA", .region = REGIONS_ETSI}, + {.ccode = "MC", .region = REGIONS_ETSI}, + {.ccode = "MD", .region = REGIONS_ETSI}, + {.ccode = "ME", .region = REGIONS_ETSI}, + {.ccode = "MF", .region = REGIONS_ETSI}, + {.ccode = "MH", .region = REGIONS_FCC}, + {.ccode = "MK", .region = REGIONS_ETSI}, + {.ccode = "MN", .region = REGIONS_ETSI}, + {.ccode = "MO", .region = REGIONS_ETSI}, + {.ccode = "MP", .region = REGIONS_FCC}, + {.ccode = "MQ", .region = REGIONS_ETSI}, + {.ccode = "MR", .region = REGIONS_ETSI}, + {.ccode = "MT", .region = REGIONS_ETSI}, + {.ccode = "MU", .region = REGIONS_FCC}, + {.ccode = "MV", .region = REGIONS_ETSI}, + {.ccode = "MW", .region = REGIONS_ETSI}, + {.ccode = "MX", .region = REGIONS_FCC}, + {.ccode = "MY", .region = REGIONS_FCC}, + {.ccode = "NA", .region = REGIONS_ETSI}, + {.ccode = "NG", .region = REGIONS_ETSI}, + {.ccode = "NI", .region = REGIONS_FCC}, + {.ccode = "NL", .region = REGIONS_ETSI}, + {.ccode = "NO", .region = REGIONS_ETSI}, + {.ccode = "NP", .region = REGIONS_JP}, + {.ccode = "NZ", .region = REGIONS_ETSI}, + {.ccode = "OM", .region = REGIONS_ETSI}, + {.ccode = "PA", .region = REGIONS_FCC}, + {.ccode = "PE", .region = REGIONS_FCC}, + {.ccode = "PF", .region = REGIONS_ETSI}, + {.ccode = "PG", .region = REGIONS_FCC}, + {.ccode = "PH", .region = REGIONS_FCC}, + {.ccode = "PK", .region = REGIONS_ETSI}, + {.ccode = "PL", .region = REGIONS_ETSI}, + {.ccode = "PM", .region = REGIONS_ETSI}, + {.ccode = "PR", .region = REGIONS_FCC}, + {.ccode = "PT", .region = REGIONS_ETSI}, + {.ccode = "PW", .region = REGIONS_FCC}, + {.ccode = "PY", .region = REGIONS_FCC}, + {.ccode = "QA", .region = REGIONS_ETSI}, + {.ccode = "RE", .region = REGIONS_ETSI}, + {.ccode = "RO", .region = REGIONS_ETSI}, + {.ccode = "RS", .region = REGIONS_ETSI}, + {.ccode = "RU", .region = REGIONS_ETSI}, + {.ccode = "RW", .region = REGIONS_FCC}, + {.ccode = "SA", .region = REGIONS_ETSI}, + {.ccode = "SE", .region = REGIONS_ETSI}, + {.ccode = "SG", .region = REGIONS_ETSI}, + {.ccode = "SI", .region = REGIONS_ETSI}, + {.ccode = "SK", .region = REGIONS_ETSI}, + {.ccode = "SM", .region = REGIONS_ETSI}, + {.ccode = "SN", .region = REGIONS_FCC}, + {.ccode = "SR", .region = REGIONS_ETSI}, + {.ccode = "SV", .region = REGIONS_FCC}, + {.ccode = "SY", .region = REGIONS_DEFAULT}, + {.ccode = "TC", .region = REGIONS_FCC}, + {.ccode = "TD", .region = REGIONS_ETSI}, + {.ccode = "TG", .region = REGIONS_ETSI}, + {.ccode = "TH", .region = REGIONS_FCC}, + {.ccode = "TJ", .region = REGIONS_ETSI}, + {.ccode = "TM", .region = REGIONS_ETSI}, + {.ccode = "TN", .region = REGIONS_ETSI}, + {.ccode = "TR", .region = REGIONS_ETSI}, + {.ccode = "TT", .region = REGIONS_FCC}, + {.ccode = "TW", .region = REGIONS_FCC}, + {.ccode = "UA", .region = REGIONS_ETSI}, + {.ccode = "UG", .region = REGIONS_FCC}, + {.ccode = "UY", .region = REGIONS_FCC}, + {.ccode = "UZ", .region = REGIONS_ETSI}, + {.ccode = "VC", .region = REGIONS_ETSI}, + {.ccode = "VE", .region = REGIONS_FCC}, + {.ccode = "VI", .region = REGIONS_FCC}, + {.ccode = "VN", .region = REGIONS_JP}, + {.ccode = "VU", .region = REGIONS_FCC}, + {.ccode = "WF", .region = REGIONS_ETSI}, + {.ccode = "YE", .region = REGIONS_DEFAULT}, + {.ccode = "YT", .region = REGIONS_ETSI}, + {.ccode = "ZA", .region = REGIONS_ETSI}, + {.ccode = "ZM", .region = REGIONS_ETSI}, + {.ccode = "ZW", .region = REGIONS_ETSI}, +}; + +uint8_t get_ccode_region(char * ccode) +{ + int i, cnt; + AICWFDBG(LOGDEBUG, "%s ccode:%s\r\n", __func__, ccode); + + cnt = sizeof(reg_tables) / sizeof(reg_tables[0]); + + for (i = 0; i < cnt; i++) { + if (reg_tables[i].ccode[0] == ccode[0] && + reg_tables[i].ccode[1] == ccode[1]) { + AICWFDBG(LOGDEBUG, "region: %d\r\n", reg_tables[i].region); + return reg_tables[i].region; + } + } + AICWFDBG(LOGDEBUG, "use default region\r\n"); + return REGIONS_DEFAULT; +} + +u8 get_region_index(char * name) +{ + if (strncmp(name, "SRRC", 4) == 0) + return REGIONS_SRRC; + else if (strncmp(name, "FCC", 3) == 0) + return REGIONS_FCC; + else if (strncmp(name, "ETSI", 4) == 0) + return REGIONS_ETSI; + else if (strncmp(name, "JP", 2) == 0) + return REGIONS_JP; + else if (strncmp(name, "UNSET", 5) == 0) + return REGIONS_DEFAULT; + + return REGIONS_DEFAULT; +} + + #ifdef CONFIG_POWER_LIMIT #define POWER_LIMIT_INVALID_VAL POWER_LEVEL_INVALID_VAL #define POWER_LIMIT_CC_MATCHED_BIT (0x1U << 0) +#define MAX_2_4G_BW_NUM 2 +#define MAX_5G_BW_NUM 3 +#define MAX_REGION_NUM 5 + + typedef struct { - u8_l ch_cnt_2g4; - u8_l ch_cnt_5g; - u8_l ch_num_2g4[MAC_DOMAINCHANNEL_24G_MAX]; - u8_l ch_num_5g[MAC_DOMAINCHANNEL_5G_MAX]; - s8_l max_pwr_2g4[MAC_DOMAINCHANNEL_24G_MAX]; - s8_l max_pwr_5g[MAC_DOMAINCHANNEL_5G_MAX]; + u8_l ch_cnt_2g4[MAX_2_4G_BW_NUM]; + u8_l ch_cnt_5g[MAX_5G_BW_NUM]; + u8_l ch_num_2g4[MAX_2_4G_BW_NUM][MAC_DOMAINCHANNEL_24G_MAX]; + u8_l ch_num_5g[MAX_5G_BW_NUM][MAC_DOMAINCHANNEL_5G_MAX]; + s8_l max_pwr_2g4[MAX_2_4G_BW_NUM][MAC_DOMAINCHANNEL_24G_MAX]; + s8_l max_pwr_5g[MAX_5G_BW_NUM][MAC_DOMAINCHANNEL_5G_MAX]; } txpwr_lmt_info_t; typedef struct { u32_l flags; - txpwr_lmt_info_t txpwr_lmt; + txpwr_lmt_info_t txpwr_lmt[MAX_REGION_NUM]; } powerlimit_info_t; powerlimit_info_t powerlimit_info = {0,}; @@ -1358,6 +1638,15 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw) } #endif else + #elif defined(CONFIG_LOFT_CALIB) + if (1) { + AICWFDBG(LOGINFO, "loft calib\n"); + ret = aicwf_loft_calib_8800dc(rwnx_hw, &loft_res_local); + if (ret) { + AICWFDBG(LOGINFO, "loft calib fail: %d\n", ret); + return ret; + } + } else #endif { ret = aicwf_misc_ram_init_8800dc(rwnx_hw); @@ -1384,8 +1673,23 @@ static int rwnx_plat_patch_load(struct rwnx_hw *rwnx_hw) return ret; } } - #endif - #endif + #endif/*CONFIG_FORCE_DPD_CALIB*/ + #elif defined(CONFIG_LOFT_CALIB) + { + AICWFDBG(LOGINFO, "patch load\n"); + ret = aicwf_plat_patch_load_8800dc(rwnx_hw); + if (ret) { + AICWFDBG(LOGINFO, "load patch bin fail: %d\n", ret); + return ret; + } + AICWFDBG(LOGINFO, "loft calib\n"); + ret = aicwf_loft_calib_8800dc(rwnx_hw, &loft_res_local); + if (ret) { + AICWFDBG(LOGINFO, "loft calib fail: %d\n", ret); + return ret; + } + } + #endif/*CONFIG_DPD*/ AICWFDBG(LOGINFO, "%s load rftest bin\n", __func__); ret = aicwf_plat_rftest_load_8800dc(rwnx_hw); if (ret) { @@ -1652,6 +1956,33 @@ static int rwnx_check_fw_compatibility(struct rwnx_hw *rwnx_hw) #endif #endif /* !CONFIG_RWNX_FHOST */ +int rwnx_atoi2(char *value, int c_len) +{ + int len = 0; + int i = 0; + int result = 0; + int flag = 1; + + if (value[0] == '-') { + flag = -1; + value++; + } + len = c_len; + + for (i = 0;i < len ;i++) { + result = result * 10; + if (value[i] >= 48 && value[i] <= 57) { + result += value[i] - 48; + } else { + result = 0; + break; + } + } + + return result * flag; +} + + int rwnx_atoi(char *value) { int len = 0; @@ -1820,6 +2151,80 @@ void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3) AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_5g:%d\r\n", __func__, txpwr_lvl_v3->pwrlvl_11ax_5g[11]); } +void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4) +{ + *txpwr_lvl_v4 = userconfig_info.txpwr_lvl_v4; + + AICWFDBG(LOGINFO, "%s:enable:%d\r\n", __func__, txpwr_lvl_v4->enable); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_1m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[0]); +#if 0//comment verbose printing + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_2m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_5m5_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_11m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_6m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_9m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_12m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_18m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_24m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_36m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_48m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[10]); + AICWFDBG(LOGINFO, "%s:lvl_11b_11ag_54m_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11b_11ag_2g4[11]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_2g4:%d\r\n",__func__, txpwr_lvl_v4->pwrlvl_11n_11ac_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[0]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[1]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[2]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[3]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[4]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[5]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[6]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[7]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[8]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[10]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_2g4:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_2g4[11]); + + AICWFDBG(LOGINFO, "%s:lvl_11a_6m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11a_9m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11a_12m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11a_18m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11a_24m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11a_36m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11a_48m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11a_54m_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11a_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[8]); + AICWFDBG(LOGINFO, "%s:lvl_11n_11ac_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11n_11ac_5g[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs0_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[0]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs1_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[1]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs2_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[2]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs3_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[3]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs4_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[4]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs5_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[5]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs6_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[6]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs7_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[7]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs8_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[8]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs9_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[9]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs10_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[10]); + AICWFDBG(LOGINFO, "%s:lvl_11ax_mcs11_5g:%d\r\n", __func__, txpwr_lvl_v4->pwrlvl_11ax_5g[11]); +#endif +} + void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj) { *txpwr_lvl_adj = userconfig_info.txpwr_lvl_adj; @@ -1883,13 +2288,47 @@ void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x) AICWFDBG(LOGINFO, "\n"); } +void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2) +{ + int type, ch_grp; + *txpwr_ofst2x_v2 = userconfig_info.txpwr_ofst2x_v2; + AICWFDBG(LOGINFO, "%s:enable :%d\r\n", __func__, txpwr_ofst2x_v2->enable); + AICWFDBG(LOGINFO, "pwrofst2x 2.4g(ant0/ant1): [0]:11b, [1]:ofdm_highrate\n" + " chan=" "\t1-4" "\t5-9" "\t10-13"); + for (type = 0; type < 2; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 3; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d/%d", txpwr_ofst2x_v2->pwrofst2x_tbl_2g4_ant0[ch_grp][type], txpwr_ofst2x_v2->pwrofst2x_tbl_2g4_ant1[ch_grp][type]); + } + } + AICWFDBG(LOGINFO, "\npwrofst2x 5g: [0]:ofdm_highrate\n" + " chan=" "\t36-50" "\t51-64" "\t98-114" "\t115-130" "\t131-146" "\t147-166"); + for (type = 0; type < 1; type++) { + AICWFDBG(LOGINFO, "\n [%d] =", type); + for (ch_grp = 0; ch_grp < 6; ch_grp++) { + AICWFDBG(LOGINFO, "\t%d/%d", txpwr_ofst2x_v2->pwrofst2x_tbl_5g_ant0[ch_grp][type], txpwr_ofst2x_v2->pwrofst2x_tbl_5g_ant1[ch_grp][type]); + } + } + AICWFDBG(LOGINFO, "\n"); +} void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss) { - txpwr_loss->loss_enable = userconfig_info.txpwr_loss.loss_enable; - txpwr_loss->loss_value = userconfig_info.txpwr_loss.loss_value; + txpwr_loss->loss_enable_2g4 = userconfig_info.txpwr_loss.loss_enable_2g4; + txpwr_loss->loss_value_2g4 = userconfig_info.txpwr_loss.loss_value_2g4; + txpwr_loss->loss_enable_5g = userconfig_info.txpwr_loss.loss_enable_5g; + txpwr_loss->loss_value_5g = userconfig_info.txpwr_loss.loss_value_5g; - AICWFDBG(LOGINFO, "%s:loss_enable:%d\r\n", __func__, txpwr_loss->loss_enable); - AICWFDBG(LOGINFO, "%s:loss_value:%d\r\n", __func__, txpwr_loss->loss_value); + AICWFDBG(LOGDEBUG, "%s:loss_enable_2g4: %d, val_2g4: %d, loss_enable_5g: %d, val_5g: %d\r\n", __func__, + txpwr_loss->loss_enable_2g4, txpwr_loss->loss_value_2g4, + txpwr_loss->loss_enable_5g, txpwr_loss->loss_value_5g); +} +void set_txpwr_loss_ofst(s8_l value) +{ + userconfig_info.txpwr_loss.loss_enable_2g4 = 1; + userconfig_info.txpwr_loss.loss_value_2g4 = -value; + userconfig_info.txpwr_loss.loss_enable_5g = 1; + userconfig_info.txpwr_loss.loss_value_5g = -value; + AICWFDBG(LOGINFO, "%s:value:%d\r\n", __func__, value); } void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap) @@ -2117,10 +2556,14 @@ void rwnx_plat_nvram_set_value(char *command, char *value) userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[4] = rwnx_atoi(value); } else if (!strcmp(command, "lvl_adj_5g_chan_155")) { userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[5] = rwnx_atoi(value); - } else if (!strcmp(command, "loss_enable")) { - userconfig_info.txpwr_loss.loss_enable = rwnx_atoi(value); - } else if (!strcmp(command, "loss_value")) { - userconfig_info.txpwr_loss.loss_value = rwnx_atoi(value); + } else if (!strcmp(command, "loss_enable_2g4")) { + userconfig_info.txpwr_loss.loss_enable_2g4 = rwnx_atoi(value); + } else if (!strcmp(command, "loss_value_2g4")) { + userconfig_info.txpwr_loss.loss_value_2g4 = rwnx_atoi(value); + } else if (!strcmp(command, "loss_enable_5g")) { + userconfig_info.txpwr_loss.loss_enable_5g = rwnx_atoi(value); + } else if (!strcmp(command, "loss_value_5g")) { + userconfig_info.txpwr_loss.loss_value_5g = rwnx_atoi(value); } else if (!strcmp(command, "ofst_enable")) { userconfig_info.txpwr_ofst.enable = rwnx_atoi(value); userconfig_info.txpwr_ofst2x.enable = rwnx_atoi(value); @@ -2155,7 +2598,7 @@ void rwnx_plat_nvram_set_value(char *command, char *value) } else if (!strcmp(command, "ofst_2g4_ofdm_lowrate_chan_5_9")) { userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][1] = rwnx_atoi(value); } else if (!strcmp(command, "ofst_2g4_ofdm_lowrate_chan_10_13")) { - userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][0] = rwnx_atoi(value); + userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_2g4[2][2] = rwnx_atoi(value); } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_42")) { userconfig_info.txpwr_ofst2x.pwrofst2x_tbl_5g[0][0] = rwnx_atoi(value); } else if (!strcmp(command, "ofst_5g_ofdm_lowrate_chan_58")) { @@ -2203,6 +2646,293 @@ void rwnx_plat_nvram_set_value(char *command, char *value) } } +void rwnx_plat_nvram_set_value_8800d80x2(char *command, char *value) +{ + //TODO send command + AICWFDBG(LOGINFO, "%s:command=%s value=%s\n", __func__, command, value); + if (!strcmp(command, "enable")) { + userconfig_info.txpwr_lvl_v4.enable = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_1m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_2m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_5m5_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_11m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_6m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_9m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_12m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_18m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_24m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[8] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_36m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[9] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_48m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[10] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11b_11ag_54m_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11b_11ag_2g4[11] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs0_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs1_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs2_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs3_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs4_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs5_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs6_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs7_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs8_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[8] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs9_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_2g4[9] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs0_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs1_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs2_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs3_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs4_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs5_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs6_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs7_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs8_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[8] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs9_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[9] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs10_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[10] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs11_2g4")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_2g4[11] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_6m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_9m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_12m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_18m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_24m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_36m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_48m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11a_54m_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11a_5g[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs0_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs1_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs2_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs3_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs4_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs5_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs6_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs7_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs8_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[8] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11n_11ac_mcs9_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11n_11ac_5g[9] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs0_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs1_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs2_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs3_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs4_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs5_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[5] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs6_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[6] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs7_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[7] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs8_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[8] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs9_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[9] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs10_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[10] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_11ax_mcs11_5g")) { + userconfig_info.txpwr_lvl_v4.pwrlvl_11ax_5g[11] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_enable")) { + userconfig_info.txpwr_lvl_adj.enable = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_2g4_chan_1_4")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_2g4_chan_5_9")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_2g4_chan_10_13")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_2g4[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_42")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[0] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_58")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[1] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_106")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[2] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_122")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[3] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_138")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[4] = rwnx_atoi(value); + } else if (!strcmp(command, "lvl_adj_5g_chan_155")) { + userconfig_info.txpwr_lvl_adj.pwrlvl_adj_tbl_5g[5] = rwnx_atoi(value); + } else if (!strcmp(command, "loss_enable_2g4")) { + userconfig_info.txpwr_loss.loss_enable_2g4 = rwnx_atoi(value); + } else if (!strcmp(command, "loss_value_2g4")) { + userconfig_info.txpwr_loss.loss_value_2g4 = rwnx_atoi(value); + } else if (!strcmp(command, "loss_enable_5g")) { + userconfig_info.txpwr_loss.loss_enable_5g = rwnx_atoi(value); + } else if (!strcmp(command, "loss_value_5g")) { + userconfig_info.txpwr_loss.loss_value_5g = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_enable")) { + userconfig_info.txpwr_ofst2x_v2.enable = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_11b_chan_1_4")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[0][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_11b_chan_5_9")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[1][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_11b_chan_10_13")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[2][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_ofdm_highrate_chan_1_4")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[0][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_ofdm_highrate_chan_5_9")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[1][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant0_ofdm_highrate_chan_10_13")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant0[2][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_11b_chan_1_4")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[0][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_11b_chan_5_9")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[1][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_11b_chan_10_13")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[2][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_ofdm_highrate_chan_1_4")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[0][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_ofdm_highrate_chan_5_9")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[1][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_2g4_ant1_ofdm_highrate_chan_10_13")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_2g4_ant1[2][1] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_42")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[0][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_58")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[1][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_106")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[2][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_122")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[3][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_138")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[4][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant0_ofdm_highrate_chan_155")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant0[5][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_42")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[0][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_58")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[1][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_106")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[2][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_122")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[3][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_138")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[4][0] = rwnx_atoi(value); + } else if (!strcmp(command, "ofst_5g_ant1_ofdm_highrate_chan_155")) { + userconfig_info.txpwr_ofst2x_v2.pwrofst2x_tbl_5g_ant1[5][0] = rwnx_atoi(value); + } else if (!strcmp(command, "xtal_enable")) { + userconfig_info.xtal_cap.enable = rwnx_atoi(value); + } else if (!strcmp(command, "xtal_cap")) { + userconfig_info.xtal_cap.xtal_cap = rwnx_atoi(value); + } else if (!strcmp(command, "xtal_cap_fine")) { + userconfig_info.xtal_cap.xtal_cap_fine = rwnx_atoi(value); + } else { + AICWFDBG(LOGERROR, "invalid cmd: %s\n", command); + } +} + +void rwnx_plat_userconfig_parsing_8800d80x2(char *buffer, int size) +{ + int i = 0; + int parse_state = 0; + char command[100]; + char value[100]; + int char_counter = 0; + + memset(command, 0, 64); + memset(value, 0, 100); + + for (i = 0; i < size; i++) { + //Send command or print nvram log when char is \r or \n + if (buffer[i] == 0x0a || buffer[i] == 0x0d) { + if (command[0] != 0 && value[0] != 0) { + if (parse_state == PRINT) { + AICWFDBG(LOGINFO, "%s:%s\r\n", __func__, value); + } else if (parse_state == GET_VALUE) { + rwnx_plat_nvram_set_value_8800d80x2(command, value); + } + } + //Reset command value and char_counter + memset(command, 0, 64); + memset(value, 0, 100); + char_counter = 0; + parse_state = INIT; + continue; + } + + //Switch parser state + if (parse_state == INIT) { + if (buffer[i] == '#') { + parse_state = PRINT; + continue; + } else if (buffer[i] == 0x0a || buffer[i] == 0x0d) { + parse_state = INIT; + continue; + } else { + parse_state = CMD; + } + } + + //Fill data to command and value + if (parse_state == PRINT) { + command[0] = 0x01; + value[char_counter] = buffer[i]; + char_counter++; + } else if (parse_state == CMD) { + if (command[0] != 0 && buffer[i] == '=') { + parse_state = GET_VALUE; + char_counter = 0; + continue; + } + command[char_counter] = buffer[i]; + char_counter++; + } else if (parse_state == GET_VALUE) { + if(buffer[i] != 0x2D && (buffer[i] < 0x30 || buffer[i] > 0x39)) { + continue; + } + value[char_counter] = buffer[i]; + char_counter++; + } + } +} void rwnx_plat_userconfig_parsing(char *buffer, int size) { @@ -2343,6 +3073,48 @@ int GetS1ByteIntegerFromStringInDecimal(char *str, s8 *val) return 1; } +int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name) +{ + u8 channel_num, powerLimit_val, reg_idx; + + if (GetU1ByteIntegerFromStringInDecimal((char *)channel, &channel_num) == 0 + || GetS1ByteIntegerFromStringInDecimal((char *)limit, &powerLimit_val) == 0) { + AICWFDBG(LOGERROR, "Illegal index of power limit table [ch %s][val %s]\n", channel, limit); + return -1; + } + + reg_idx = get_region_index(name); + + if (band == PHY_BAND_2G4) { + uint8_t cur_idx = powerlimit_info.txpwr_lmt[reg_idx].ch_cnt_2g4[bw]; + AICWFDBG(LOGINFO, "reg_idx=%d, band=%d, bw=%d, cur_idx=%d, ch=%s, pwr=%s\n", + reg_idx, band, bw, cur_idx, channel, limit); + if (cur_idx < MAC_DOMAINCHANNEL_24G_MAX) { + powerlimit_info.txpwr_lmt[reg_idx].ch_num_2g4[bw][cur_idx] = channel_num; + powerlimit_info.txpwr_lmt[reg_idx].max_pwr_2g4[bw][cur_idx] = powerLimit_val; + powerlimit_info.txpwr_lmt[reg_idx].ch_cnt_2g4[bw]++; + } else { + AICWFDBG(LOGERROR, "band %d chan_cnt reached %d\n", band, MAC_DOMAINCHANNEL_24G_MAX); + AICWFDBG(LOGERROR, "channel=%s(%d) powerLimit=%s(%d)\n", channel, channel_num, limit, powerLimit_val); + } + } else if (band == PHY_BAND_5G) { + uint8_t cur_idx = powerlimit_info.txpwr_lmt[reg_idx].ch_cnt_5g[bw]; + AICWFDBG(LOGINFO, "reg_idx=%d, band=%d, bw=%d, cur_idx=%d, ch=%s, pwr=%s\n", + reg_idx, band, bw, cur_idx, channel, limit); + if (cur_idx < MAC_DOMAINCHANNEL_5G_MAX) { + powerlimit_info.txpwr_lmt[reg_idx].ch_num_5g[bw][cur_idx] = channel_num; + powerlimit_info.txpwr_lmt[reg_idx].max_pwr_5g[bw][cur_idx] = powerLimit_val; + powerlimit_info.txpwr_lmt[reg_idx].ch_cnt_5g[bw]++; + } else { + AICWFDBG(LOGERROR, "band %d chan_cnt reached %d\n", band, MAC_DOMAINCHANNEL_5G_MAX); + AICWFDBG(LOGERROR, "channel=%s(%d) powerLimit=%s(%d)\n", channel, channel_num, limit, powerLimit_val); + } + } + + return 0; +} + + void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc) { #define LD_STAGE_EXC_MAPPING 0 @@ -2351,224 +3123,236 @@ void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc) #define LD_STAGE_COLUMN_DEFINE 3 #define LD_STAGE_CH_ROW 4 - uint8_t loadingStage = LD_STAGE_EXC_MAPPING; - uint32_t i = 0, forCnt = 0; - uint32_t i_cc; - char *szLine, *ptmp; - char band[10], colNumBuf[10]; - uint8_t colNum = 0, colNum_cc = 255, band_cc = 0; - // clear powerlimit info at first - memset((void *)&powerlimit_info, 0, sizeof(powerlimit_info_t)); - ptmp = buffer; - for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) { - if (isAllSpaceOrTab(szLine, sizeof(*szLine))) - continue; - if (IsCommentString(szLine)) - continue; + uint8_t loadingStage = LD_STAGE_EXC_MAPPING; + uint32_t i = 0, forCnt = 0; + uint32_t i_cc; + char *szLine, *ptmp; + char band[10], colNumBuf[10], bandwidth[10]; + uint8_t colNum = 0, band_cc = 0, bw_cc = 0; + char **reg_name = NULL; + // clear powerlimit info at first + memset((void *)&powerlimit_info, 0, sizeof(powerlimit_info_t)); + ptmp = buffer; + for (szLine = GetLineFromBuffer(ptmp); szLine != NULL; szLine = GetLineFromBuffer(ptmp)) { + if (isAllSpaceOrTab(szLine, sizeof(*szLine))) + continue; + if (IsCommentString(szLine)) + continue; - if (loadingStage == LD_STAGE_EXC_MAPPING) { - if (szLine[0] == '#' || szLine[1] == '#') { - loadingStage = LD_STAGE_TAB_DEFINE; - } else { - continue; - } - } + if (loadingStage == LD_STAGE_EXC_MAPPING) { + if (szLine[0] == '#' || szLine[1] == '#') { + loadingStage = LD_STAGE_TAB_DEFINE; + } else { + continue; + } + } - if (loadingStage == LD_STAGE_TAB_DEFINE) { - /* read "## 2.4G" */ - if (szLine[0] != '#' || szLine[1] != '#') - continue; + if (loadingStage == LD_STAGE_TAB_DEFINE) { + /* read "## 2.4G" */ + if (szLine[0] != '#' || szLine[1] != '#') + continue; - /* skip the space */ - i = 2; - while (szLine[i] == ' ' || szLine[i] == '\t') - ++i; + /* skip the space */ + i = 2; + while (szLine[i] == ' ' || szLine[i] == '\t') + ++i; - szLine[--i] = ' '; /* return the space in front of the regulation info */ + szLine[--i] = ' '; /* return the space in front of the regulation info */ - /* Parse the label of the table */ - memset((void *)band, 0, 10); - if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) { - AICWFDBG(LOGERROR, "Fail to parse band!\n"); - goto exit; - } - if (strncmp(band, "2.4G", 4) == 0) { - band_cc = PHY_BAND_2G4; - } else if (strncmp(band, "5G", 2) == 0) { - band_cc = PHY_BAND_5G; - } - memset((void *) colNumBuf, 0, 10); - if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) { - AICWFDBG(LOGERROR, "Fail to parse column number!\n"); - goto exit; - } - if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum)) { - AICWFDBG(LOGERROR, "Column number \"%s\" is not unsigned decimal\n", colNumBuf); - goto exit; - } - if (colNum == 0) { - AICWFDBG(LOGERROR, "Column number is 0\n"); - goto exit; - } + /* Parse the label of the table */ + memset((void *)band, 0, 10); + memset((void *)bandwidth, 0, 10); + memset((void *)colNumBuf, 0, 10); - AICWFDBG(LOGINFO, "band=%s(%d)\n", band, band_cc); - loadingStage = LD_STAGE_TAB_START; - } else if (loadingStage == LD_STAGE_TAB_START) { - /* read "## START" */ - if (szLine[0] != '#' || szLine[1] != '#') - continue; + if (!ParseQualifiedString(szLine, &i, band, ' ', ',')) { + AICWFDBG(LOGERROR, "Fail to parse band!\n"); + goto exit; + } + if (strncmp(band, "2.4G", 4) == 0) { + band_cc = PHY_BAND_2G4; + } else if (strncmp(band, "5G", 2) == 0) { + band_cc = PHY_BAND_5G; + } - /* skip the space */ - i = 2; - while (szLine[i] == ' ' || szLine[i] == '\t') - ++i; + if (!ParseQualifiedString(szLine, &i, bandwidth, ' ', ',')) { + AICWFDBG(LOGERROR, "Fail to parse bandwidth!\n"); + goto exit; + } + if (strncmp(bandwidth, "20M", 3) == 0) + bw_cc = PHY_CHNL_BW_20; + else if (strncmp(bandwidth, "40M", 3) == 0) + bw_cc = PHY_CHNL_BW_40; + else if (strncmp(bandwidth, "80M", 3) == 0) + bw_cc = PHY_CHNL_BW_80; - if (strncmp((u8 *)(szLine + i), "START", 5)) { - AICWFDBG(LOGERROR, "Missing \"## START\" label\n"); - goto exit; - } + if (!ParseQualifiedString(szLine, &i, colNumBuf, '#', '#')) { + AICWFDBG(LOGERROR, "Fail to parse column number!\n"); + goto exit; + } + if (!GetU1ByteIntegerFromStringInDecimal(colNumBuf, &colNum)) { + AICWFDBG(LOGERROR, "Column number \"%s\" is not unsigned decimal\n", colNumBuf); + goto exit; + } + if (colNum == 0) { + AICWFDBG(LOGERROR, "Column number is 0\n"); + goto exit; + } - loadingStage = LD_STAGE_COLUMN_DEFINE; - } else if (loadingStage == LD_STAGE_COLUMN_DEFINE) { - /* read "## CN US" */ - if (szLine[0] != '#' || szLine[1] != '#') - continue; + AICWFDBG(LOGINFO, "band=%s, bandwidth=%s, colnum=%d\n", band, bandwidth, colNum); + loadingStage = LD_STAGE_TAB_START; + } else if (loadingStage == LD_STAGE_TAB_START) { + /* read "## START" */ + if (szLine[0] != '#' || szLine[1] != '#') + continue; - /* skip the space */ - i = 2; - while (szLine[i] == ' ' || szLine[i] == '\t') - ++i; + /* skip the space */ + i = 2; + while (szLine[i] == ' ' || szLine[i] == '\t') + ++i; - for (forCnt = 0; forCnt < colNum; forCnt++) { - /* skip the space */ - while (szLine[i] == ' ' || szLine[i] == '\t') - i++; - i_cc = i; + if (strncmp((u8 *)(szLine + i), "START", 5)) { + AICWFDBG(LOGERROR, "Missing \"## START\" label\n"); + goto exit; + } - while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0') - i++; + loadingStage = LD_STAGE_COLUMN_DEFINE; + } else if (loadingStage == LD_STAGE_COLUMN_DEFINE) { + /* read "## FCC ETSI" */ + if (szLine[0] != '#' || szLine[1] != '#') + continue; - if ((i - i_cc) != 2) { - AICWFDBG(LOGERROR, "CC len err\n"); - goto exit; - } else if ((szLine[i_cc] == cc[0]) && (szLine[i_cc + 1] == cc[1])) { - AICWFDBG(LOGINFO, "CC matched: %s, col=%d\n", cc, forCnt); - colNum_cc = forCnt; - powerlimit_info.flags |= POWER_LIMIT_CC_MATCHED_BIT; - break; - } - } + /* skip the space */ + i = 2; + while (szLine[i] == ' ' || szLine[i] == '\t') + ++i; - loadingStage = LD_STAGE_CH_ROW; - } else if (loadingStage == LD_STAGE_CH_ROW) { - char channel[10] = {0}, powerLimit[10] = {0}; - u8 channel_num, powerLimit_val, cnt = 0; + reg_name = (char **)kmalloc(sizeof(char *) * colNum, GFP_KERNEL); + if (!reg_name) { + AICWFDBG(LOGERROR, "reg_name alloc fail\n"); + goto exit; + } - /* the table ends */ - if (szLine[0] == '#' && szLine[1] == '#') { - i = 2; - while (szLine[i] == ' ' || szLine[i] == '\t') - ++i; + for (forCnt = 0; forCnt < colNum; ++forCnt) { + /* skip the space */ + while (szLine[i] == ' ' || szLine[i] == '\t') + i++; + i_cc = i; - if (strncmp((u8 *)(szLine + i), "END", 3) == 0) { - loadingStage = LD_STAGE_TAB_DEFINE; - colNum = 0; - continue; - } else { - AICWFDBG(LOGERROR, "Missing \"## END\" label\n"); - goto exit; - } - } + while (szLine[i] != ' ' && szLine[i] != '\t' && szLine[i] != '\0') + i++; - if ((szLine[0] != 'c' && szLine[0] != 'C') || - (szLine[1] != 'h' && szLine[1] != 'H') - ) { - AICWFDBG(LOGERROR, "Wrong channel prefix: '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]); - continue; - } - i = 2;/* move to the location behind 'h' */ + reg_name[forCnt] = (char *)kmalloc(i - i_cc + 1, GFP_KERNEL); + if (!reg_name[forCnt]) { + AICWFDBG(LOGERROR, "reg_name element alloc fail\n"); + goto exit; + } - /* load the channel number */ - cnt = 0; - while (szLine[i] >= '0' && szLine[i] <= '9') { - channel[cnt] = szLine[i]; - ++cnt; - ++i; - } + strncpy(reg_name[forCnt], szLine + i_cc, i - i_cc); + reg_name[forCnt][i - i_cc] = '\0'; + AICWFDBG(LOGINFO, "reg_name: %s\n", reg_name[forCnt]); - for (forCnt = 0; forCnt < colNum; ++forCnt) { - /* skip the space between channel number and the power limit value */ - while (szLine[i] == ' ' || szLine[i] == '\t') - ++i; + } - /* load the power limit value */ - memset((void *)powerLimit, 0, 10); + loadingStage = LD_STAGE_CH_ROW; + } else if (loadingStage == LD_STAGE_CH_ROW) { + char channel[10] = {0}, powerLimit[10] = {0}; + u8 cnt = 0; - if (szLine[i] == 'N' && szLine[i + 1] == 'A') { - /* - * means channel not available - */ - sprintf(powerLimit, "%d", POWER_LIMIT_INVALID_VAL); - i += 2; - } else if ((szLine[i] >= '0' && szLine[i] <= '9') - || szLine[i] == '+' || szLine[i] == '-' - ) { - /* case of dBm value */ - cnt = 0; - while ((szLine[i] >= '0' && szLine[i] <= '9') - || szLine[i] == '+' || szLine[i] == '-' - ) { - powerLimit[cnt] = szLine[i]; - ++cnt; - ++i; - } - } else { - AICWFDBG(LOGERROR, "Wrong limit expression \"%c%c\"(%d, %d)\n" - , szLine[i], szLine[i + 1], szLine[i], szLine[i + 1]); - goto exit; - } + /* the table ends */ + if (szLine[0] == '#' && szLine[1] == '#') { + i = 2; + while (szLine[i] == ' ' || szLine[i] == '\t') + ++i; - if (forCnt == colNum_cc) { - /* store the power limit value */ - if (GetU1ByteIntegerFromStringInDecimal((char *)channel, &channel_num) == 0 - || GetS1ByteIntegerFromStringInDecimal((char *)powerLimit, &powerLimit_val) == 0 - ) { - AICWFDBG(LOGERROR, "Illegal index of power limit table [ch %s][val %s]\n", channel, powerLimit); - goto exit; - } + if (strncmp((u8 *)(szLine + i), "END", 3) == 0) { + loadingStage = LD_STAGE_TAB_DEFINE; + if (reg_name) { + for (forCnt = 0; forCnt < colNum; ++forCnt) { + if (reg_name[forCnt]) { + kfree(reg_name[forCnt]); + reg_name[forCnt] = NULL; + } + } + kfree(reg_name); + reg_name = NULL; + } + colNum = 0; + continue; + } else { + AICWFDBG(LOGERROR, "Missing \"## END\" label\n"); + goto exit; + } + } - if (band_cc == PHY_BAND_2G4) { - uint8_t cur_idx = powerlimit_info.txpwr_lmt.ch_cnt_2g4; - AICWFDBG(LOGINFO, "[%d]: ch=%s, pwr=%s\n", cur_idx, channel, powerLimit); - if (cur_idx < MAC_DOMAINCHANNEL_24G_MAX) { - powerlimit_info.txpwr_lmt.ch_num_2g4[cur_idx] = channel_num; - powerlimit_info.txpwr_lmt.max_pwr_2g4[cur_idx] = powerLimit_val; - powerlimit_info.txpwr_lmt.ch_cnt_2g4++; - } else { - AICWFDBG(LOGERROR, "band %d chan_cnt reached %d\n", band_cc, MAC_DOMAINCHANNEL_24G_MAX); - AICWFDBG(LOGERROR, "channel=%s(%d) powerLimit=%s(%d)\n", channel, channel_num, powerLimit, powerLimit_val); - } - } else if (band_cc == PHY_BAND_5G) { - uint8_t cur_idx = powerlimit_info.txpwr_lmt.ch_cnt_5g; - AICWFDBG(LOGINFO, "[%d]: ch=%s, pwr=%s\n", cur_idx, channel, powerLimit); - if (cur_idx < MAC_DOMAINCHANNEL_5G_MAX) { - powerlimit_info.txpwr_lmt.ch_num_5g[cur_idx] = channel_num; - powerlimit_info.txpwr_lmt.max_pwr_5g[cur_idx] = powerLimit_val; - powerlimit_info.txpwr_lmt.ch_cnt_5g++; - } else { - AICWFDBG(LOGERROR, "band %d chan_cnt reached %d\n", band_cc, MAC_DOMAINCHANNEL_5G_MAX); - AICWFDBG(LOGERROR, "channel=%s(%d) powerLimit=%s(%d)\n", channel, channel_num, powerLimit, powerLimit_val); - } - } - break; - } - } - } - } + if ((szLine[0] != 'c' && szLine[0] != 'C') || + (szLine[1] != 'h' && szLine[1] != 'H')) { + AICWFDBG(LOGERROR, "Wrong channel prefix: '%c','%c'(%d,%d)\n", szLine[0], szLine[1], szLine[0], szLine[1]); + continue; + } + i = 2;/* move to the location behind 'h' */ + + /* load the channel number */ + cnt = 0; + while (szLine[i] >= '0' && szLine[i] <= '9') { + channel[cnt] = szLine[i]; + ++cnt; + ++i; + } + + for (forCnt = 0; forCnt < colNum; ++forCnt) { + /* skip the space between channel number and the power limit value */ + while (szLine[i] == ' ' || szLine[i] == '\t') + ++i; + + /* load the power limit value */ + memset((void *)powerLimit, 0, 10); + + if (szLine[i] == 'N' && szLine[i + 1] == 'A') { + /* + * means channel not available + */ + sprintf(powerLimit, "%d", POWER_LIMIT_INVALID_VAL); + i += 2; + } else if ((szLine[i] >= '0' && szLine[i] <= '9') + || szLine[i] == '+' || szLine[i] == '-') { + /* case of dBm value */ + cnt = 0; + while ((szLine[i] >= '0' && szLine[i] <= '9') + || szLine[i] == '+' || szLine[i] == '-' + ) { + powerLimit[cnt] = szLine[i]; + ++cnt; + ++i; + } + } else { + AICWFDBG(LOGERROR, "Wrong limit expression \"%c%c\"(%d, %d)\n", + szLine[i], szLine[i + 1], szLine[i], szLine[i + 1]); + goto exit; + } + + if (rwnx_plat_powerlimit_save(band_cc, channel, bw_cc, powerLimit, reg_name[forCnt]) < 0) + goto exit; + } + } + } + + powerlimit_info.flags |= POWER_LIMIT_CC_MATCHED_BIT; exit: - return; + if (reg_name) { + for (forCnt = 0; forCnt < colNum; ++forCnt) { + if (reg_name[forCnt]) { + kfree(reg_name[forCnt]); + reg_name[forCnt] = NULL; + } + } + kfree(reg_name); + reg_name = NULL; + } + + return; } + /// 5G lower bound freq #define PHY_FREQ_5G 5000 @@ -2585,78 +3369,83 @@ uint16_t phy_channel_to_freq(uint8_t band, int channel) return 0; } -int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq) +int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx) { - int8_t ret = POWER_LIMIT_INVALID_VAL; - uint8_t idx; - if (powerlimit_info.flags & POWER_LIMIT_CC_MATCHED_BIT) { - if (band == PHY_BAND_2G4) { - uint8_t idx_cnt = powerlimit_info.txpwr_lmt.ch_cnt_2g4; - for (idx = 0; idx < idx_cnt; idx++) { - int ch_num = powerlimit_info.txpwr_lmt.ch_num_2g4[idx]; - uint16_t freq_tmp = phy_channel_to_freq(PHY_BAND_2G4, ch_num); - if (freq == freq_tmp) { - ret = powerlimit_info.txpwr_lmt.max_pwr_2g4[idx]; - //AICWFDBG(LOGINFO, "[%d]: ch=%d(freq=%d), pwr=%d\n", idx, ch_num, freq, ret); - break; - } - } - if (idx == idx_cnt) { - AICWFDBG(LOGERROR, "powerlimit search failed: band=%d freq=%d\n", band, freq); - } - } else if (band == PHY_BAND_5G) { - uint8_t idx_cnt = powerlimit_info.txpwr_lmt.ch_cnt_5g; - for (idx = 0; idx < idx_cnt; idx++) { - int ch_num = powerlimit_info.txpwr_lmt.ch_num_5g[idx]; - uint16_t freq_tmp = phy_channel_to_freq(PHY_BAND_5G, ch_num); - if (freq == freq_tmp) { - ret = powerlimit_info.txpwr_lmt.max_pwr_5g[idx]; - //AICWFDBG(LOGINFO, "[%d]: ch=%d(freq=%d), pwr=%d\n", idx, ch_num, freq, ret); - break; - } - } - if (idx == idx_cnt) { - AICWFDBG(LOGERROR, "powerlimit search failed: band=%d freq=%d\n", band, freq); - } - } - } + int8_t ret = POWER_LIMIT_INVALID_VAL; + uint8_t idx; + if (!(powerlimit_info.flags & POWER_LIMIT_CC_MATCHED_BIT)) { + AICWFDBG(LOGERROR, "powerlimit flag not set\n"); + return ret; + } + + if (band == PHY_BAND_2G4) { + uint8_t idx_cnt = powerlimit_info.txpwr_lmt[r_idx].ch_cnt_2g4[0]; + for (idx = 0; idx < idx_cnt; idx++) { + int ch_num = powerlimit_info.txpwr_lmt[r_idx].ch_num_2g4[0][idx]; + uint16_t freq_tmp = phy_channel_to_freq(PHY_BAND_2G4, ch_num); + if (freq == freq_tmp) { + ret = powerlimit_info.txpwr_lmt[r_idx].max_pwr_2g4[0][idx]; + AICWFDBG(LOGINFO, "[%d]: ch=%d(freq=%d), pwr=%d\n", idx, ch_num, freq, ret); + break; + } + } + if (idx == idx_cnt) + AICWFDBG(LOGERROR, "powerlimit search failed: band=%d freq=%d\n", band, freq); + } else if (band == PHY_BAND_5G) { + uint8_t idx_cnt = powerlimit_info.txpwr_lmt[r_idx].ch_cnt_5g[0]; + for (idx = 0; idx < idx_cnt; idx++) { + int ch_num = powerlimit_info.txpwr_lmt[r_idx].ch_num_5g[0][idx]; + uint16_t freq_tmp = phy_channel_to_freq(PHY_BAND_5G, ch_num); + if (freq == freq_tmp) { + ret = powerlimit_info.txpwr_lmt[r_idx].max_pwr_5g[0][idx]; + AICWFDBG(LOGINFO, "[%d]: ch=%d(freq=%d), pwr=%d\n", idx, ch_num, freq, ret); + break; + } + } + if (idx == idx_cnt) + AICWFDBG(LOGERROR, "powerlimit search failed: band=%d freq=%d\n", band, freq); + } return ret; } -int8_t get_powerlimit_by_chnum(uint8_t chnum) +int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw) { - int8_t ret = POWER_LIMIT_INVALID_VAL; - uint8_t idx; - if (powerlimit_info.flags & POWER_LIMIT_CC_MATCHED_BIT) { - if (chnum <= 14) { - uint8_t idx_cnt = powerlimit_info.txpwr_lmt.ch_cnt_2g4; - for (idx = 0; idx < idx_cnt; idx++) { - uint8_t ch_num = powerlimit_info.txpwr_lmt.ch_num_2g4[idx]; - if (chnum == ch_num) { - ret = powerlimit_info.txpwr_lmt.max_pwr_2g4[idx]; - //AICWFDBG(LOGINFO, "[%d]: ch=%d, pwr=%d\n", idx, ch_num, ret); - break; - } - } - if (idx == idx_cnt) { - AICWFDBG(LOGERROR, "powerlimit search failed: chnum=%d\n", chnum); - } - } else if (chnum <= 165) { - uint8_t idx_cnt = powerlimit_info.txpwr_lmt.ch_cnt_5g; - for (idx = 0; idx < idx_cnt; idx++) { - int ch_num = powerlimit_info.txpwr_lmt.ch_num_5g[idx]; - if (chnum == ch_num) { - ret = powerlimit_info.txpwr_lmt.max_pwr_5g[idx]; - //AICWFDBG(LOGINFO, "[%d]: ch=%d, pwr=%d\n", idx, ch_num, ret); - break; - } - } - if (idx == idx_cnt) { - AICWFDBG(LOGERROR, "powerlimit search failed: chnum=%d\n", chnum); - } - } - } - return ret; + int8_t ret = POWER_LIMIT_INVALID_VAL; + uint8_t idx; + if (!(powerlimit_info.flags & POWER_LIMIT_CC_MATCHED_BIT)) { + AICWFDBG(LOGERROR, "powerlimit flag not set\n"); + return ret; + } + + if (chnum <= 14) { + uint8_t idx_cnt = powerlimit_info.txpwr_lmt[r_idx].ch_cnt_2g4[bw]; + for (idx = 0; idx < idx_cnt; idx++) { + uint8_t ch_num = powerlimit_info.txpwr_lmt[r_idx].ch_num_2g4[bw][idx]; + if (chnum == ch_num) { + ret = powerlimit_info.txpwr_lmt[r_idx].max_pwr_2g4[bw][idx]; + AICWFDBG(LOGINFO, "[%d]: ch=%d, pwr=%d\n", idx, ch_num, ret); + break; + } + } + if (idx == idx_cnt) + AICWFDBG(LOGERROR, "%s powerlimit search failed: chnum=%d, please confirm the center frequency\n", + __func__, chnum); + } else if (chnum <= 165) { + uint8_t idx_cnt = powerlimit_info.txpwr_lmt[r_idx].ch_cnt_5g[bw]; + for (idx = 0; idx < idx_cnt; idx++) { + uint8_t ch_num = powerlimit_info.txpwr_lmt[r_idx].ch_num_5g[bw][idx]; + if (chnum == ch_num) { + ret = powerlimit_info.txpwr_lmt[r_idx].max_pwr_5g[bw][idx]; + AICWFDBG(LOGINFO, "[%d]: ch=%d, pwr=%d\n", idx, ch_num, ret); + break; + } + } + if (idx == idx_cnt) + AICWFDBG(LOGERROR, "%s powerlimit search failed: chnum=%d, please confirm the center frequency\n", + __func__, chnum); + } + + return ret; } #endif @@ -2678,6 +3467,9 @@ static int rwnx_plat_userconfig_load(struct rwnx_hw *rwnx_hw) { #endif }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81){ rwnx_plat_userconfig_load_8800d80(rwnx_hw); + }else if(rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D81X2 || + rwnx_hw->usbdev->chipid == PRODUCT_ID_AIC8800D89X2){ + rwnx_plat_userconfig_load_8800d80x2(rwnx_hw); } return 0; diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_platform.h b/drivers/aic8800/aic8800_fdrv/rwnx_platform.h index e957763..7d54740 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_platform.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_platform.h @@ -64,6 +64,31 @@ enum rwnx_platform_addr { RWNX_ADDR_MAX, }; +typedef struct +{ + txpwr_lvl_conf_t txpwr_lvl; + txpwr_lvl_conf_v2_t txpwr_lvl_v2; + txpwr_lvl_conf_v3_t txpwr_lvl_v3; + txpwr_lvl_conf_v4_t txpwr_lvl_v4; + txpwr_lvl_adj_conf_t txpwr_lvl_adj; + txpwr_loss_conf_t txpwr_loss; + txpwr_ofst_conf_t txpwr_ofst; + txpwr_ofst2x_conf_t txpwr_ofst2x; + txpwr_ofst2x_conf_v2_t txpwr_ofst2x_v2; + xtal_cap_conf_t xtal_cap; +} userconfig_info_t; + +extern userconfig_info_t userconfig_info; + +typedef enum { + REGIONS_SRRC, + REGIONS_FCC, + REGIONS_ETSI, + REGIONS_JP, + REGIONS_DEFAULT, +} Regions_code; + + struct rwnx_hw; /** @@ -129,15 +154,24 @@ int is_file_exist(char* name); void get_userconfig_txpwr_lvl_in_fdrv(txpwr_lvl_conf_t *txpwr_lvl); void get_userconfig_txpwr_lvl_v2_in_fdrv(txpwr_lvl_conf_v2_t *txpwr_lvl_v2); void get_userconfig_txpwr_lvl_v3_in_fdrv(txpwr_lvl_conf_v3_t *txpwr_lvl_v3); +void get_userconfig_txpwr_lvl_v4_in_fdrv(txpwr_lvl_conf_v4_t *txpwr_lvl_v4); void get_userconfig_txpwr_lvl_adj_in_fdrv(txpwr_lvl_adj_conf_t *txpwr_lvl_adj); void get_userconfig_txpwr_ofst_in_fdrv(txpwr_ofst_conf_t *txpwr_ofst); void get_userconfig_txpwr_ofst2x_in_fdrv(txpwr_ofst2x_conf_t *txpwr_ofst2x); +void get_userconfig_txpwr_ofst2x_v2_in_fdrv(txpwr_ofst2x_conf_v2_t *txpwr_ofst2x_v2); void get_userconfig_txpwr_loss(txpwr_loss_conf_t *txpwr_loss); +void set_txpwr_loss_ofst(s8_l value); void rwnx_plat_userconfig_parsing(char *buffer, int size); + +uint8_t get_ccode_region(char * ccode); +u8 get_region_index(char * name); + + #ifdef CONFIG_POWER_LIMIT +int8_t rwnx_plat_powerlimit_save(u8_l band, char *channel, u8_l bw, char *limit, char *name); void rwnx_plat_powerlimit_parsing(char *buffer, int size, char *cc); -int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq); -int8_t get_powerlimit_by_chnum(uint8_t chnum); +int8_t get_powerlimit_by_freq(uint8_t band, uint16_t freq, uint8_t r_idx); +int8_t get_powerlimit_by_chnum(uint8_t chnum, uint8_t r_idx, uint8_t bw); #endif int rwnx_platform_register_drv(void); void rwnx_platform_unregister_drv(void); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_radar.c b/drivers/aic8800/aic8800_fdrv/rwnx_radar.c index bc65c45..947b713 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_radar.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_radar.c @@ -288,7 +288,7 @@ struct pri_detector { */ struct pri_detector_ops { void (*init)(struct pri_detector *pde); - struct pri_sequence * (*add_pulse)(struct pri_detector *pde, u16 len, u64 ts, u16 pri); + struct pri_sequence * (*add_pulse)(struct rwnx_radar *radar, struct pri_detector *pde, u16 len, u64 ts, u16 pri); int reset_on_pri_overflow; }; @@ -708,7 +708,7 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts); * - If not save this pulse in the list */ static -struct pri_sequence *pde_short_add_pulse(struct pri_detector *pde, +struct pri_sequence *pde_short_add_pulse(struct rwnx_radar *radar, struct pri_detector *pde, u16 len, u64 ts, u16 pri) { u32 max_updated_seq; @@ -798,12 +798,16 @@ void pde_long_init(struct pri_detector *pde) * has been detected. */ static -struct pri_sequence *pde_long_add_pulse(struct pri_detector *pde, +struct pri_sequence *pde_long_add_pulse(struct rwnx_radar *radar, struct pri_detector *pde, u16 len, u64 ts, u16 pri) { struct pri_sequence *ps; const struct radar_detector_specs *rs = pde->rs; + if(radar->status != RWNX_RADAR_CAC_BUSY) { + return NULL; + } + if (list_empty(&pde->sequences)) { /* First pulse, create a new sequence */ ps = pool_get_pseq_elem(); @@ -1066,6 +1070,35 @@ static void dfs_pattern_detector_pri_overflow(struct dfs_pattern_detector *dpd) } } +void print_radar_detect_info(struct pri_detector *pde, struct pri_sequence *ps) +{ + struct radar_detector_specs *rs = (struct radar_detector_specs *)pde->rs; + struct pulse_elem *p; + u16 idx = 0; + + AICWFDBG(LOGINFO, "aic dfs detected: %d, %d, %d\n", pde->window_size, pde->count, pde->max_count); + AICWFDBG(LOGINFO, "\t rs: %u %u\n", rs->type, rs->type_id); + AICWFDBG(LOGINFO, "\t rs: width[%u, %u]\n", rs->width_min, rs->width_max); + AICWFDBG(LOGINFO, "\t rs: pri[%u, %u] %u\n", rs->pri_min, rs->pri_max, rs->num_pri); + AICWFDBG(LOGINFO, "\t rs: %u/%u %u\n", rs->ppb, rs->ppb_thresh, rs->max_pri_tolerance); + + AICWFDBG(LOGINFO, "\t ps.pri = %u\n" , ps->pri ); + AICWFDBG(LOGINFO, "\t ps.dur = %u\n" , ps->dur ); + AICWFDBG(LOGINFO, "\t ps.count = %u\n" , ps->count ); + AICWFDBG(LOGINFO, "\t ps.count_falses = %u\n" , ps->count_falses ); + AICWFDBG(LOGINFO, "\t ps.first_ts = %lu\n", (long unsigned int)ps->first_ts ); + AICWFDBG(LOGINFO, "\t ps.last_ts = %lu\n", (long unsigned int)ps->last_ts ); + AICWFDBG(LOGINFO, "\t ps.deadline_ts = %lu\n", (long unsigned int)ps->deadline_ts ); + AICWFDBG(LOGINFO, "\t ps.ppb_thresh = %u\n" , ps->ppb_thresh ); + + AICWFDBG(LOGINFO, "\t pulses -->\n"); + list_for_each_entry_reverse(p, &pde->pulses, head) { + AICWFDBG(LOGINFO, "\t %u: %lu\n", idx, (long unsigned int)p->ts); + idx++; + } +} + + /** * dfs_pattern_detector_add_pulse - Process one pulse * @@ -1082,7 +1115,7 @@ static void dfs_pattern_detector_pri_overflow(struct dfs_pattern_detector *dpd) * * @return True is the pulse complete a radar pattern, false otherwise */ -static bool dfs_pattern_detector_add_pulse(struct dfs_pattern_detector *dpd, +static bool dfs_pattern_detector_add_pulse(struct rwnx_radar *radar, struct dfs_pattern_detector *dpd, enum rwnx_radar_chain chain, u16 freq, u16 pri, u16 len, u32 now) { @@ -1122,9 +1155,10 @@ static bool dfs_pattern_detector_add_pulse(struct dfs_pattern_detector *dpd, } pde = pri_detector_get(dpd, freq, i); - ps = pde->ops->add_pulse(pde, len, dpd->last_pulse_ts, pri); + ps = pde->ops->add_pulse(radar, pde, len, dpd->last_pulse_ts, pri); if (ps != NULL) { + print_radar_detect_info(pde, ps); #ifdef CREATE_TRACE_POINTS trace_radar_detected(chain, dpd->region, pde->freq, i, ps->pri); #endif @@ -1207,6 +1241,8 @@ bool dfs_pattern_detector_set_domain(struct dfs_pattern_detector *dpd, dpd->num_radar_types = rt->num_radar_types; dpd->region = region; + + AICWFDBG(LOGINFO,"set_region %d \n",region); return true; } @@ -1269,6 +1305,8 @@ static void rwnx_radar_detected(struct rwnx_hw *rwnx_hw) #ifdef CONFIG_RWNX_FULLMAC struct cfg80211_chan_def chan_def; + RWNX_DBG(RWNX_FN_ENTRY_STR); + if (!rwnx_chanctx_valid(rwnx_hw, rwnx_hw->cur_chanctx)) { WARN(1, "Radar detected without channel information"); return; @@ -1296,6 +1334,9 @@ static void rwnx_radar_process_pulse(struct work_struct *ws) u32 pulses[RWNX_RADAR_LAST][RWNX_RADAR_PULSE_MAX]; u16 pulses_count[RWNX_RADAR_LAST]; u32 now = jiffies; /* would be better to store jiffies value in IT handler */ + #ifdef RWNX_RADAR_DUMP_EN + struct rwnx_radar_dump *rm = radar->rmem; + #endif /* recopy pulses locally to avoid too long spin_lock */ spin_lock_bh(&radar->lock); @@ -1344,11 +1385,51 @@ static void rwnx_radar_process_pulse(struct work_struct *ws) #ifdef CREATE_TRACE_POINTS trace_radar_pulse(chain, p); #endif - if (dfs_pattern_detector_add_pulse(radar->dpd[chain], chain, - (s16)freq + (2 * p->freq), - p->rep, (p->len * 2), now)) { + #ifdef RWNX_RADAR_DUMP_EN + if(chain == RWNX_RADAR_RIU) { + u16 pri; + struct dfs_pattern_detector *dpd = NULL; + rm->ps[rm->idx] = pulses[chain][i]; + rm->tm[rm->idx] = now; + rm->cnt ++; + + pri = p->rep; + dpd = radar->dpd[chain]; + if (pri == 0) { + u32 delta_jiffie; + if (unlikely(now < dpd->prev_jiffies)) { + delta_jiffie = 0xffffffff - dpd->prev_jiffies + now; + } else { + delta_jiffie = now - dpd->prev_jiffies; + } + rm->ts[rm->idx] = dpd->last_pulse_ts + jiffies_to_usecs(delta_jiffie); + } else { + rm->ts[rm->idx] = dpd->last_pulse_ts + pri; + } + rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB; + } + #endif + if((radar->status != RWNX_RADAR_CAC_BUSY) && (radar->status != RWNX_RADAR_INSERVICE_BUSY)) { + break; + } + AICWFDBG(LOGTRACE, "+r:%x\n", *(uint32_t *)p); + if (dfs_pattern_detector_add_pulse(radar, radar->dpd[chain], chain, + (s16)freq + (2 * p->freq), + p->rep, (p->len * 2), now)) { + u16 idx = radar->detected[chain].index; + #ifdef RWNX_RADAR_DUMP_EN + if (chain == RWNX_RADAR_RIU) { + int k; + AICWFDBG(LOGINFO, "\t received pulses %d %d\n", rm->cnt, rm->idx-1); + for(k=0; kidx, rm->ps[rm->idx], rm->ts[rm->idx], rm->tm[rm->idx]); + rm->idx = (rm->idx + 1) % RWNX_RADARR_DUMP_NB; + } + } + #endif + if (chain == RWNX_RADAR_RIU) { /* operating chain, inform upper layer to change channel */ if (radar->dpd[chain]->enabled == RWNX_RADAR_DETECT_REPORT) { @@ -1399,11 +1480,11 @@ static void rwnx_radar_cac_work(struct work_struct *ws) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) &ctxt->chan_def, #endif - NL80211_RADAR_CAC_FINISHED, GFP_KERNEL - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) - , 0 - #endif - ); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0); +#else + NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); +#endif rwnx_send_apm_stop_cac_req(rwnx_hw, radar->cac_vif); rwnx_chanctx_unlink(radar->cac_vif); @@ -1411,6 +1492,36 @@ static void rwnx_radar_cac_work(struct work_struct *ws) } #endif /* CONFIG_RWNX_FULLMAC */ + +void rwnx_radar_reset_rmem(struct rwnx_radar *radar) +{ +#ifdef RWNX_RADAR_DUMP_EN + if (radar->rmem != NULL) { + memset((void *)radar->rmem, 0, sizeof(*radar->rmem)); + } +#endif +} + +void rwnx_radar_init_rmem(struct rwnx_radar *radar) +{ +#ifdef RWNX_RADAR_DUMP_EN + if (radar->rmem == NULL) { + radar->rmem = kmalloc(sizeof(*radar->rmem), GFP_ATOMIC); + } + rwnx_radar_reset_rmem(radar); +#endif +} + +void rwnx_radar_deinit_rmem(struct rwnx_radar *radar) +{ +#ifdef RWNX_RADAR_DUMP_EN + if (radar->rmem != NULL) { + kfree(radar->rmem); + } +#endif +} + + bool rwnx_radar_detection_init(struct rwnx_radar *radar) { spin_lock_init(&radar->lock); @@ -1422,6 +1533,10 @@ bool rwnx_radar_detection_init(struct rwnx_radar *radar) radar->dpd[RWNX_RADAR_FCU] = dfs_pattern_detector_init(NL80211_DFS_UNSET, RWNX_RADAR_FCU); + rwnx_radar_init_rmem(radar); + radar->status = RWNX_RADAR_IDLE; + AICWFDBG(LOGINFO, "DFS: radar st = %d\n", radar->status); + if (radar->dpd[RWNX_RADAR_FCU] == NULL) { rwnx_radar_detection_deinit(radar); return false; @@ -1445,11 +1560,13 @@ void rwnx_radar_detection_deinit(struct rwnx_radar *radar) dfs_pattern_detector_exit(radar->dpd[RWNX_RADAR_FCU]); radar->dpd[RWNX_RADAR_FCU] = NULL; } + rwnx_radar_deinit_rmem(radar); } bool rwnx_radar_set_domain(struct rwnx_radar *radar, enum nl80211_dfs_regions region) { + AICWFDBG(LOGINFO, "%s \n",__func__); if (radar->dpd[0] == NULL) return false; #ifdef CREATE_TRACE_POINTS @@ -1463,6 +1580,7 @@ bool rwnx_radar_set_domain(struct rwnx_radar *radar, void rwnx_radar_detection_enable(struct rwnx_radar *radar, u8 enable, u8 chain) { + //printk("%s enable:%u chain:%u \n",__func__,enable,chain); if (chain < RWNX_RADAR_LAST ) { #ifdef CREATE_TRACE_POINTS trace_radar_enable_detection(radar->dpd[chain]->region, enable, chain); @@ -1503,11 +1621,11 @@ void rwnx_radar_cancel_cac(struct rwnx_radar *radar) #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) &ctxt->chan_def, #endif - NL80211_RADAR_CAC_ABORTED, GFP_KERNEL - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) - , 0 - #endif - ); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + NL80211_RADAR_CAC_FINISHED, GFP_KERNEL, 0); +#else + NL80211_RADAR_CAC_ABORTED, GFP_KERNEL); +#endif rwnx_chanctx_unlink(radar->cac_vif); } diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_radar.h b/drivers/aic8800/aic8800_fdrv/rwnx_radar.h index 355320f..5e2b8e4 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_radar.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_radar.h @@ -82,11 +82,33 @@ struct rwnx_radar_detected { s16 freq[NX_NB_RADAR_DETECTED]; }; - +#define RWNX_RADAR_DUMP_EN 1 +#ifdef RWNX_RADAR_DUMP_EN +#define RWNX_RADARR_DUMP_NB 32 +struct rwnx_radar_dump { + u32 cnt; + u32 idx; + u32 ps[RWNX_RADARR_DUMP_NB]; + u64 tm[RWNX_RADARR_DUMP_NB]; + u64 ts[RWNX_RADARR_DUMP_NB]; +}; +#endif +enum rwnx_radar_status { + RWNX_RADAR_IDLE = 0, + RWNX_RADAR_CAC_BUSY = 1, + RWNX_RADAR_CAC_DONE = 2, + RWNX_RADAR_INSERVICE_BUSY = 3, + RWNX_RADAR_INSERVICE_DONE = 4 +}; struct rwnx_radar { struct rwnx_radar_pulses pulses[RWNX_RADAR_LAST]; struct dfs_pattern_detector *dpd[RWNX_RADAR_LAST]; struct rwnx_radar_detected detected[RWNX_RADAR_LAST]; + #ifdef RWNX_RADAR_DUMP_EN + struct rwnx_radar_dump *rmem; + #endif + u16 status; + u16 sta_num; struct work_struct detection_work; /* Work used to process radar pulses */ spinlock_t lock; /* lock for pulses processing */ @@ -97,6 +119,10 @@ struct rwnx_radar { #endif }; +void rwnx_radar_reset_rmem(struct rwnx_radar *radar); +void rwnx_radar_init_rmem(struct rwnx_radar *radar); +void rwnx_radar_deinit_rmem(struct rwnx_radar *radar); + bool rwnx_radar_detection_init(struct rwnx_radar *radar); void rwnx_radar_detection_deinit(struct rwnx_radar *radar); bool rwnx_radar_set_domain(struct rwnx_radar *radar, diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c index 13f4330..eb6d60a 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.c @@ -25,6 +25,10 @@ #include #include "rwnx_msg_tx.h" #endif +#include "rwnx_main.h" +#ifdef CONFIG_BAND_STEERING +#include "aicwf_manager.h" +#endif #ifndef IEEE80211_MAX_CHAINS #define IEEE80211_MAX_CHAINS 4 @@ -47,46 +51,56 @@ u16 tx_legrates_lut_rate[] = { 540 }; - -u16 legrates_lut_rate[] = { - 10 , - 20 , - 55 , - 110 , - 0 , - 0 , - 0 , - 0 , - 480 , - 240 , - 120 , - 60 , - 540 , - 360 , - 180 , - 90 +struct rwnx_legrate legrates_lut[] = { + [0] = { .idx = 0, .rate = 10}, + [1] = { .idx = 1, .rate = 20}, + [2] = { .idx = 2, .rate = 55}, + [3] = { .idx = 3, .rate = 110}, + [4] = { .idx = -1, .rate = 0}, + [5] = { .idx = -1, .rate = 0}, + [6] = { .idx = -1, .rate = 0}, + [7] = { .idx = -1, .rate = 0}, + [8] = { .idx = 10, .rate = 480}, + [9] = { .idx = 8, .rate = 240}, + [10] = { .idx = 6, .rate = 120}, + [11] = { .idx = 4, .rate = 60}, + [12] = { .idx = 11, .rate = 540}, + [13] = { .idx = 9, .rate = 360}, + [14] = { .idx = 7, .rate = 180}, + [15] = { .idx = 5, .rate = 90}, }; +#ifdef CONFIG_BAND_STEERING +typedef struct _op_class_ { + u8_l op_class; + u8_l band; /* 0: 2.4g, 1: 5g*/ +} _op_class_; -const u8 legrates_lut[] = { - 0, /* 0 */ - 1, /* 1 */ - 2, /* 2 */ - 3, /* 3 */ - -1, /* 4 */ - -1, /* 5 */ - -1, /* 6 */ - -1, /* 7 */ - 10, /* 8 */ - 8, /* 9 */ - 6, /* 10 */ - 4, /* 11 */ - 11, /* 12 */ - 9, /* 13 */ - 7, /* 14 */ - 5 /* 15 */ +static const _op_class_ g_op_class[] = { + { 81, BAND_ON_24G }, + { 82, BAND_ON_24G }, + { 83, BAND_ON_24G }, + { 84, BAND_ON_24G }, + { 115, BAND_ON_5G }, + { 116, BAND_ON_5G }, + { 117, BAND_ON_5G }, + { 118, BAND_ON_5G }, + { 119, BAND_ON_5G }, + { 120, BAND_ON_5G }, + { 121, BAND_ON_5G }, + { 122, BAND_ON_5G }, + { 123, BAND_ON_5G }, + { 124, BAND_ON_5G }, + { 125, BAND_ON_5G }, + { 126, BAND_ON_5G }, + { 127, BAND_ON_5G }, + { 128, BAND_ON_5G } }; +#define BAND_CAP_2G BIT(BAND_ON_24G) +#define BAND_CAP_5G BIT(BAND_ON_5G) +#endif + struct vendor_radiotap_hdr { u8 oui[3]; u8 subns; @@ -285,7 +299,7 @@ static void rwnx_rx_statistic(struct rwnx_hw *rwnx_hw, struct hw_rxhdr *hw_rxhdr break; } } else { - int idx = legrates_lut[rxvect->leg_rate]; + int idx = legrates_lut[rxvect->leg_rate].idx; if (idx < 4) { rate_idx = idx * 2 + rxvect->pre_type; } else { @@ -327,8 +341,7 @@ static void rwnx_rx_statistic(struct rwnx_hw *rwnx_hw, struct hw_rxhdr *hw_rxhdr cpu_raise_softirq(smp_processor_id(), NET_RX_SOFTIRQ) #endif /* LINUX_VERSION_CODE */ -void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, - struct sk_buff *skb, struct hw_rxhdr *rxhdr) +void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *skb) { struct sk_buff *rx_skb = skb; //bool amsdu = rxhdr->flags_is_amsdu; @@ -369,8 +382,7 @@ void rwnx_rx_data_skb_resend(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, } } #ifdef AICWF_RX_REORDER -static void rwnx_rx_data_skb_forward(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, - struct sk_buff *skb, struct hw_rxhdr *rxhdr) +static void rwnx_rx_data_skb_forward(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *skb) { struct sk_buff *rx_skb; @@ -457,16 +469,19 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct sk_buff *rx_skb; bool amsdu = rxhdr->flags_is_amsdu; bool resend = false, forward = true; + u8 flags_vif_idx = rxhdr->flags_vif_idx; + u8 flags_dst_idx = rxhdr->flags_dst_idx; skb->dev = rwnx_vif->ndev; __skb_queue_head_init(&list); if (amsdu) { + #if 1 + rwnx_rxdata_process_amsdu(rwnx_hw, skb, flags_vif_idx, &list); + #else int count; -// Debian 6.1.0-26 backported the new function call, but not Ubuntu 6.2. -#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) || \ - (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 109) && LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0)) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) ieee80211_amsdu_to_8023s(skb, &list, rwnx_vif->ndev->dev_addr, RWNX_VIF_TYPE(rwnx_vif), 0, NULL, NULL, false); #else @@ -478,6 +493,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, if (count > ARRAY_SIZE(rwnx_hw->stats.amsdus_rx)) count = ARRAY_SIZE(rwnx_hw->stats.amsdus_rx); rwnx_hw->stats.amsdus_rx[count - 1]++; + #endif } else { rwnx_hw->stats.amsdus_rx[0]++; __skb_queue_head(&list, skb); @@ -499,9 +515,9 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, } else { /* unicast pkt for STA inside the BSS, no need to forward to upper layer simply resend on wireless interface */ - if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) + if (flags_dst_idx != RWNX_INVALID_STA) { - struct rwnx_sta *sta = &rwnx_hw->sta_table[rxhdr->flags_dst_idx]; + struct rwnx_sta *sta = &rwnx_hw->sta_table[flags_dst_idx]; if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) { forward = false; @@ -518,7 +534,7 @@ static bool rwnx_rx_data_skb(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, if (!is_multicast_ether_addr(eth->h_dest)) { /* unicast pkt for STA inside the BSS, no need to forward to upper layer simply resend on wireless interface */ - if (rxhdr->flags_dst_idx != RWNX_INVALID_STA) + if (flags_dst_idx != RWNX_INVALID_STA) { forward = false; resend = true; @@ -675,6 +691,81 @@ static inline const u8 *cfg80211_find_ext_ie(u8 ext_eid, const u8* ies, int len) #endif +#ifdef CONFIG_BAND_STEERING +static void handle_op_class_band(struct tmp_feature_sta *f_sta, const u8 *ie, int ie_len) +{ + int op_num, i, j; + u8 op_class; + + if (!ie) { + return; + } + + op_num = ie[1]; + for (i = 0; i < op_num; i++) { + op_class = ie[i + 2]; + for (j = 0; j < ARRAY_SIZE(g_op_class); j++) { + if (op_class == g_op_class[j].op_class) { + switch (g_op_class[j].band) { + case BAND_ON_24G: + f_sta->supported_band |= BAND_CAP_2G; + break; + case BAND_ON_5G: + f_sta->supported_band |= BAND_CAP_5G; + break; + default: + break; + } + break; + } + } + } +} + +static void set_band_by_freq(struct tmp_feature_sta *f_sta, u16 freq) +{ + if (freq >= 5180) { + f_sta->supported_band |= BAND_CAP_5G; + } else { + f_sta->supported_band |= BAND_CAP_2G; + } +} + +static void handle_assoc_request(struct rwnx_vif *rwnx_vif, + struct tmp_feature_sta *f_sta, + struct ieee80211_mgmt *mgmt, + struct sk_buff *skb, + struct rx_vector_1 *rxvect, + struct hw_rxhdr *hw_rxhdr, + bool is_reassoc) +{ + const u8 *ie; + u8 *variable_field; + size_t variable_len; + + aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_ASSOCREQ, mgmt->sa, rxvect->rssi1); + f_sta->sta_idx = rwnx_vif->ap.tmp_sta_idx; + + if (is_reassoc) { + variable_field = mgmt->u.reassoc_req.variable; + } else { + variable_field = mgmt->u.assoc_req.variable; + } + variable_len = skb->len - (variable_field - skb->data); + + ie = cfg80211_find_ie(WLAN_EID_SUPPORTED_REGULATORY_CLASSES, + variable_field, variable_len); + + if (ie) { + handle_op_class_band(f_sta, ie, variable_len); + AICWFDBG(LOGINFO, "%s usb %sassoc supported_band: %u\n", __func__, + is_reassoc ? "re" : "", f_sta->supported_band); + } else { + AICWFDBG(LOGINFO, "%s usb %sassoc no find op_class\n", __func__, is_reassoc ? "re" : ""); + set_band_by_freq(f_sta, hw_rxhdr->phy_info.phy_prim20_freq); + } +} +#endif /** * rwnx_rx_mgmt - Process one 802.11 management frame @@ -693,9 +784,54 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, struct rx_vector_1 *rxvect = &hw_rxhdr->hwvect.rx_vect1; #ifdef CONFIG_HE_FOR_OLD_KERNEL struct ieee80211_he_cap_elem *he; + struct ieee80211_he_mcs_nss_supp *he_mcs; +#endif + + //printk("rwnx_rx_mgmt\n"); + if(skb->data[0]!=0x80 && skb->data[0] != 0x40) + AICWFDBG(LOGDEBUG,"rxmgmt:%x,%x\n", skb->data[0], skb->data[1]); + +#ifdef CONFIG_BAND_STEERING + bool queued = false; + struct tmp_feature_sta *f_sta = &rwnx_hw->feature_table[rwnx_vif->ap.tmp_sta_idx]; + if (RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_AP) { +#if 0 + if(skb->data[0] != 0x80) + printk("rx mgmt:%02x\n", mgmt->frame_control); +#endif + + if (ieee80211_is_assoc_req(mgmt->frame_control)) { + handle_assoc_request(rwnx_vif, f_sta, mgmt, skb, rxvect, hw_rxhdr, false); + } else if (ieee80211_is_reassoc_req(mgmt->frame_control)) { + handle_assoc_request(rwnx_vif, f_sta, mgmt, skb, rxvect, hw_rxhdr, true); + } + + if (ieee80211_is_auth(mgmt->frame_control)) { + aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_AUTH, mgmt->sa, rxvect->rssi1); + } + + if (ieee80211_is_probe_req(mgmt->frame_control)) { + if (!rwnx_vif->ap.start) + return; + aicwf_nl_send_frame_rpt_msg(rwnx_vif, WIFI_PROBEREQ, mgmt->sa, rxvect->rssi1); + AICWFDBG(LOGSTEER, "usb rx p_req: %pM\n", mgmt->sa); + for (int i = 0; i < MAX_PENDING_PROBES; i++) { + if (!rwnx_vif->pb_pool[i].in_use) { + rwnx_vif->pb_pool[i].in_use = true; + memcpy(rwnx_vif->pb_pool[i].da, mgmt->sa, 6); + queue_work(rwnx_vif->rsp_wq, &rwnx_vif->pb_pool[i].rsp_work); + queued = true; + break; + } + } + if (!queued) + AICWFDBG(LOGERROR, "usb probe_rsp pool full, drop %pM\n", mgmt->sa); + return; + } + + } #endif - //printk("rwnx_rx_mgmt\n"); #if (defined CONFIG_HE_FOR_OLD_KERNEL) || (defined CONFIG_VHT_FOR_OLD_KERNEL) struct aic_sta *sta = &rwnx_hw->aic_table[rwnx_vif->ap.aic_index]; const u8* ie; @@ -710,6 +846,12 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, ie = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, mgmt->u.assoc_req.variable, len); if (ie && ie[1] >= sizeof(*he) + 1) { printk("assoc_req: find he\n"); + he = (struct ieee80211_he_cap_elem *)(ie+3); + he_mcs = (struct ieee80211_he_mcs_nss_supp *)((u8 *)he + sizeof(*he)); + memcpy(&sta->he_cap_elem,ie+3,sizeof(struct ieee80211_he_cap_elem)); + + sta->he_mcs_nss_supp.rx_mcs_80 = he_mcs->rx_mcs_80; + sta->he_mcs_nss_supp.tx_mcs_80 = he_mcs->tx_mcs_80; sta->he = true; } else { @@ -723,6 +865,8 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, ie = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, mgmt->u.assoc_req.variable, len); if (ie && ie[1] >= sizeof(*vht)) { printk("assoc_req: find vht\n"); + memcpy(&sta->vht_cap_info,ie+2,4); + memcpy(&sta->supp_mcs,ie+2+4,sizeof(struct ieee80211_vht_mcs_info)); sta->vht = true; } else { printk("assoc_req: no find vht\n"); @@ -730,8 +874,20 @@ static void rwnx_rx_mgmt(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, } #endif } + if (ieee80211_is_deauth(mgmt->frame_control) && rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) { + printk("DEAUTH: sta_idx %d MAC %pM reason:%x\n", rwnx_vif->ap.aic_index, mgmt->sa, mgmt->u.deauth.reason_code); + } + if (ieee80211_is_disassoc(mgmt->frame_control) && rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) { + printk("DISASSOC: sta_idx %d MAC %pM reason:%x\n", rwnx_vif->ap.aic_index, mgmt->sa, mgmt->u.disassoc.reason_code); + } #endif + /*if (ieee80211_is_mgmt(mgmt->frame_control) && + (skb->len <= 24 || skb->len > 768)) { + printk("mgmt err\n"); + return; + }*/ + if (ieee80211_is_beacon(mgmt->frame_control)) { if ((RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_MESH_POINT) && hw_rxhdr->flags_new_peer) { @@ -1020,7 +1176,7 @@ static void rwnx_rx_add_rtap_hdr(struct rwnx_hw* rwnx_hw, struct ieee80211_supported_band* band = rwnx_hw->wiphy->bands[phy_info->phy_band]; rtap->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE); - BUG_ON((rate_idx = legrates_lut[rxvect->leg_rate]) == -1); + BUG_ON((rate_idx = legrates_lut[rxvect->leg_rate].idx) == -1); if (phy_info->phy_band == NL80211_BAND_5GHZ) rate_idx -= 4; /* rwnx_ratetable_5ghz[0].hw_value == 4 */ *pos = DIV_ROUND_UP(band->bitrates[rate_idx].bitrate, 5); @@ -1347,6 +1503,7 @@ struct reord_ctrl_info *reord_init_sta(struct aicwf_rx_priv* rx_priv, const u8 * return NULL; } + AICWFDBG(LOGINFO, "reord_init_sta:%pM\n", mac_addr); reord_info = kmalloc(sizeof(struct reord_ctrl_info), GFP_ATOMIC); if (!reord_info) return NULL; @@ -1428,11 +1585,7 @@ int reord_flush_tid(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u8 tid) preorder_ctrl->enable = false; spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags); if (timer_pending(&preorder_ctrl->reord_timer)) - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - ret = timer_delete_sync(&preorder_ctrl->reord_timer); - #else - ret = del_timer_sync(&preorder_ctrl->reord_timer); - #endif + ret = del_timer_sync(&preorder_ctrl->reord_timer); cancel_work_sync(&preorder_ctrl->reord_timer_work); return 0; @@ -1458,11 +1611,7 @@ void reord_deinit_sta(struct aicwf_rx_priv* rx_priv, struct reord_ctrl_info *reo if(preorder_ctrl->enable){ preorder_ctrl->enable = false; if (timer_pending(&preorder_ctrl->reord_timer)) { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - ret = timer_delete_sync(&preorder_ctrl->reord_timer); - #else - ret = del_timer_sync(&preorder_ctrl->reord_timer); - #endif + ret = del_timer_sync(&preorder_ctrl->reord_timer); } cancel_work_sync(&preorder_ctrl->reord_timer_work); } @@ -1492,31 +1641,13 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr struct list_head *rxframes_freequeue = NULL; struct sk_buff *skb = NULL; struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; + struct sk_buff_head list; + struct sk_buff *rx_skb; rxframes_freequeue = &rx_priv->rxframes_freequeue; skb = prframe->pkt; - if (skb == NULL) { - txrx_err("skb is NULL\n"); - return -1; - } - if(!prframe->forward) { - //printk("single: %d not forward: drop\n", prframe->seq_num); - dev_kfree_skb(skb); - prframe->pkt = NULL; - reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); - return 0; - } - - skb->data = prframe->rx_data; - skb_set_tail_pointer(skb, prframe->len); - skb->len = prframe->len; - - rwnx_vif->net_stats.rx_packets++; - rwnx_vif->net_stats.rx_bytes += skb->len; - //printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len); - -#ifdef CONFIG_BR_SUPPORT + #ifdef CONFIG_BR_SUPPORT void *br_port = NULL; if (1) {//(check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) { @@ -1541,54 +1672,110 @@ int reord_single_frame_ind(struct aicwf_rx_priv *rx_priv, struct recv_msdu *prfr } #endif /* CONFIG_BR_SUPPORT */ - skb->dev = rwnx_vif->ndev; + if (skb == NULL) { + txrx_err("skb is NULL\n"); + return -1; + } -#if 0 - if(test_log_flag){ - if(skb->data[42] == 0x80){ - printk("AIDEN : SN:%d R_SN:%d pid:%d\r\n", - prframe->seq_num, (skb->data[44] << 8| skb->data[45]), current->pid); - } - } -#endif - rwnx_skb_align_8bytes(skb); + if(prframe->is_ap_reord) { + if(prframe->ap_resend_cnt) { + struct sk_buff *resend_skb = prframe->first_resend_skb; + struct sk_buff *resend_next_skb; + u8 resend_cnt = 0; + while(resend_skb) { + resend_cnt++; + resend_next_skb = resend_skb->next; + dev_kfree_skb(resend_skb); + resend_skb = resend_next_skb; + } + if(resend_cnt != prframe->ap_resend_cnt) + printk("resend cnt error: %d,%d\n", resend_cnt, prframe->ap_resend_cnt); - skb->protocol = eth_type_trans(skb, rwnx_vif->ndev); + if(!prframe->ap_fwd_cnt) { + prframe->pkt = NULL; + reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); + return 0; + } //else + // printk("both has resend & fwd\n"); + } + } else { + if(!prframe->forward) { + dev_kfree_skb(skb); + prframe->pkt = NULL; + reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); + return 0; + } + } + + __skb_queue_head_init(&list); + if(!prframe->is_ap_reord) + { + if(prframe->is_amsdu) { + rwnx_rxdata_process_amsdu(rwnx_vif->rwnx_hw, skb, rwnx_vif->vif_index, &list); //rxhdr not used below since skb free! + } else { + __skb_queue_head(&list, skb); + } + } else { + struct sk_buff *fwd_skb = prframe->first_fwd_skb; + struct sk_buff *fwd_next_skb; + u8 fwd_cnt = 0; + while(fwd_skb) { + //printk("single ind:%p\n", fwd_skb); + fwd_cnt++; + fwd_next_skb = fwd_skb->next; + __skb_queue_tail(&list, fwd_skb); + fwd_skb = fwd_next_skb; + } + if(fwd_cnt != prframe->ap_fwd_cnt) + printk("fwd cnt error: %d,%d\n", fwd_cnt, prframe->ap_fwd_cnt); + } + + while (!skb_queue_empty(&list)) { + rx_skb = __skb_dequeue(&list); + + rwnx_vif->net_stats.rx_packets++; + rwnx_vif->net_stats.rx_bytes += rx_skb->len; + //printk("netif sn=%d, len=%d\n", precv_frame->attrib.seq_num, skb->len); + rx_skb->dev = rwnx_vif->ndev; + rwnx_skb_align_8bytes(rx_skb); + rx_skb->protocol = eth_type_trans(rx_skb, rwnx_vif->ndev); #ifdef AICWF_ARP_OFFLOAD - if(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { - arpoffload_proc(skb, rwnx_vif); - } + if(RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_STATION || RWNX_VIF_TYPE(rwnx_vif) == NL80211_IFTYPE_P2P_CLIENT) { + arpoffload_proc(rx_skb, rwnx_vif); + } #endif - memset(skb->cb, 0, sizeof(skb->cb)); + memset(rx_skb->cb, 0, sizeof(rx_skb->cb)); #ifdef CONFIG_FILTER_TCP_ACK - filter_rx_tcp_ack(rwnx_vif->rwnx_hw, skb->data, cpu_to_le16(skb->len)); + filter_rx_tcp_ack(rwnx_vif->rwnx_hw, rx_skb->data, cpu_to_le16(rx_skb->len)); #endif #ifdef CONFIG_RX_NETIF_RECV_SKB//AIDEN test - local_bh_disable(); - netif_receive_skb(skb); - local_bh_enable(); + local_bh_disable(); + netif_receive_skb(rx_skb); + local_bh_enable(); #else - if (in_interrupt()) { - netif_rx(skb); - } else { - /* - * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ. - * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually. - */ + if (in_interrupt()) { + netif_rx(rx_skb); + } else { + /* + * If the receive is not processed inside an ISR, the softirqd must be woken explicitly to service the NET_RX_SOFTIRQ. + * * In 2.6 kernels, this is handledby netif_rx_ni(), but in earlier kernels, we need to do it manually. + */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - netif_rx_ni(skb); + netif_rx_ni(rx_skb); #else - ulong flags; - netif_rx(skb); - local_irq_save(flags); - RAISE_RX_SOFTIRQ(); - local_irq_restore(flags); + ulong flags; + netif_rx(rx_skb); + local_irq_save(flags); + RAISE_RX_SOFTIRQ(); + local_irq_restore(flags); #endif - } + } #endif//CONFIG_RX_NETIF_RECV_SKB + } + prframe->pkt = NULL; reord_rxframe_free(&rx_priv->freeq_lock, rxframes_freequeue, &prframe->rxframe_list); @@ -1715,45 +1902,38 @@ void reord_timeout_worker(struct work_struct *work) return ; } -int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward) +int reord_process_unit(struct recv_msdu *pframe, struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 seq_num, u8 tid, u8 forward, u8 is_amsdu) { int ret=0; u8 *mac; - struct recv_msdu *pframe; struct reord_ctrl *preorder_ctrl; struct reord_ctrl_info *reord_info; struct rwnx_vif *rwnx_vif = (struct rwnx_vif *)rx_priv->rwnx_vif; struct ethhdr *eh = (struct ethhdr *)(skb->data); - //u8 *da = eh->h_dest; - //u8 is_mcast = ((*da) & 0x01)? 1 : 0; - - if (rwnx_vif == NULL || skb->len <= 14) { - dev_kfree_skb(skb); - return -1; - } + u8 *da = eh->h_dest; + u8 is_mcast = ((*da) & 0x01)? 1 : 0; + #if 0 + struct recv_msdu *pframe; pframe = reord_rxframe_alloc(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue); if (!pframe) { dev_kfree_skb(skb); return -1; } + #endif INIT_LIST_HEAD(&pframe->reord_pending_list); pframe->seq_num = seq_num; pframe->tid = tid; pframe->rx_data = skb->data; - pframe->len = skb->len; + //pframe->len = skb->len; pframe->pkt = skb; - pframe->forward = forward; + pframe->forward = forward; preorder_ctrl = pframe->preorder_ctrl; + pframe->is_amsdu = is_amsdu; -#if 0 - if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast){ - printk("%s AIDEN pframe->seq_num:%d is bcast or mcast\r\n", __func__, pframe->seq_num); - ret = reord_single_frame_ind(rx_priv, pframe); - return ret; - } -#endif + if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast) + return reord_single_frame_ind(rx_priv, pframe); if((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) mac = eh->h_dest; @@ -1775,11 +1955,11 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s if (&reord_info->list == &rx_priv->stas_reord_list) {//first time??? reord_info = reord_init_sta(rx_priv, mac); - //reord_info has 8 preorder_ctrl, - //There is a one-to-one matched preorder_ctrl and tid + //reord_info has 8 preorder_ctrl, + //There is a one-to-one matched preorder_ctrl and tid if (!reord_info) { spin_unlock_bh(&rx_priv->stas_reord_lock); - dev_kfree_skb(skb); + reord_single_frame_ind(rx_priv, pframe); return -1; } list_add_tail(&reord_info->list, &rx_priv->stas_reord_list); @@ -1796,9 +1976,9 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s if (preorder_ctrl->enable == false) { preorder_ctrl->ind_sn = pframe->seq_num; - spin_lock_bh(&preorder_ctrl->reord_list_lock);//AIDEN + spin_lock_bh(&preorder_ctrl->reord_list_lock);//AIDEN reord_single_frame_ind(rx_priv, pframe); - spin_unlock_bh(&preorder_ctrl->reord_list_lock);//AIDEN + spin_unlock_bh(&preorder_ctrl->reord_list_lock);//AIDEN preorder_ctrl->ind_sn = (preorder_ctrl->ind_sn + 1)%4096; return 0; } @@ -1841,11 +2021,7 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s } } else { if(timer_pending(&preorder_ctrl->reord_timer)) { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - ret = timer_delete(&preorder_ctrl->reord_timer); - #else - ret = del_timer(&preorder_ctrl->reord_timer); - #endif + ret = del_timer(&preorder_ctrl->reord_timer); } } @@ -1862,7 +2038,7 @@ fail: dev_kfree_skb(pframe->pkt); pframe->pkt = NULL; } - reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list); + reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &pframe->rxframe_list); return ret; } @@ -1935,14 +2111,94 @@ void remove_sec_hdr_mgmt_frame(struct hw_rxhdr *hw_rxhdr,struct sk_buff *skb) skb_pull(skb,8); memcpy(skb->data,mgmt_header,hdr_len); hw_rxhdr->hwvect.len -= 8; - } - else { + } else { printk("unsupport decr_status:%d\n",hw_rxhdr->hwvect.decr_status); } } } } +void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, + struct sk_buff_head *list) +{ + u16 len_alligned = 0; + u16 sublen = 0; + struct sk_buff *sub_skb = NULL; + struct rwnx_vif *rwnx_vif; + + //if (is_amsdu) + { + //skb_pull(skb, pull_len-8); + /* |amsdu sub1 | amsdu sub2 | ... */ + len_alligned = 0; + sublen = 0; + sub_skb = NULL; + while (skb->len > 16) { + sublen = (skb->data[12]<<8)|(skb->data[13]); + if (skb->len > (sublen+14)) + len_alligned = roundup(sublen + 14, 4); + else if (skb->len == (sublen+14)) + len_alligned = sublen+14; + else { + printk("accroding to amsdu: this will not happen\n"); + break; + } + //printk("sublen = %d, %x, %x, %x, %x\r\n", sublen,skb->data[0], skb->data[1], skb->data[12], skb->data[13]); +#if 1 + sub_skb = __dev_alloc_skb(sublen - 6 + 12, GFP_ATOMIC); + if(!sub_skb){ + printk("sub_skb alloc fail:%d\n", sublen); + break; + } + skb_put(sub_skb, sublen - 6 + 12); + memcpy(sub_skb->data, skb->data, MAC_ADDR_LEN); + memcpy(&sub_skb->data[6], &skb->data[6], MAC_ADDR_LEN); + memcpy(&sub_skb->data[12], &skb->data[14 + 6], sublen - 6); + + rwnx_vif = rwnx_rx_get_vif(rwnx_hw, vif_idx); + if (!rwnx_vif) { + printk("frame received but no active vif (%d), skb->len:%u\n", vif_idx, skb->len); + //dev_kfree_skb(sub_skb); + break; + } + __skb_queue_tail(list, sub_skb); + + //printk("a:%p\n", sub_skb); + //if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, sub_skb, hw_rxhdr)) + // dev_kfree_skb(sub_skb); +#endif + skb_pull(skb, len_alligned); + } + //printk("af:%p\n", skb); + //printk("cnt=%d\n", cnt); + dev_kfree_skb(skb); + //return 0; + } +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) +void defrag_timeout_cb(ulong data) +#else +void defrag_timeout_cb(struct timer_list *t) +#endif +{ + struct defrag_ctrl_info *defrag_ctrl = NULL; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + defrag_ctrl = (struct defrag_ctrl_info *)data; +#else + defrag_ctrl = from_timer(defrag_ctrl, t, defrag_timer); +#endif + + printk("%s:%p\r\n", __func__, defrag_ctrl); + spin_lock_bh(&defrag_ctrl->rwnx_hw->defrag_lock); + list_del_init(&defrag_ctrl->list); + dev_kfree_skb(defrag_ctrl->skb); + kfree(defrag_ctrl); + spin_unlock_bh(&defrag_ctrl->rwnx_hw->defrag_lock); +} + +extern void rwnx_data_dump(char* tag, void* data, unsigned long len); + u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) { struct hw_rxhdr *hw_rxhdr; @@ -1951,19 +2207,26 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) struct sk_buff *skb = hostid; int msdu_offset = sizeof(struct hw_rxhdr) + 2; u16_l status = 0; + struct aicwf_rx_priv *rx_priv_tmp; u8 hdr_len = 24; u8 ra[MAC_ADDR_LEN] = {0}; u8 ta[MAC_ADDR_LEN] = {0}; u8 ether_type[2] = {0}; u8 pull_len = 0; + u16 seq_num = 0; + u8_l frag_num = 0; u8 tid = 0; u8 is_qos = 0; -#ifdef AICWF_RX_REORDER - struct aicwf_rx_priv *rx_priv_tmp; - u16 seq_num = 0; - bool resend = false; - bool forward = false; -#endif + u8 is_frag = 0; + struct defrag_ctrl_info *defrag_info = NULL; + struct defrag_ctrl_info *defrag_info_tmp = NULL; + struct sk_buff *skb_tmp = NULL; + int ret; + u8 sta_idx = 0; + u16_l frame_ctrl; + u8 is_amsdu = 0; + bool resend = false, forward = true; + const struct ethhdr *eth; REG_SW_SET_PROFILING(rwnx_hw, SW_PROF_RWNXDATAIND); hw_rxhdr = (struct hw_rxhdr *)skb->data; @@ -1999,7 +2262,7 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) //Check if monitor interface exists and is open rwnx_vif = rwnx_rx_get_vif(rwnx_hw, rwnx_hw->monitor_vif); if (!rwnx_vif) { - dev_err(rwnx_hw->dev, "Received monitor frame but there is no monitor interface open\n"); + dev_err(rwnx_hw->dev, "Received monitor frame but there is no monitor interface open, skb->len:%u\n", skb->len); goto check_len_update; } @@ -2047,6 +2310,8 @@ u8 rwnx_rxdataind_aicwf(struct rwnx_hw *rwnx_hw, void *hostid, void *rx_priv) #endif } + skb_reset_tail_pointer(skb); + skb->len = 0; skb_reset_tail_pointer(skb_monitor); skb_monitor->len = 0; skb_put(skb_monitor, frm_len); @@ -2098,16 +2363,23 @@ check_len_update: &hw_rxhdr->hwvect.rx_vect1, &hw_rxhdr->hwvect.rx_vect2); skb_pull(skb, msdu_offset + 2); //+2 since sdio allign 58->60 +#define MAC_FCTRL_MOREFRAG 0x0400 + frame_ctrl = (skb->data[1] << 8) | skb->data[0]; + seq_num = ((skb->data[22] & 0xf0) >> 4) | (skb->data[23] << 4); + frag_num = (skb->data[22] & 0x0f); + is_amsdu = 0; - if(skb->data[1] & 0x80)//htc - hdr_len += 4; + if ((skb->data[0] & 0x0f) == 0x08) { + if ((skb->data[0] & 0x80) == 0x80) {//qos data + hdr_len = 26; + tid = skb->data[24] & 0x0F; + is_qos = 1; + if (skb->data[24] & 0x80) + is_amsdu = 1; + } - if((skb->data[0] & 0x0f)==0x08) { - if((skb->data[0] & 0x80) == 0x80) {//qos data - hdr_len += 2;//802.11 mac header len - tid = skb->data[24] & 0x0F; - is_qos = 1; - } + if(skb->data[1] & 0x80)// htc + hdr_len += 4; if((skb->data[1] & 0x3) == 0x1) {// to ds memcpy(ra, &skb->data[16], MAC_ADDR_LEN);//destination addr @@ -2118,41 +2390,185 @@ check_len_update: } pull_len += (hdr_len + 8); -#ifdef AICWF_RX_REORDER - seq_num = ((skb->data[22]&0xf0)>>4) | (skb->data[23]<<4); + + switch (hw_rxhdr->hwvect.decr_status) { + case RWNX_RX_HD_DECR_CCMP128: + pull_len += 8;//ccmp_header + //skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len + memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); + break; + case RWNX_RX_HD_DECR_TKIP: + pull_len += 8;//tkip_header + memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); + break; + case RWNX_RX_HD_DECR_WEP: + pull_len += 4;//wep_header + memcpy(ether_type, &skb->data[hdr_len + 6 + 4], 2); + break; + case RWNX_RX_HD_DECR_WAPI: + pull_len += 18;//wapi_header + memcpy(ether_type, &skb->data[hdr_len + 6 + 18], 2); + break; + + default: + memcpy(ether_type, &skb->data[hdr_len + 6], 2); + break; + } + if(is_amsdu) + hw_rxhdr->flags_is_amsdu = 1; + else + hw_rxhdr->flags_is_amsdu = 0; + + if((ether_type[0] == 0x8e && ether_type[1] == 0x88) || (ether_type[0] == 0x88 && ether_type[1] == 0x8e)) + printk("rx eapol\n"); + if (is_amsdu) { + skb_pull(skb, pull_len-8); + } + + if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) + sta_idx = hw_rxhdr->flags_dst_idx; + + if (!hw_rxhdr->flags_need_reord && ((frame_ctrl & MAC_FCTRL_MOREFRAG) || frag_num)) { + printk("rxfrag:%d,%d,%d,sn=%d,%d\r\n", (frame_ctrl & MAC_FCTRL_MOREFRAG), frag_num, skb->len, seq_num,pull_len); + if (frame_ctrl & MAC_FCTRL_MOREFRAG) { + spin_lock_bh(&rwnx_hw->defrag_lock); + if (!list_empty(&rwnx_hw->defrag_list)) { + list_for_each_entry(defrag_info_tmp, &rwnx_hw->defrag_list, list) { + if ((defrag_info_tmp->sn == seq_num) && (defrag_info_tmp->tid == tid) && \ + defrag_info_tmp->sta_idx == sta_idx) { + defrag_info = defrag_info_tmp; + break; + } + } + } + + //printk("rx frag: sn=%d, fn=%d, skb->len=%d\r\n", seq_num, frag_num, skb->len); + if (defrag_info) { + is_frag = 1; + if (defrag_info->next_fn != frag_num) { + printk("discard:%d:%d\n", defrag_info->next_fn, frag_num); + dev_kfree_skb(skb); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } + + skb_put(defrag_info->skb, skb->len-(pull_len-8)); + memcpy(&defrag_info->skb->data[defrag_info->frm_len], \ + &skb->data[pull_len-8], skb->len - (pull_len-8)); + //printk("middle:%d,%d\n", skb->len-(pull_len-8), skb->len); + defrag_info->frm_len += (skb->len - (pull_len - 8)); + defrag_info->next_fn++; + dev_kfree_skb(skb); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } else { + defrag_info = kzalloc(sizeof(struct defrag_ctrl_info), GFP_KERNEL); + if (defrag_info == NULL) { + printk("no defrag_ctrl_info\r\n"); + dev_kfree_skb(skb); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } + defrag_info->skb = __dev_alloc_skb(2000, GFP_KERNEL); + if (defrag_info->skb == NULL) { + printk("no fragment skb\r\n"); + dev_kfree_skb(skb); + kfree(defrag_info); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } + is_frag = 1; + skb_pull(skb, pull_len); + skb_push(skb, 14); + memcpy(skb->data, ra, MAC_ADDR_LEN); + memcpy(&skb->data[6], ta, MAC_ADDR_LEN); + memcpy(&skb->data[12], ether_type, 2); + defrag_info->sn = seq_num; + defrag_info->next_fn = 1; + defrag_info->tid = tid; + defrag_info->sta_idx = sta_idx; + + skb_put(defrag_info->skb, skb->len); + memcpy(defrag_info->skb->data, skb->data, skb->len); + defrag_info->frm_len = skb->len; + defrag_info->rwnx_hw = rwnx_hw; + //printk("first:%p,%p,%p,%p,%p, %d,%d\r\n", defrag_info, defrag_info->skb, defrag_info->skb->head, defrag_info->skb->tail, defrag_info->skb->end, defrag_info->frm_len, skb->len); + list_add_tail(&defrag_info->list, &rwnx_hw->defrag_list); + spin_unlock_bh(&rwnx_hw->defrag_lock); +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0) + init_timer(&defrag_info->defrag_timer); + defrag_info->defrag_timer.data = (unsigned long)defrag_info; + defrag_info->defrag_timer.function = defrag_timeout_cb; +#else + timer_setup(&defrag_info->defrag_timer, defrag_timeout_cb, 0); #endif - switch(hw_rxhdr->hwvect.decr_status) - { - case RWNX_RX_HD_DECR_CCMP128: - pull_len += 8;//ccmp_header - //skb_pull(&skb->data[skb->len-8], 8); //ccmp_mic_len - memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); - break; - case RWNX_RX_HD_DECR_TKIP: - pull_len += 8;//tkip_header - memcpy(ether_type, &skb->data[hdr_len + 6 + 8], 2); - break; - case RWNX_RX_HD_DECR_WEP: - pull_len += 4;//wep_header - memcpy(ether_type, &skb->data[hdr_len + 6 + 4], 2); - break; - case RWNX_RX_HD_DECR_WAPI: - pull_len += 18;//wapi_header - memcpy(ether_type, &skb->data[hdr_len + 6 + 18], 2); - break; + ret = mod_timer(&defrag_info->defrag_timer, jiffies + msecs_to_jiffies(DEFRAG_MAX_WAIT)); + dev_kfree_skb(skb); + return 0; + } + } else { + //check whether the last fragment + if (!list_empty(&rwnx_hw->defrag_list)) { + spin_lock_bh(&rwnx_hw->defrag_lock); + list_for_each_entry(defrag_info_tmp, &rwnx_hw->defrag_list, list) { + if (((defrag_info_tmp->sn == seq_num) && (defrag_info_tmp->tid == tid) && \ + defrag_info_tmp->sta_idx == sta_idx)) { + defrag_info = defrag_info_tmp; + break; + } + } - default: - memcpy(ether_type, &skb->data[hdr_len + 6], 2); - break; - } + if (!defrag_info) + spin_unlock_bh(&rwnx_hw->defrag_lock); + else { + if (defrag_info->next_fn != frag_num) { + printk("discard:%d:%d\n", defrag_info->next_fn, frag_num); + dev_kfree_skb(skb); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } - skb_pull(skb, pull_len); - skb_push(skb, 14); - //fill 802.3 header - memcpy(skb->data, ra, MAC_ADDR_LEN);//destination addr - memcpy(&skb->data[6], ta, MAC_ADDR_LEN);//source addr - memcpy(&skb->data[12], ether_type, 2);//802.3 type - } + skb_put(defrag_info->skb, skb->len - (pull_len-8)); + memcpy(&defrag_info->skb->data[defrag_info->frm_len], \ + &skb->data[pull_len-8], skb->len - (pull_len-8)); + defrag_info->frm_len += (skb->len - (pull_len-8)); + is_frag = 1; + //printk("last: sn=%d, fn=%d, %d, %d\r\n", seq_num, frag_num, defrag_info->frm_len, skb->len); + + rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); + if (!rwnx_vif) { + printk("Frame received but no active vif (%d)", hw_rxhdr->flags_vif_idx); + dev_kfree_skb(skb); + spin_unlock_bh(&rwnx_hw->defrag_lock); + return 0; + } + dev_kfree_skb(skb); + + skb_tmp = defrag_info->skb; + list_del_init(&defrag_info->list); + if (timer_pending(&defrag_info->defrag_timer)) { + ret = del_timer(&defrag_info->defrag_timer); + } + kfree(defrag_info); + spin_unlock_bh(&rwnx_hw->defrag_lock); + + if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb_tmp, hw_rxhdr)) + dev_kfree_skb(skb_tmp); + + return 0; + } + } + } + } + + if (!is_frag && !is_amsdu) { + skb_pull(skb, pull_len); + skb_push(skb, 14); + memcpy(skb->data, ra, MAC_ADDR_LEN); + memcpy(&skb->data[6], ta, MAC_ADDR_LEN); + memcpy(&skb->data[12], ether_type, 2); + } + } if (hw_rxhdr->flags_is_80211_mpdu) { remove_sec_hdr_mgmt_frame(hw_rxhdr,skb); @@ -2161,8 +2577,8 @@ check_len_update: rwnx_vif = rwnx_rx_get_vif(rwnx_hw, hw_rxhdr->flags_vif_idx); if (!rwnx_vif) { - dev_err(rwnx_hw->dev, "Frame received but no active vif (%d)", - hw_rxhdr->flags_vif_idx); + dev_err(rwnx_hw->dev, "Frame received but no active vif (%d), skb->len:%u\n", + hw_rxhdr->flags_vif_idx, skb->len); dev_kfree_skb(skb); goto end; } @@ -2190,71 +2606,179 @@ check_len_update: skb->priority = 256 + tid;//hw_rxhdr->flags_user_prio; #ifdef AICWF_RX_REORDER - rx_priv_tmp = rx_priv; + rx_priv_tmp = rx_priv; rx_priv_tmp->rwnx_vif = (void *)rwnx_vif; - if( (rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ){ - if(is_qos && hw_rxhdr->flags_need_reord){ - reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1); - }else if(is_qos && !hw_rxhdr->flags_need_reord) { - reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); - if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) - dev_kfree_skb(skb); - } - else { - if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) - dev_kfree_skb(skb); - } - } else if( (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ) { - #if 1 - const struct ethhdr *eth; - resend = false; - forward = true; - skb_reset_mac_header(skb); - eth = eth_hdr(skb); - //printk("da:%pM, %x,%x, len=%d\n", eth->h_dest, skb->data[12], skb->data[13], skb->len); - - if (unlikely(is_multicast_ether_addr(eth->h_dest))) { - /* broadcast pkt need to be forwared to upper layer and resent - on wireless interface */ - resend = true; + if( (rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ){ + if(is_qos && hw_rxhdr->flags_need_reord){ + struct recv_msdu *pframe; + pframe = reord_rxframe_alloc(&rx_priv_tmp->freeq_lock, &rx_priv_tmp->rxframes_freequeue); + if (!pframe) { + printk("no pframe\n"); + dev_kfree_skb(skb); + return -1; + } + pframe->is_ap_reord = 0; + pframe->ap_fwd_cnt = 0; + pframe->ap_resend_cnt = 0; + reord_process_unit(pframe, (struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1, hw_rxhdr->flags_is_amsdu); + } else if (is_qos && !hw_rxhdr->flags_need_reord) { + reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); + if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu) + dev_kfree_skb(skb); } else { - /* unicast pkt for STA inside the BSS, no need to forward to upper - layer simply resend on wireless interface */ - if (hw_rxhdr->flags_dst_idx != RWNX_INVALID_STA) { - struct rwnx_sta *sta = &rwnx_hw->sta_table[hw_rxhdr->flags_dst_idx]; - if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) { - resend = true; - forward = false; - } - } + if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr) && !hw_rxhdr->flags_is_amsdu) + dev_kfree_skb(skb); } + } else if( (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ) { +#ifdef CONFIG_DYNAMIC_PERPWR + struct rwnx_sta *sta; +#endif + struct sk_buff_head list; + struct sk_buff *rx_skb; + +#ifdef CONFIG_DYNAMIC_PERPWR + sta = &rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx]; + rssi_update_txpwrloss(sta, hw_rxhdr->hwvect.rx_vect1.rssi1); +#endif +#ifdef CONFIG_BAND_STEERING + (&rwnx_hw->sta_table[hw_rxhdr->flags_sta_idx])->rssi = hw_rxhdr->hwvect.rx_vect1.rssi1; +#endif + u8 flags_dst_idx = hw_rxhdr->flags_dst_idx; + u8 flags_need_reord = hw_rxhdr->flags_need_reord; + u8 flags_vif_idx = hw_rxhdr->flags_vif_idx; + u8 flags_is_amsdu = hw_rxhdr->flags_is_amsdu; + //u8 reord_cnt = 0; + struct recv_msdu *pframe = NULL; + + __skb_queue_head_init(&list); + + //printk("dst_idx=%d, len=%d\n", flags_dst_idx, skb->len); + if (flags_is_amsdu) { + rwnx_rxdata_process_amsdu(rwnx_hw, skb, flags_vif_idx, &list); //rxhdr not used below since skb free! + } else { + rwnx_hw->stats.amsdus_rx[0]++; + __skb_queue_head(&list, skb); + } + + while (!skb_queue_empty(&list)) { + rx_skb = __skb_dequeue(&list); + + skb_reset_mac_header(rx_skb); + eth = eth_hdr(rx_skb); + //printk("da:%pM, %x,%x, len=%d\n", eth->h_dest, skb->data[12], skb->data[13], skb->len); + + resend = false; + forward = true; + if (unlikely(is_multicast_ether_addr(eth->h_dest))) { + /* broadcast pkt need to be forwared to upper layer and resent + on wireless interface */ + resend = true; + } else { + /* unicast pkt for STA inside the BSS, no need to forward to upper + layer simply resend on wireless interface */ + if ((flags_dst_idx != RWNX_INVALID_STA) && !flags_is_amsdu) { + struct rwnx_sta *sta = &rwnx_hw->sta_table[flags_dst_idx]; + if (sta->valid && (sta->vlan_idx == rwnx_vif->vif_index)) { + resend = true; + forward = false; + } + } else { + struct rwnx_sta *cur, *tmp; + bool found = false; + spin_lock_bh(&rwnx_hw->cb_lock); + list_for_each_entry_safe(cur, tmp, &rwnx_vif->ap.sta_list, list) { + if (!memcmp(cur->mac_addr, eth->h_dest, ETH_ALEN)) { + found = true; + break; + } + } + spin_unlock_bh(&rwnx_hw->cb_lock); + if(found) { + //printk("amsdu found da\n"); + resend = true; + forward = false; + } + } + } if(resend){ - rwnx_rx_data_skb_resend(rwnx_hw, rwnx_vif, skb, hw_rxhdr); + rwnx_rx_data_skb_resend(rwnx_hw, rwnx_vif, rx_skb); } if(forward) { - if (is_qos && hw_rxhdr->flags_need_reord) - reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 1); - else if (is_qos && !hw_rxhdr->flags_need_reord) { - reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); - rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr); + if (is_qos && flags_need_reord) { + if(pframe == NULL) { + pframe = reord_rxframe_alloc(&rx_priv_tmp->freeq_lock, &rx_priv_tmp->rxframes_freequeue); + if (!pframe) { + dev_kfree_skb(rx_skb); + return -1; + } + rx_skb->next = NULL; + pframe->ap_fwd_cnt = 1; + pframe->ap_resend_cnt = 0; + pframe->first_fwd_skb = rx_skb; + pframe->last_fwd_skb = rx_skb; + pframe->first_resend_skb = NULL; + pframe->last_resend_skb = NULL; + } else { + rx_skb->next = NULL; + pframe->ap_fwd_cnt++; + if(pframe->first_fwd_skb == NULL) { + pframe->first_fwd_skb = rx_skb; + pframe->last_fwd_skb = rx_skb; + } else { + pframe->last_fwd_skb->next = rx_skb; + pframe->last_fwd_skb = rx_skb; + } + } + } else if (is_qos && !flags_need_reord) { + reord_flush_tid((struct aicwf_rx_priv *)rx_priv, rx_skb, tid); + rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, rx_skb); } else - rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, skb, hw_rxhdr); + rwnx_rx_data_skb_forward(rwnx_hw, rwnx_vif, rx_skb); } else if(resend) { - if (is_qos && hw_rxhdr->flags_need_reord) - reord_process_unit((struct aicwf_rx_priv *)rx_priv, skb, seq_num, tid, 0); - else if (is_qos && !hw_rxhdr->flags_need_reord) { - reord_flush_tid((struct aicwf_rx_priv *)rx_priv, skb, tid); - dev_kfree_skb(skb); - } + if (is_qos && flags_need_reord) { + if(pframe == NULL) { + pframe = reord_rxframe_alloc(&rx_priv_tmp->freeq_lock, &rx_priv_tmp->rxframes_freequeue); + if (!pframe) { + dev_kfree_skb(rx_skb); + return -1; + } + rx_skb->next = NULL; + pframe->ap_fwd_cnt = 0; + pframe->ap_resend_cnt = 1; + pframe->first_fwd_skb = NULL; + pframe->last_fwd_skb = NULL; + pframe->first_resend_skb = rx_skb; + pframe->last_resend_skb = rx_skb; + } else { + rx_skb->next = NULL; + pframe->ap_resend_cnt++; + if(pframe->first_resend_skb == NULL) { + pframe->first_resend_skb = rx_skb; + pframe->last_resend_skb = rx_skb; + } else { + pframe->last_resend_skb->next = rx_skb; + pframe->last_resend_skb = rx_skb; + } + } + } + else if (is_qos && !flags_need_reord) { + if(!reord_flush_tid((struct aicwf_rx_priv *)rx_priv, rx_skb, tid)) + dev_kfree_skb(rx_skb); + } else { + dev_kfree_skb(rx_skb); + } } else - dev_kfree_skb(skb); - #else - if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) - dev_kfree_skb(skb); - #endif + dev_kfree_skb(rx_skb); + } + + if(pframe != NULL) { + pframe->is_ap_reord = 1; + //printk("reord:%d,%d\n", pframe->ap_fwd_cnt, pframe->ap_resend_cnt); + reord_process_unit(pframe, (struct aicwf_rx_priv *)rx_priv, rx_skb, seq_num, tid, 0, 0); + } } #else if (!rwnx_rx_data_skb(rwnx_hw, rwnx_vif, skb, hw_rxhdr)) diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h index e5480cd..e7e71f6 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_rx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_rx.h @@ -326,8 +326,12 @@ struct hw_rxhdr { u32 pattern; }; -extern const u8 legrates_lut[]; -extern u16 legrates_lut_rate[]; +struct rwnx_legrate { + int idx; + int rate; +}; + +extern struct rwnx_legrate legrates_lut[]; extern u16 tx_legrates_lut_rate[]; struct DHCPInfo { @@ -376,6 +380,8 @@ void reord_timeout_handler (struct timer_list *t); #endif #endif +void rwnx_rxdata_process_amsdu(struct rwnx_hw *rwnx_hw, struct sk_buff *skb, u8 vif_idx, + struct sk_buff_head *list); #ifdef CONFIG_HE_FOR_OLD_KERNEL #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 197) diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_strs.c b/drivers/aic8800/aic8800_fdrv/rwnx_strs.c index 1e52871..105301d 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_strs.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_strs.c @@ -135,6 +135,8 @@ static const char *const rwnx_mmid2str[MSG_I(MM_MAX)] = { [MSG_I(MM_GET_WIFI_DISABLE_REQ)] = "MM_GET_WIFI_DISABLE_REQ", [MSG_I(MM_GET_WIFI_DISABLE_CFM)] = "MM_GET_WIFI_DISABLE_CFM", [MSG_I(MM_CFG_RSSI_CFM)] = "MM_CFG_RSSI_CFM", + [MSG_I(MM_SET_TXPWR_PER_STA_REQ)] = "MM_SET_TXPWR_PER_STA_REQ", + [MSG_I(MM_SET_TXPWR_PER_STA_CFM)] = "MM_SET_TXPWR_PER_STA_CFM", }; static const char *const rwnx_dbgid2str[MSG_I(DBG_MAX)] = { diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c index 0d66786..ae44319 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.c +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.c @@ -18,6 +18,7 @@ #include "rwnx_events.h" #include "rwnx_compat.h" #include "aicwf_txrxif.h" +#include "rwnx_main.h" #ifdef CONFIG_RWNX_MON_XMIT #include #endif @@ -107,7 +108,7 @@ void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, spin_unlock_bh(&rwnx_hw->tx_lock); //if (sta->ps.pkt_ready[LEGACY_PS_ID]) - // rwnx_set_traffic_status(rwnx_hw, sta, true, LEGACY_PS_ID); + //rwnx_set_traffic_status(rwnx_hw, sta, true, LEGACY_PS_ID); //if (sta->ps.pkt_ready[UAPSD_ID]) // rwnx_set_traffic_status(rwnx_hw, sta, true, UAPSD_ID); @@ -132,8 +133,8 @@ void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta, rwnx_txq_sta_start(sta, RWNX_TXQ_STOP_STA_PS, rwnx_hw); spin_unlock_bh(&rwnx_hw->tx_lock); - //if (sta->ps.pkt_ready[LEGACY_PS_ID]) - // rwnx_set_traffic_status(rwnx_hw, sta, false, LEGACY_PS_ID); + if (sta->ps.pkt_ready[LEGACY_PS_ID]) + rwnx_set_traffic_status(rwnx_hw, sta, false, LEGACY_PS_ID); //if (sta->ps.pkt_ready[UAPSD_ID]) // rwnx_set_traffic_status(rwnx_hw, sta, false, UAPSD_ID); @@ -1466,6 +1467,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->priority = 0; #ifdef CONFIG_FILTER_TCP_ACK + if(cpu_to_le16(skb->len) <= MAX_TCP_ACK){ msgbuf=intf_tcp_alloc_msg(msgbuf); msgbuf->rwnx_vif=rwnx_vif; msgbuf->skb=skb; @@ -1475,6 +1477,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev) move_tcpack_msg(rwnx_hw,msgbuf); kfree(msgbuf); } + } #endif memcpy(ð_t, skb->data, sizeof(struct ethhdr)); @@ -1830,6 +1833,141 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta, return 0; } +#ifdef CONFIG_BAND_STEERING +void rwnx_probersp_work(struct work_struct *work) +{ + struct ap_probe_rsp *rsp = container_of(work, struct ap_probe_rsp, rsp_work); + struct rwnx_vif *rwnx_vif = container_of(rsp, struct rwnx_vif, pb_pool[0]); + struct rwnx_hw *rwnx_hw = rwnx_vif->rwnx_hw; + struct sk_buff *skb = NULL; + struct rwnx_bcn *bcn = &rwnx_vif->ap.bcn; + unsigned int len = bcn->len; + u8_l *buf; + struct ieee80211_mgmt *mgmt; + bool robust; + u16_l headroom, frame_len; + struct rwnx_sta *sta = NULL; + struct rwnx_txq *txq; + struct rwnx_txhdr *txhdr; + struct rwnx_sw_txhdr *sw_txhdr; + struct txdesc_api *desc; + headroom = sizeof(struct rwnx_txhdr); + frame_len = len; + + if (aicwf_band_steering_block_chk(rwnx_vif, rsp->da)) { + AICWFDBG(LOGSTEER, "usb %s, %d, probe_rsp refuse temp %pM\n", __func__, rwnx_vif->ap.freq, rsp->da); + goto free_use; + } + if (!bcn->head || bcn->head_len == 0 || bcn->head_len > frame_len) { + AICWFDBG(LOGSTEER, "%s bcn head NULL\n", __func__); + goto free_use; + } + + skb = dev_alloc_skb(frame_len + headroom); + if (!skb) { + AICWFDBG(LOGERROR, "%s alloc skb fail\n", __func__); + goto free_use; + } + + skb_reserve(skb, headroom); + buf = skb_put(skb, frame_len); + + memcpy(buf, bcn->head, bcn->head_len); + buf += bcn->head_len; + *buf++ = WLAN_EID_TIM; + *buf++ = 4; + *buf++ = 0; + *buf++ = bcn->dtim; + *buf++ = 0; + *buf++ = 0; + if (bcn->tail) { + memcpy(buf, bcn->tail, bcn->tail_len); + buf += bcn->tail_len; + } + if (bcn->ies) + memcpy(buf, bcn->ies, bcn->ies_len); + + mgmt = (struct ieee80211_mgmt *)skb->data; + mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); + memcpy (mgmt->da, rsp->da, ETH_ALEN); + rsp->in_use = false; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + robust = ieee80211_is_robust_mgmt_frame(skb); +#else + if (skb->len < 25) + robust = false; + robust = ieee80211_is_robust_mgmt_frame((void *)skb->data); +#endif + + sta = rwnx_retrieve_sta(rwnx_hw, rwnx_vif, mgmt->da, mgmt->frame_control, true); + if (sta) { + txq = rwnx_txq_sta_get(sta, 8, rwnx_hw); + } else { + txq = rwnx_txq_vif_get(rwnx_vif, NX_UNK_TXQ_TYPE); + } + if (txq->idx == TXQ_INACTIVE) { + AICWFDBG(LOGERROR, "%s TXQ inactive\n", __func__); + goto fail; + } + + skb_push(skb, headroom); + txhdr = (struct rwnx_txhdr *)skb->data; + txhdr->hw_hdr.cfm.status.value = 0; + sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC); + if (unlikely(sw_txhdr == NULL)) { + AICWFDBG(LOGERROR, "%s cache fail\n", __func__); + goto fail; + } + txhdr->sw_hdr = sw_txhdr; + sw_txhdr->txq = txq; + sw_txhdr->frame_len = frame_len; + sw_txhdr->rwnx_sta = sta; + sw_txhdr->rwnx_vif = rwnx_vif; + sw_txhdr->skb = skb; + sw_txhdr->headroom = headroom; + sw_txhdr->map_len = skb->len - offsetof(struct rwnx_txhdr, hw_hdr); +#ifdef CONFIG_RWNX_AMSDUS_TX + sw_txhdr->amsdu.len = 0; + sw_txhdr->amsdu.nb = 0; +#endif + sw_txhdr->raw_frame = 0; + sw_txhdr->fixed_rate = 0; + + desc = &sw_txhdr->desc; + desc->host.ethertype = 0; + desc->host.staid = (sta) ? sta->sta_idx : 0xFF; + desc->host.vif_idx = rwnx_vif->vif_index; + desc->host.tid = 0xFF; + desc->host.flags = TXU_CNTRL_MGMT; + if (robust) + desc->host.flags |= TXU_CNTRL_MGMT_ROBUST; +#ifdef CONFIG_RWNX_SPLIT_TX_BUF + desc->host.packet_len[0] = frame_len; +#else + desc->host.packet_len = frame_len; +#endif + desc->host.status_desc_addr = sw_txhdr->dma_addr; + + spin_lock_bh(&rwnx_hw->tx_lock); + AICWFDBG(LOGSTEER, "usb p_rsp: %pM", mgmt->da); + // AICWFDBG(LOGDEBUG, "usb %s sta:%p skb:%p desc->host.staid:%d \r\n", __func__, sta, skb, desc->host.staid); + if (rwnx_txq_queue_skb(skb, txq, rwnx_hw, false)) + rwnx_hwq_process(rwnx_hw, txq->hwq); + spin_unlock_bh(&rwnx_hw->tx_lock); + + return; + +fail: + if (sw_txhdr) + kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr); + dev_kfree_skb(skb); +free_use: + if (rsp->in_use) + rsp->in_use = false; +} +#endif + #ifdef CONFIG_RWNX_MON_XMIT /** * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb, @@ -1876,11 +2014,11 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d int nx_off_chan_txq_idx = NX_OFF_CHAN_TXQ_IDX; rtap_hdr = (struct ieee80211_radiotap_header*)(rtap_buf); - rtap_len = ieee80211_get_radiotap_len(rtap_buf); + rtap_len = ieee80211_get_radiotap_len(rtap_buf);//max_length frame_len = skb->len; - printk("rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len); - + AICWFDBG(LOGINFO, "rwnx_start_monitor_if_xmit, skb_len=%d, rtap_len=%d\n", skb->len, rtap_len); +//rwnx_data_dump((char*)__func__, skb->data, skb->len); if((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8801) || ((g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DC || g_rwnx_plat->usbdev->chipid == PRODUCT_ID_AIC8800DW) && chip_id < 3)){ @@ -1888,14 +2026,20 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d } - if (unlikely(rtap_hdr->it_version)) + if (unlikely(rtap_hdr->it_version)){ + AICWFDBG(LOGERROR, "%s itv \r\n", __func__); goto free_tag; + } - if (unlikely(skb->len < rtap_len)) + if (unlikely(skb->len < rtap_len)){ + AICWFDBG(LOGERROR, "%s skb->len < rtap_len \r\n", __func__); goto free_tag; + } - if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))) + if (unlikely(rtap_len < sizeof(struct ieee80211_radiotap_header))){ + AICWFDBG(LOGERROR, "%s rtap_len < sizeof(struct ieee80211_radiotap_header) \r\n", __func__); goto free_tag; + } frame_len -= rtap_len; pframe = rtap_buf + rtap_len; @@ -1907,39 +2051,44 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d if (ret) { continue; } + AICWFDBG(LOGDEBUG, "%s iterator.this_arg_index:%d iterator.this_arg:%x\r\n", __func__, + iterator.this_arg_index, *iterator.this_arg); switch (iterator.this_arg_index) { case IEEE80211_RADIOTAP_RATE: // This is basic 802.11b/g rate; use MCS/VHT for higher rates rate = *iterator.this_arg; - printk("rate=0x%x\n", rate); + AICWFDBG(LOGDEBUG, "rate=0x%x\n", rate); for (idx = 0; idx < HW_RATE_MAX; idx++) { if ((rate * 5) == tx_legrates_lut_rate[idx]) { + AICWFDBG(LOGDEBUG, "%s datarate:%d \r\n", __func__, tx_legrates_lut_rate[idx]); break; } } + if (idx < HW_RATE_MAX) { rate_idx = idx; + AICWFDBG(LOGDEBUG, "rate_idx = %d \r\n", rate_idx); } else { - printk("invalid radiotap rate: %d\n", rate); + AICWFDBG(LOGERROR, "invalid radiotap rate: %d\n", rate); } break; case IEEE80211_RADIOTAP_TX_FLAGS: { u16_l txflags = get_unaligned_le16(iterator.this_arg); - printk("txflags=0x%x\n", txflags); + AICWFDBG(LOGDEBUG, "txflags=0x%x\n", txflags); if ((txflags & IEEE80211_RADIOTAP_F_TX_NOACK) == 0) { - printk(" TX_NOACK\n"); + AICWFDBG(LOGDEBUG, " TX_NOACK\n"); } if (txflags & 0x0010) { // Use preconfigured seq num // NOTE: this is currently ignored due to qos_en=_FALSE and HW seq num override - printk(" GetSequence\n"); + AICWFDBG(LOGDEBUG, " GetSequence\n"); } } break; case IEEE80211_RADIOTAP_MCS: { u8_l mcs_have = iterator.this_arg[0]; - printk("mcs_have=0x%x\n", mcs_have); + AICWFDBG(LOGDEBUG, "mcs_have=0x%x\n", mcs_have); rate_fmt = FORMATMOD_HT_MF; if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_BW) { u8_l bw = (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_BW_MASK); @@ -1953,7 +2102,7 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d bw = IEEE80211_RADIOTAP_MCS_BW_20; ch_offset = 2; // CHNL_OFFSET_UPPER; } - printk(" bw=%d, ch_offset=%d\n", bw, ch_offset); + AICWFDBG(LOGDEBUG, " bw=%d, ch_offset=%d\n", bw, ch_offset); } if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_MCS) { u8_l fixed_rate = iterator.this_arg[2] & 0x7f; @@ -1961,17 +2110,17 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d fixed_rate = 0; } rate_idx = fixed_rate; - printk(" fixed_rate=0x%x\n", fixed_rate); + AICWFDBG(LOGDEBUG, " fixed_rate=0x%x\n", fixed_rate); } if ((mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_GI) && (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_SGI)) { - printk(" sgi\n"); + AICWFDBG(LOGDEBUG, " sgi\n"); } if ((mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_FEC) && (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_FEC_LDPC)) { - printk(" ldpc\n"); + AICWFDBG(LOGDEBUG, " ldpc\n"); } if (mcs_have & IEEE80211_RADIOTAP_MCS_HAVE_STBC) { u8 stbc = (iterator.this_arg[1] & IEEE80211_RADIOTAP_MCS_STBC_MASK) >> IEEE80211_RADIOTAP_MCS_STBC_SHIFT; - printk(" stbc=0x%x\n", stbc); + AICWFDBG(LOGDEBUG, " stbc=0x%x\n", stbc); } } break; @@ -1981,17 +2130,17 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d u8 known = iterator.this_arg[0]; u8 flags = iterator.this_arg[2]; rate_fmt = FORMATMOD_VHT; - printk("known=0x%x, flags=0x%x\n", known, flags); + AICWFDBG(LOGDEBUG, "known=0x%x, flags=0x%x\n", known, flags); // NOTE: this code currently only supports 1SS for radiotap defined rates if ((known & IEEE80211_RADIOTAP_VHT_KNOWN_STBC) && (flags & IEEE80211_RADIOTAP_VHT_FLAG_STBC)) { - printk(" stbc\n"); + AICWFDBG(LOGDEBUG, " stbc\n"); } if ((known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) && (flags & IEEE80211_RADIOTAP_VHT_FLAG_SGI)) { - printk(" sgi\n"); + AICWFDBG(LOGDEBUG, " sgi\n"); } if (known & IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) { u8_l bw = iterator.this_arg[3] & 0x1F; - printk(" bw=0x%x\n",bw); + AICWFDBG(LOGDEBUG, " bw=0x%x\n",bw); // NOTE: there are various L and U, but we just use straight 20/40/80 // since it's not clear how to set CHNL_OFFSET_LOWER/_UPPER with different // sideband sizes/configurations. TODO. @@ -1999,26 +2148,26 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d txsig_bw = PHY_CHNL_BW_40; if (bw == 0) { txsig_bw = PHY_CHNL_BW_20; - printk(" 20M\n"); + AICWFDBG(LOGDEBUG, " 20M\n"); } else if (bw >=1 && bw <= 3) { - printk(" 40M\n"); + AICWFDBG(LOGDEBUG, " 40M\n"); } else if (bw >=4 && bw <= 10) { - printk(" 80M\n"); + AICWFDBG(LOGDEBUG, " 80M\n"); } else if (bw >= 11 && bw <= 25) { - printk(" 160M\n"); + AICWFDBG(LOGDEBUG, " 160M\n"); } } // User 0 nss = iterator.this_arg[4] & 0x0F; // Number of spatial streams - printk(" nss=0x%x\n", nss); + AICWFDBG(LOGINFO, " nss=0x%x\n", nss); if (nss > 0) { if (nss > 4) nss = 4; mcs = (iterator.this_arg[4]>>4) & 0x0F; // MCS rate index if (mcs > 8) mcs = 9; rate_idx = mcs; - printk(" mcs=0x%x\n", mcs); + AICWFDBG(LOGDEBUG, " mcs=0x%x\n", mcs); if (iterator.this_arg[8] & IEEE80211_RADIOTAP_CODING_LDPC_USER0) { - printk(" ldpc\n"); + AICWFDBG(LOGDEBUG, " ldpc\n"); } } } @@ -2048,13 +2197,13 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d } if (data2 & IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN) { u8 gi = (data5 & IEEE80211_RADIOTAP_HE_DATA5_GI) >> 4; - printk(" gi: %d\n", gi); + AICWFDBG(LOGDEBUG, " gi: %d\n", gi); } } break; default: - printk("unparsed arg: 0x%x\n",iterator.this_arg_index); + AICWFDBG(LOGERROR, "unparsed arg: 0x%x\n",iterator.this_arg_index); break; } } @@ -2089,14 +2238,14 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d txq = rwnx_txq_vif_get(vif, NX_UNK_TXQ_TYPE); } if (txq->idx == TXQ_INACTIVE) { - printk("TXQ_INACTIVE\n"); + AICWFDBG(LOGERROR, "TXQ_INACTIVE\n"); goto free_tag; } // prepare to xmit headroom = sizeof(struct rwnx_txhdr); skb_mgmt = dev_alloc_skb(headroom + frame_len); if (!skb_mgmt) { - printk("skb_mgmt alloc fail\n"); + AICWFDBG(LOGERROR, "skb_mgmt alloc fail\n"); goto free_tag; } skb_reserve(skb_mgmt, headroom); @@ -2118,7 +2267,7 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d sw_txhdr = kmem_cache_alloc(rwnx_hw->sw_txhdr_cache, GFP_ATOMIC); if (unlikely(sw_txhdr == NULL)) { dev_kfree_skb(skb_mgmt); - printk("sw_txhdr alloc fail\n"); + AICWFDBG(LOGERROR, "sw_txhdr alloc fail\n"); goto free_tag; } txhdr->sw_hdr = sw_txhdr; @@ -2160,6 +2309,7 @@ netdev_tx_t rwnx_start_monitor_if_xmit(struct sk_buff *skb, struct net_device *d desc->host.status_desc_addr = sw_txhdr->dma_addr; spin_lock_bh(&rwnx_hw->tx_lock); + AICWFDBG(LOGTRACE, "%s send data\r\n", __func__); if (rwnx_txq_queue_skb(skb_mgmt, txq, rwnx_hw, false)) rwnx_hwq_process(rwnx_hw, txq->hwq); spin_unlock_bh(&rwnx_hw->tx_lock); diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h index da4511d..eb64c77 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_tx.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_tx.h @@ -194,5 +194,9 @@ int rwnx_dbgfs_print_sta(char *buf, size_t size, struct rwnx_sta *sta, void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid, s8 update); void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags); +#ifdef CONFIG_BAND_STEERING +void rwnx_probersp_work(struct work_struct *work); +#endif + #endif /* _RWNX_TX_H_ */ diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h b/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h index 6de34a9..705c56e 100644 --- a/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h +++ b/drivers/aic8800/aic8800_fdrv/rwnx_version_gen.h @@ -1,5 +1,5 @@ #define RWNX_VERS_REV "1a4b0054d2M (master)" #define RWNX_VERS_MOD "6.4.3.0" #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)" -#define RELEASE_DATE "2024_0420_24c7777c" +#define RELEASE_DATE "2025_0423_71b66e7b" diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c new file mode 100644 index 0000000..90e7ad8 --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.c @@ -0,0 +1,92 @@ +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +#include +#else +#include +#endif +#include "rwnx_defs.h" +#include "rwnx_wakelock.h" + +struct wakeup_source *rwnx_wakeup_init(const char *name) +{ + struct wakeup_source *ws; + ws = wakeup_source_create(name); + wakeup_source_add(ws); + return ws; +} + +void rwnx_wakeup_deinit(struct wakeup_source *ws) +{ + if (ws && ws->active) + __pm_relax(ws); + wakeup_source_remove(ws); + wakeup_source_destroy(ws); +} + +struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name) +{ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) + return wakeup_source_register(dev, name); +#else + +#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0) + return wakeup_source_register(dev, name); +#else + return wakeup_source_register(name); +#endif + +#else + return wakeup_source_register(name); +#endif//#if defined(CONFIG_PLATFORM_ROCKCHIP2) || defined(CONFIG_PLATFORM_ROCKCHIP) + +#endif//LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) +} + +void rwnx_wakeup_unregister(struct wakeup_source *ws) +{ + if (ws && ws->active) + __pm_relax(ws); + wakeup_source_unregister(ws); +} + +void rwnx_wakeup_lock(struct wakeup_source *ws) +{ + AICWFDBG(LOGDEBUG, "%s enter \r\n", __func__); + __pm_stay_awake(ws); +} + +void rwnx_wakeup_unlock(struct wakeup_source *ws) +{ + AICWFDBG(LOGDEBUG, "%s enter \r\n", __func__); + __pm_relax(ws); +} + +void rwnx_wakeup_lock_timeout(struct wakeup_source *ws, unsigned int msec) +{ + __pm_wakeup_event(ws, msec); +} + +void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw) +{ + rwnx_hw->ws_tx = rwnx_wakeup_init("rwnx_tx_wakelock"); + rwnx_hw->ws_rx = rwnx_wakeup_init("rwnx_rx_wakelock"); + rwnx_hw->ws_irqrx = rwnx_wakeup_init("rwnx_irqrx_wakelock"); + rwnx_hw->ws_pwrctrl = rwnx_wakeup_init("rwnx_pwrcrl_wakelock"); +} + +void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw) +{ + rwnx_wakeup_deinit(rwnx_hw->ws_tx); + rwnx_wakeup_deinit(rwnx_hw->ws_rx); + rwnx_wakeup_deinit(rwnx_hw->ws_irqrx); + rwnx_wakeup_deinit(rwnx_hw->ws_pwrctrl); + rwnx_hw->ws_tx = NULL; + rwnx_hw->ws_rx = NULL; + rwnx_hw->ws_irqrx = NULL; + rwnx_hw->ws_pwrctrl = NULL; +} + diff --git a/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.h b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.h new file mode 100644 index 0000000..9c9655a --- /dev/null +++ b/drivers/aic8800/aic8800_fdrv/rwnx_wakelock.h @@ -0,0 +1,21 @@ +#ifndef __RWNX_WAKELOCK_H +#define __RWNX_WAKELOCK_H + +#include +#include +#include + +struct wakeup_source *rwnx_wakeup_init(const char *name); +void rwnx_wakeup_deinit(struct wakeup_source *ws); + +struct wakeup_source *rwnx_wakeup_register(struct device *dev, const char *name); +void rwnx_wakeup_unregister(struct wakeup_source *ws); + +void rwnx_wakeup_lock(struct wakeup_source *ws); +void rwnx_wakeup_unlock(struct wakeup_source *ws); +void rwnx_wakeup_lock_timeout(struct wakeup_source *ws, unsigned int msec); + +void aicwf_wakeup_lock_init(struct rwnx_hw *rwnx_hw); +void aicwf_wakeup_lock_deinit(struct rwnx_hw *rwnx_hw); + +#endif diff --git a/drivers/aic8800/aic_load_fw/.gitignore b/drivers/aic8800/aic_load_fw/.gitignore new file mode 100644 index 0000000..6ebacd5 --- /dev/null +++ b/drivers/aic8800/aic_load_fw/.gitignore @@ -0,0 +1,11 @@ +*.o +*.ko +*.order +*.symvers +*.o.d +*.o.cmd +*.ko.cmd +*.mod +*.mod.c* + +.tmp_versions/ diff --git a/drivers/aic8800/aic_load_fw/Makefile b/drivers/aic8800/aic_load_fw/Makefile index 9c87ab3..3479e82 100644 --- a/drivers/aic8800/aic_load_fw/Makefile +++ b/drivers/aic8800/aic_load_fw/Makefile @@ -7,11 +7,14 @@ CONFIG_M2D_OTA_AUTO_SUPPORT = n CONFIG_LINK_DET_5G = y CONFIG_FOR_IPCAM = n CONFIG_USB_SUSPEND_REBOOT_TIME = n +CONFIG_SUPPORT_USB_SUSP = n +CONFIG_RADAR_OR_IR_DETECT =n # Need to set fw path in BOARD_KERNEL_CMDLINE CONFIG_USE_FW_REQUEST ?= n CONFIG_PREALLOC_RX_SKB ?= n CONFIG_PREALLOC_TXQ ?= y +CONFIG_BAND_STEERING = n # Platform support list CONFIG_PLATFORM_ROCKCHIP ?= n @@ -39,7 +42,9 @@ ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST ccflags-$(CONFIG_PREALLOC_RX_SKB) += -DCONFIG_PREALLOC_RX_SKB ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ ccflags-$(CONFIG_USB_SUSPEND_REBOOT_TIME) += -DCONFIG_USB_SUSPEND_REBOOT_TIME - +ccflags-$(CONFIG_SUPPORT_USB_SUSP) += -DCONFIG_SUPPORT_USB_SUSP +ccflags-$(CONFIG_RADAR_OR_IR_DETECT) += -DCONFIG_RADAR_OR_IR_DETECT +ccflags-$(CONFIG_BAND_STEERING) += -DCONFIG_BAND_STEERING obj-$(CONFIG_AIC_LOADFW_SUPPORT) := $(MODULE_NAME).o $(MODULE_NAME)-y := aic_bluetooth_main.o \ @@ -48,6 +53,7 @@ $(MODULE_NAME)-y := aic_bluetooth_main.o \ aic_txrxif.o \ aicbluetooth_cmds.o \ aic_compat_8800d80.o \ + aic_compat_8800d80x2.o \ md5.o $(MODULE_NAME)-$(CONFIG_PREALLOC_RX_SKB) += aicwf_rx_prealloc.o diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c index 2d1f272..1a9c43e 100644 --- a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.c @@ -17,7 +17,7 @@ void rwnx_release_firmware_common(u32** buffer); extern int testmode; extern u8 chip_id; -u8 chip_mcu_id = 0; +extern u8 chip_mcu_id; typedef u32 (*array2_tbl_t)[2]; @@ -39,13 +39,26 @@ typedef struct { #define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem) #define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem))) +#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) #define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) #define USER_TX_USE_ANA_F_FLAG (0x01U << 2) +#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) +#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) +#define CFG_PWROFST_COVER_CALIB 1 +#ifdef CONFIG_POWER_LIMIT +#define CFG_USER_CHAN_MAX_TXPWR_EN 1 +#else #define CFG_USER_CHAN_MAX_TXPWR_EN 0 +#endif #define CFG_USER_TX_USE_ANA_F 0 +#ifdef CONFIG_BAND_STEERING +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1 +#else +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 +#endif -#define CFG_USER_EXT_FLAGS_EN (CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F) +#define CFG_USER_EXT_FLAGS_EN (CFG_PWROFST_COVER_CALIB || CFG_USER_CHAN_MAX_TXPWR_EN || CFG_USER_TX_USE_ANA_F|| CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE) u32 patch_tbl_d80[][2] = { @@ -60,16 +73,26 @@ u32 patch_tbl_d80[][2] = {0x0170, 0x0001000A},//rx aggr counter #endif - #if CFG_USER_EXT_FLAGS_EN - {0x0188, 0x00000001 - #if CFG_USER_CHAN_MAX_TXPWR_EN - | USER_CHAN_MAX_TXPWR_EN_FLAG - #endif - #if CFG_USER_TX_USE_ANA_F - | USER_TX_USE_ANA_F_FLAG - #endif - }, // user_ext_flags - #endif +#if CFG_USER_EXT_FLAGS_EN + {0x0188, 0x00000000 +#if CFG_PWROFST_COVER_CALIB + | USER_PWROFST_COVER_CALIB_FLAG +#endif +#if CFG_USER_CHAN_MAX_TXPWR_EN + | USER_CHAN_MAX_TXPWR_EN_FLAG +#endif +#if CFG_USER_TX_USE_ANA_F + | USER_TX_USE_ANA_F_FLAG +#endif +#if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE + | USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG +#endif + }, // user_ext_flags +#endif + +#ifdef CONFIG_RADAR_OR_IR_DETECT + {0x0019c,0x00000B00}, +#endif }; //adap test @@ -314,6 +337,38 @@ int system_config_8800d80(struct aic_usb_dev *usb_dev){ } +static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) +{ + int ret = 0; + uint32_t ext_patch_nb = patch_info->ext_patch_nb; + char ext_patch_file_name[50]; + int index = 0; + uint32_t id = 0; + uint32_t addr = 0; + + + if (ext_patch_nb > 0){ + + for (index = 0; index < patch_info->ext_patch_nb; index++){ + id = *(patch_info->ext_patch_param + (index * 2)); + addr = *(patch_info->ext_patch_param + (index * 2) + 1); + memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); + sprintf(ext_patch_file_name,"%s%d.bin", + FW_PATCH_BASE_NAME_8800D80_U02_EXT, + id); + AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", + __func__,ext_patch_file_name, id, addr); + + if (rwnx_plat_bin_fw_upload_android(usb_dev, addr, ext_patch_file_name)) { + ret = -1; + break; + } + } + } + return ret; +} + + int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) { struct aicbt_patch_table *head = NULL; @@ -331,6 +386,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) int i = 0; +#if 0 if (chip_id == CHIP_REV_U01) { head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80); } else { @@ -358,7 +414,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) } printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch); - +#endif if(testmode == FW_NORMAL_MODE){ if (chip_id != CHIP_REV_U01){ @@ -369,16 +425,16 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80_U02)) { return -1; } - #if 0 - if (rwnx_plat_bin_fw_patch_table_upload_android(usb_dev, FW_PATCH_TABLE_NAME_8800D80_U02)) { + + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { return -1; } - #else + if (aicbt_patch_table_load(usb_dev, head)) { return -1; } #endif - #endif + if (IS_CHIP_ID_H()){ if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80_U02, FW_BASE_NAME_8800D80_H_U02)) return -1; @@ -426,7 +482,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) } }else if(testmode == FW_TEST_MODE){ if (chip_id != CHIP_REV_U01){ - +#if 0 if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80_U02)) { return -1; } @@ -434,15 +490,15 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80_U02)) { return -1; } -#if 0 - if (rwnx_plat_bin_fw_patch_table_upload_android(usb_dev, FW_PATCH_TABLE_NAME_8800D80_U02)) { + + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { return -1; } -#else + if (aicbt_patch_table_load(usb_dev, head)) { return -1; } -#endif + if (chip_mcu_id) { int ret = 0; @@ -452,7 +508,7 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) return -1; } } - +#endif if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80_U02, FW_RF_BASE_NAME_8800D80_U02)) { AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); return -1; @@ -500,64 +556,115 @@ int aicfw_download_fw_8800d80(struct aic_usb_dev *usb_dev) wakeup_param->gpio_num[1] = 3;////default select gpiob2 for fw_wakeup_host wakeup_param->gpio_dft_lvl[1] = 1;////0:defalut pull down, 1:default pull up /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 0 - { - const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[0].ad_len = 12; - wakeup_param->ad_filter[0].ad_type = 0x09; - memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 - wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; - wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); - wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 1 - { - const uint8_t data[2] = {0x12,0x18}; - wakeup_param->ad_filter[1].ad_len = 3; - wakeup_param->ad_filter[1].ad_type = 0x3; - memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 - wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; - wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); - wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 2 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[2].ad_len = 0; - wakeup_param->ad_filter[2].ad_type = 0; - //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 - wakeup_param->ad_filter[2].ad_data_mask = 0; - wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; - wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 3 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[3].ad_len = 0; - wakeup_param->ad_filter[3].ad_type = 0; - //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 - wakeup_param->ad_filter[3].ad_data_mask = 0; - wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); - wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 4 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[4].ad_len = 0; - wakeup_param->ad_filter[4].ad_type = 0x09; - //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 - wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; - wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); - wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 0 + { + const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[0].ad_len = 12; + wakeup_param->ad_filter[0].ad_type = 0x09; + memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[0].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 1 + { + const uint8_t data[2] = {0x12,0x18}; + wakeup_param->ad_filter[1].ad_len = 3; + wakeup_param->ad_filter[1].ad_type = 0x3; + memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 + wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; + wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[1].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 2 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[2].ad_len = 0; + wakeup_param->ad_filter[2].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[2].ad_data_mask = 0; + wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; + wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[2].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 3 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[3].ad_len = 0; + wakeup_param->ad_filter[3].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[3].ad_data_mask = 0; + wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[3].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 4 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[4].ad_len = 0; + wakeup_param->ad_filter[4].ad_type = 0x09; + //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[4].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[5] = 0; + } for(i = 0; i < (sizeof(struct ble_wakeup_param_t)/4 +1); i++){ printk("write_blocks[%d]:0x%08X \r\n", i, write_blocks[i]); - rwnx_send_dbg_mem_write_req(usb_dev, 0x15FF00 + (4 * i), write_blocks[i]); + rwnx_send_dbg_mem_write_req(usb_dev, 0x15FE00 + (4 * i), write_blocks[i]); } rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO); kfree(wakeup_param); diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.h b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.h index c32d984..de6d99f 100644 --- a/drivers/aic8800/aic_load_fw/aic_compat_8800d80.h +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80.h @@ -15,13 +15,13 @@ #ifdef CONFIG_FOR_IPCAM #define FW_BASE_NAME_8800D80_U02 "fmacfw_8800d80_u02_ipc.bin" #define FW_BASE_NAME_8800D80_H_U02 "fmacfw_8800d80_h_u02_ipc.bin" - #else #define FW_BASE_NAME_8800D80_U02 "fmacfw_8800d80_u02.bin" #define FW_BASE_NAME_8800D80_H_U02 "fmacfw_8800d80_h_u02.bin" #endif #define FW_RF_BASE_NAME_8800D80_U02 "lmacfw_rf_8800d80_u02.bin" #define FW_PATCH_BASE_NAME_8800D80_U02 "fw_patch_8800d80_u02.bin" +#define FW_PATCH_BASE_NAME_8800D80_U02_EXT "fw_patch_8800d80_u02_ext" #define FW_ADID_BASE_NAME_8800D80_U02 "fw_adid_8800d80_u02.bin" #define FW_CALIBMODE_NAME_8800D80_U02 "calibmode_8800d80.bin" #define FW_PATCH_TABLE_NAME_8800D80_U02 "fw_patch_table_8800d80_u02.bin" diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c new file mode 100644 index 0000000..847f1bb --- /dev/null +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.c @@ -0,0 +1,767 @@ +#include "aic_txrxif.h" +#include "aicwf_usb.h" +#include "aicbluetooth.h" +#include "aic_compat_8800d80x2.h" +#include "aicwf_debug.h" +extern int ble_scan_wakeup_reboot_time; +extern uint32_t ad_data_filter_mask; +extern uint32_t gpio_num;//default select gpiob2 for fw_wakeup_host +extern uint32_t gpio_dft_lvl;//0:defalut pull down, 1:default pull up + +int rwnx_plat_bin_fw_upload_2(struct aic_usb_dev *usbdev, u32 fw_addr, + char *filename); +int rwnx_request_firmware_common(struct aic_usb_dev *usbdev, + u32** buffer, const char *filename); +void rwnx_plat_userconfig_parsing(char *buffer, int size); +void rwnx_release_firmware_common(u32** buffer); + +extern int testmode; +extern u8 chip_id; +extern u8 chip_mcu_id; + +typedef u32 (*array2_tbl_t)[2]; + +#define AIC_PATCH_MAGIG_NUM 0x48435450 // "PTCH" +#define AIC_PATCH_MAGIG_NUM_2 0x50544348 // "HCTP" +#define AIC_PATCH_BLOCK_MAX 4 + +typedef struct { + uint32_t magic_num; + uint32_t pair_start; + uint32_t magic_num_2; + uint32_t pair_count; + uint32_t block_dst[AIC_PATCH_BLOCK_MAX]; + uint32_t block_src[AIC_PATCH_BLOCK_MAX]; + uint32_t block_size[AIC_PATCH_BLOCK_MAX]; // word count +} aic_patch_t; + + +#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem) +#define AIC_PATCH_ADDR(mem) ((u32) (aic_patch_str_base + AIC_PATCH_OFST(mem))) + +#define USER_PWROFST_COVER_CALIB_FLAG (0x01U << 0) +#define USER_CHAN_MAX_TXPWR_EN_FLAG (0x01U << 1) +#define USER_TX_USE_ANA_F_FLAG (0x01U << 2) +#define USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG (0x01U << 3) +#define USER_HE_MU_EDCA_UPDATE_DISABLE_FLAG (0x01U << 4) + +#ifdef CONFIG_POWER_LIMIT +#define CFG_USER_CHAN_MAX_TXPWR_EN 1 +#else +#define CFG_USER_CHAN_MAX_TXPWR_EN 0 +#endif +#define CFG_USER_TX_USE_ANA_F 0 +#ifdef CONFIG_BAND_STEERING +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 1 +#else +#define CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE 0 +#endif + +u32 patch_tbl_d80x2[][2] = +{ +#ifdef CONFIG_PLATFORM_HI + {0x021c, 0x04000000},//hs amsdu + {0x0220, 0x04000000},//ss amsdu + {0x0224, 0x08000a01},//hs aggr + {0x0228, 0x08000a01},//ss aggr +#else + {0x021c, 0x04000000},//hs amsdu + {0x0220, 0x04010101},//ss amsdu + {0x0224, 0x50000a01},//hs aggr + {0x0228, 0x50000a00},//ss aggr +#endif + +#if 0 + #ifdef USE_5G + {0x00b4, 0xf3010001}, + #else + {0x00b4, 0xf3010000}, + #endif +#ifdef CONFIG_PLATFORM_HI + {0x0170, 0x00000001},//rx aggr counter +#else + {0x0170, 0x0000000A},//rx aggr counter +#endif +#endif + + {0x01f0, 0x00000001 + #if CFG_USER_CHAN_MAX_TXPWR_EN + | USER_CHAN_MAX_TXPWR_EN_FLAG + #endif + #if CFG_USER_TX_USE_ANA_F + | USER_TX_USE_ANA_F_FLAG + #endif + #if CFG_USER_APM_PRBRSP_OFFLOAD_DISABLE + | USER_APM_PRBRSP_OFFLOAD_DISABLE_FLAG + #endif + }, // user_ext_flags +}; + +//adap test +u32 adaptivity_patch_tbl_d80x2[][2] = { + {0x000C, 0x0000320A}, //linkloss_thd + {0x009C, 0x00000000}, //ac_param_conf + {0x01D0, 0x00010000}, //tx_adaptivity_en +}; + +u32 syscfg_tbl_masked_8800d80x2[][3] = { +}; + +u32 syscfg_tbl_8800d80x2[][2] = { + #ifdef CONFIG_PMIC_SETTING + {0x70001408, 0x00000000}, // stop wdg + #endif /* CONFIG_PMIC_SETTING */ + {0x40500010, 0x00000006},//cpu performance + {0x40500024, 0x0000001f}, +}; + +extern int adap_test; + +#define NEW_PATCH_BUFFER_MAP 1 + +int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev) +{ +#if 1 + u32 rd_patch_addr; + u32 aic_patch_addr; + u32 config_base, aic_patch_str_base; + #if (NEW_PATCH_BUFFER_MAP) + u32 patch_buff_addr, patch_buff_base, rd_version_addr, rd_version_val; + #endif + uint32_t start_addr; + u32 patch_addr; + u32 patch_cnt = sizeof(patch_tbl_d80x2) / 4 / 2; + struct dbg_mem_read_cfm rd_patch_addr_cfm; + int ret = 0; + int cnt = 0; + //adap test + int adap_patch_cnt = 0; + + if (adap_test) { + AICWFDBG(LOGINFO, "%s adap test \r\n", __func__); + adap_patch_cnt = sizeof(adaptivity_patch_tbl_d80x2)/sizeof(u32)/2; + } + + rd_patch_addr = RAM_FMAC_FW_ADDR_8800D80X2 + 0x01A8; + aic_patch_addr = rd_patch_addr + 8; + + AICWFDBG(LOGERROR, "Read FW mem: %08x\n", rd_patch_addr); + if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_patch_addr, &rd_patch_addr_cfm))) { + AICWFDBG(LOGERROR, "setting base[0x%x] rd fail: %d\n", rd_patch_addr, ret); + return ret; + } + AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); + config_base = rd_patch_addr_cfm.memdata; + + if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, aic_patch_addr, &rd_patch_addr_cfm))) { + AICWFDBG(LOGERROR, "patch_str_base[0x%x] rd fail: %d\n", aic_patch_addr, ret); + return ret; + } + AICWFDBG(LOGERROR, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); + aic_patch_str_base = rd_patch_addr_cfm.memdata; + + #if (NEW_PATCH_BUFFER_MAP) + rd_version_addr = RAM_FMAC_FW_ADDR_8800D80X2 + 0x01C; + if ((ret = rwnx_send_dbg_mem_read_req(usb_dev, rd_version_addr, &rd_patch_addr_cfm))) { + AICWFDBG(LOGERROR, "version val[0x%x] rd fail: %d\n", rd_version_addr, ret); + return ret; + } + rd_version_val = rd_patch_addr_cfm.memdata; + AICWFDBG(LOGINFO, "rd_version_val=%08X\n", rd_version_val); + usb_dev->fw_version_uint = rd_version_val; + patch_buff_addr = rd_patch_addr + 12; + ret = rwnx_send_dbg_mem_read_req(usb_dev, patch_buff_addr, &rd_patch_addr_cfm); + if (ret) { + AICWFDBG(LOGERROR, "patch buf rd fail\n"); + return ret; + } + AICWFDBG(LOGINFO, "%x=%x\n", rd_patch_addr_cfm.memaddr, rd_patch_addr_cfm.memdata); + patch_buff_base = rd_patch_addr_cfm.memdata; + patch_addr = start_addr = patch_buff_base; + #endif + + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM))) { + AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num), ret); + return ret; + } + + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(magic_num_2), AIC_PATCH_MAGIG_NUM_2))) { + AICWFDBG(LOGERROR, "maigic_num[0x%x] write fail: %d\n", AIC_PATCH_ADDR(magic_num_2), ret); + return ret; + } + + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(pair_start), patch_addr))) { + AICWFDBG(LOGERROR, "pair_start[0x%x] write fail: %d\n", AIC_PATCH_ADDR(pair_start), ret); + return ret; + } + + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(pair_count), patch_cnt + adap_patch_cnt))) { + AICWFDBG(LOGERROR, "pair_count[0x%x] write fail: %d\n", AIC_PATCH_ADDR(pair_count), ret); + return ret; + } + + for (cnt = 0; cnt < patch_cnt; cnt++) { + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt, patch_tbl_d80x2[cnt][0]+config_base))) { + AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt); + return ret; + } + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt+4, patch_tbl_d80x2[cnt][1]))) { + AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt+4); + return ret; + } + } + + if (adap_test){ + int tmp_cnt = patch_cnt + adap_patch_cnt; + AICWFDBG(LOGINFO, "%s set adap_test patch \r\n", __func__); + for (cnt = patch_cnt; cnt < tmp_cnt; cnt++) { + int tbl_idx = cnt - patch_cnt; + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt, adaptivity_patch_tbl_d80x2[tbl_idx][0]+config_base))) { + AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt); + return ret; + } + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, start_addr+8*cnt+4, adaptivity_patch_tbl_d80x2[tbl_idx][1]))) { + AICWFDBG(LOGERROR, "%x write fail\n", start_addr+8*cnt+4); + return ret; + } + } + } + + /* + * Patch block 0 ~ 3, that is void by default, can be set as: + * + * const u32 patch_block_0[3] = {0x11223344, 0x55667788, 0xaabbccdd}; + * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_dst[0]), 0x160000))) { + * printk("block_dst [0x%x] write fail: %d\n", (u32)(&aic_patch->block_dst[0]), ret); + * } + * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_src[0]), 0x307000))) { + * printk("block_src [0x%x] write fail: %d\n", (u32)(&aic_patch->block_src[0]), ret); + * } + * if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, (u32)(&aic_patch->block_size[0]), sizeof(patch_block_0) / sizeof(u32)))) { + * printk("block_size[0x%x] write fail: %d\n", (u32)(&aic_patch->block_size[0]), ret); + * } + * if ((ret = rwnx_send_dbg_mem_block_write_req(usb_dev, 0x307000, sizeof(patch_block_0), patch_block_0))) { + * printk("blk set fail: %d\n", ret); + * } + */ + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[0]), 0))) { + AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[0]), ret); + return ret; + } + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[1]), 0))) { + AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[1]), ret); + return ret; + } + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[2]), 0))) { + AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[2]), ret); + return ret; + } + if ((ret = rwnx_send_dbg_mem_write_req(usb_dev, AIC_PATCH_ADDR(block_size[3]), 0))) { + AICWFDBG(LOGERROR, "block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[3]), ret); + return ret; + } +#endif + + return 0; +} + + +#if 0 +extern char aic_fw_path[200]; + +int rwnx_plat_userconfig_load_8800d80x2(struct aic_usb_dev *usb_dev){ + int size; + u32 *dst=NULL; + char *filename = FW_USERCONFIG_NAME_8800D80X2; + + AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename); + + /* load file */ + size = rwnx_request_firmware_common(usb_dev, &dst, filename); + if (size <= 0) { + AICWFDBG(LOGERROR, "wrong size of firmware file\n"); + dst = NULL; + return 0; + } + + /* Copy the file on the Embedded side */ + AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size); + + rwnx_plat_userconfig_parsing((char *)dst, size); + + rwnx_release_firmware_common(&dst); + + AICWFDBG(LOGINFO, "userconfig download complete\n\n"); + return 0; + +} +#endif +int system_config_8800d80x2(struct aic_usb_dev *usb_dev){ + int syscfg_num; + int ret, cnt; + const u32 mem_addr = 0x40500000; + const u32 mem_addr2 = 0x40500004; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr, ret); + return ret; + } + chip_id = rd_mem_addr_cfm.memdata >> 16; + + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr2, ret); + return ret; + } + if (((rd_mem_addr_cfm.memdata >> 17) & 0x01UL) == 0x00UL) { + chip_mcu_id = 1; + } + + printk("chip_id=%x, chip_mcu_id = %d\n", chip_id, chip_mcu_id); + #if 1 + syscfg_num = sizeof(syscfg_tbl_8800d80x2) / sizeof(u32) / 2; + for (cnt = 0; cnt < syscfg_num; cnt++) { + ret = rwnx_send_dbg_mem_write_req(usb_dev, syscfg_tbl_8800d80x2[cnt][0], syscfg_tbl_8800d80x2[cnt][1]); + if (ret) { + printk("%x write fail: %d\n", syscfg_tbl_8800d80x2[cnt][0], ret); + return ret; + } + } + syscfg_num = sizeof(syscfg_tbl_masked_8800d80x2) / sizeof(u32) / 3; + for (cnt = 0; cnt < syscfg_num; cnt++) { + ret = rwnx_send_dbg_mem_mask_write_req(usb_dev, + syscfg_tbl_masked_8800d80x2[cnt][0], syscfg_tbl_masked_8800d80x2[cnt][1], syscfg_tbl_masked_8800d80x2[cnt][2]); + if (ret) { + printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800d80x2[cnt][0], ret); + return ret; + } + } + #endif + + return 0; +} + + +static int aicbt_ext_patch_data_load(struct aic_usb_dev *usb_dev, struct aicbt_patch_info_t *patch_info) +{ + int ret = 0; + uint32_t ext_patch_nb = patch_info->ext_patch_nb; + char ext_patch_file_name[50]; + int index = 0; + uint32_t id = 0; + uint32_t addr = 0; + + + if (ext_patch_nb > 0){ + + for (index = 0; index < patch_info->ext_patch_nb; index++){ + id = *(patch_info->ext_patch_param + (index * 2)); + addr = *(patch_info->ext_patch_param + (index * 2) + 1); + memset(ext_patch_file_name, 0, sizeof(ext_patch_file_name)); + sprintf(ext_patch_file_name,"%s%d.bin", + FW_PATCH_BASE_NAME_8800D80X2_U03_EXT, + id); + AICWFDBG(LOGDEBUG, "%s ext_patch_file_name:%s ext_patch_id:%x ext_patch_addr:%x \r\n", + __func__,ext_patch_file_name, id, addr); + + if (rwnx_plat_bin_fw_upload_android(usb_dev, addr, ext_patch_file_name)) { + ret = -1; + break; + } + } + } + return ret; +} + + +int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev) +{ +#ifdef CONFIG_USB_BT + struct aicbt_patch_table *head = NULL; + struct aicbt_patch_info_t patch_info = { + .info_len = 0, + .adid_addrinf = 0, + .addr_adid = 0, + .patch_addrinf = 0, + .addr_patch = 0, + .reset_addr = 0, + .reset_val = 0, + .adid_flag_addr = 0, + .adid_flag = 0, + }; + + int i = 0; + + if (chip_id < CHIP_REV_U05) { + head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U03); + } else { + head = aicbt_patch_table_alloc(usb_dev, FW_PATCH_TABLE_NAME_8800D80X2_U05); + } + if (head == NULL){ + printk("aicbt_patch_table_alloc fail\n"); + return -1; + } + + if(head == NULL){ + return -1; + } + if (chip_id < CHIP_REV_U05) { + patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80X2_U03; + patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03; + } else { + patch_info.addr_adid = FW_RAM_ADID_BASE_ADDR_8800D80X2_U05; + patch_info.addr_patch = FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05; + } + aicbt_patch_info_unpack(&patch_info, head); + if(patch_info.info_len == 0) { + printk("%s, aicbt_patch_info_unpack fail\n", __func__); + return -1; + } + + printk("addr_adid 0x%x, addr_patch 0x%x\n", patch_info.addr_adid, patch_info.addr_patch); + + if (chip_mcu_id) { + int ret = 0; + u32 retry = 0; + const u32 mem_addr = 0x40506030; + const u32 mem_addr2 = 0x40506004; + u32 mem_data; + struct dbg_mem_read_cfm rd_mem_addr_cfm; + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr, ret); + return ret; + } + if (0 == (rd_mem_addr_cfm.memdata & (0x01UL << 2))) { + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr2, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr2, ret); + return ret; + } + mem_data = (rd_mem_addr_cfm.memdata | (0x01UL << 17)) & (~(0x01UL << 18)); + + ret = rwnx_send_dbg_mem_write_req(usb_dev, mem_addr2, mem_data); + if (ret) { + printk("%x wr fail: %d\n", mem_addr2, ret); + return ret; + } + mdelay(1); + + while (1) { + ret = rwnx_send_dbg_mem_read_req(usb_dev, mem_addr, &rd_mem_addr_cfm); + if (ret) { + printk("%x rd fail: %d\n", mem_addr, ret); + return ret; + } + if (0 == (rd_mem_addr_cfm.memdata & (0x01UL << 2))) { + mdelay(1); + retry++; + if (retry > 20) { + printk("bt pwron timeout\n"); + return -1; + } + } else { + break; + } + } + } + } +#endif + + if(testmode == FW_NORMAL_MODE){ + + if (chip_id < CHIP_REV_U05){ +#ifdef CONFIG_USB_BT + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U03)) { + return -1; + } + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U03)) { + return -1; + } + + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + return -1; + } + + if (aicbt_patch_table_load(usb_dev, head)) { + return -1; + } + + mdelay(100); +#endif + + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80X2, FW_BASE_NAME_8800D80X2)) { + return -1; + } + #if 0 + if(rwnx_plat_bin_fw_upload_android(usb_dev, FW_RAM_CALIBMODE_ADDR_8800D80X2_U02, FW_CALIBMODE_NAME_8800D80X2_U02)) { + return -1; + } + if (rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, 0x1e0000)) + return -1; + #endif + if (aicwf_patch_config_8800d80x2(usb_dev)) { + return -1; + } + if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { + return -1; + } + }else { +#ifdef CONFIG_USB_BT + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U05)) { + return -1; + } + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) { + return -1; + } + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + return -1; + } + if (aicbt_patch_table_load(usb_dev, head)) { + return -1; + } + + mdelay(100); +#endif + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_FW_ADDR_8800D80X2, FW_BASE_NAME_8800D80X2)) { + return -1; + } + if (aicwf_patch_config_8800d80x2(usb_dev)) { + return -1; + } + if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { + return -1; + } + } + }else if(testmode == FW_TEST_MODE){ + if (chip_id < CHIP_REV_U05){ +#ifdef CONFIG_USB_BT + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U03)) { + return -1; + } + + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U03)) { + return -1; + } + + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + return -1; + } + + if (aicbt_patch_table_load(usb_dev, head)) { + return -1; + } + + mdelay(100); +#endif + + if (chip_mcu_id) { + int ret = 0; + ret = rwnx_plat_flash_bin_upload_android(usb_dev, FLASH_BIN_ADDR_8800M80X2, FLASH_BIN_8800M80X2); + if (ret && ret!= ENOENT) { + AICWFDBG(LOGERROR,"%s flash bin download fail \r\n", __func__); + return -1; + } + } + + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) { + AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); + return -1; + } + if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { + return -1; + } + } else { +#ifdef CONFIG_USB_BT + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_adid, FW_ADID_BASE_NAME_8800D80X2_U05)) { + return -1; + } + + if(rwnx_plat_bin_fw_upload_android(usb_dev, patch_info.addr_patch, FW_PATCH_BASE_NAME_8800D80X2_U05)) { + return -1; + } + + if (aicbt_ext_patch_data_load(usb_dev, &patch_info)) { + return -1; + } + + if (aicbt_patch_table_load(usb_dev, head)) { + return -1; + } + + mdelay(100); +#endif + if(rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, FW_RF_BASE_NAME_8800D80X2)) { + AICWFDBG(LOGERROR,"%s wifi fw download fail \r\n", __func__); + return -1; + } + if (rwnx_send_dbg_start_app_req(usb_dev, RAM_FMAC_RF_FW_ADDR_8800D80X2, HOST_START_APP_AUTO)) { + return -1; + } + } + }else if(testmode == FW_BLE_SCAN_AD_FILTER_MODE){ +/* + data and ad_data_filter_mask instructions for use + ex. + data[18] = {0x46,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0xff,0xff,0x43,0x52,0x45,0x4c,0x42}; + mask = 1100 0000 0111 1111 1100 0000 0000 0000 = 0xc07fc000 + + data = 0x46,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0xff,0xff,0x43,0x52,0x45,0x4c,0x42 + mask = 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0...... fill 0 + + data & mask = "0x46 0x00" 0x00 0x00 0x00 0x00 0x00 0x00 0x00 "0x30 0xff 0xff 0x43 0x52 0x45 0x4c 0x42" + using data & mask value condition to wakeup host_wake_bt gpio +*/ + + struct ble_wakeup_param_t* wakeup_param = (struct ble_wakeup_param_t*)kmalloc(sizeof(struct ble_wakeup_param_t), GFP_KERNEL); + uint32_t *write_blocks = (uint32_t *)wakeup_param; + + printk("%s ble scan wakeup \r\n", __func__); + + memset(wakeup_param, 0, sizeof(struct ble_wakeup_param_t)); + rwnx_plat_bin_fw_upload_android(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, FW_BLE_SCAN_AD_FILTER_NAME); + wakeup_param->magic_num = 0x53454C42;//magic_num + wakeup_param->delay_scan_to = 1000;//delay start scan time(ms) + wakeup_param->reboot_to = ble_scan_wakeup_reboot_time;//reboot time + /******************************************************************/ + ///gpio_trigger_idx : 0 if wakeup_param->gpio_dft_lvl[0]=0xfe,this idx will be invalid. + wakeup_param->gpio_num[0] = gpio_num;////default select gpiob2 for fw_wakeup_host + wakeup_param->gpio_dft_lvl[0] = gpio_dft_lvl;////0:defalut pull down, 1:default pull up + ///gpio_trigger_idx : 1 if wakeup_param->gpio_dft_lvl[1]=0xfe,this idx will be invalid. + wakeup_param->gpio_num[1] = 3;////default select gpiob2 for fw_wakeup_host + wakeup_param->gpio_dft_lvl[1] = 1;////0:defalut pull down, 1:default pull up + /********************************************************************/ + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 0 + { + const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[0].ad_len = 12; + wakeup_param->ad_filter[0].ad_type = 0x09; + memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[0].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 1 + { + const uint8_t data[2] = {0x12,0x18}; + wakeup_param->ad_filter[1].ad_len = 3; + wakeup_param->ad_filter[1].ad_type = 0x3; + memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 + wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; + wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[1].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 2 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[2].ad_len = 0; + wakeup_param->ad_filter[2].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[2].ad_data_mask = 0; + wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; + wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[2].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 3 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[3].ad_len = 0; + wakeup_param->ad_filter[3].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[3].ad_data_mask = 0; + wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[3].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 4 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[4].ad_len = 0; + wakeup_param->ad_filter[4].ad_type = 0x09; + //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[4].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[5] = 0; + } + + for(i = 0; i < (sizeof(struct ble_wakeup_param_t)/4 +1); i++){ + printk("write_blocks[%d]:0x%08X \r\n", i, write_blocks[i]); + rwnx_send_dbg_mem_write_req(usb_dev, 0x15FE00 + (4 * i), write_blocks[i]); + } + //rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80, HOST_START_APP_AUTO); + + int ret; + ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x40500048, RAM_FW_BLE_SCAN_WAKEUP_ADDR_8800D80); + if (ret) { + printk("%x write fail\n", ret); + } + ret = rwnx_send_dbg_mem_write_req(usb_dev, 0x4050012c, 0x00000040); + if (ret) { + printk("%x write fail\n", ret); + } + + + kfree(wakeup_param); + + return -1; + + } + + return 0; +} + + diff --git a/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h new file mode 100644 index 0000000..571bf8c --- /dev/null +++ b/drivers/aic8800/aic_load_fw/aic_compat_8800d80x2.h @@ -0,0 +1,45 @@ +#include +#include "aicwf_usb.h" + +#define USB_DEVICE_ID_AIC_8800D80X2 0x8D90 +#define USB_DEVICE_ID_AIC_8800D81X2 0x8D91 +#define USB_DEVICE_ID_AIC_8800D89X2 0x8D99 + +#ifdef CONFIG_FOR_IPCAM +#define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2_ipc.bin" +#else +#define FW_BASE_NAME_8800D80X2 "fmacfw_8800d80x2.bin" +#endif +#define FW_RF_BASE_NAME_8800D80X2 "lmacfw_rf_8800d80x2.bin" + +#define FW_PATCH_BASE_NAME_8800D80X2_U03 "fw_patch_8800d80x2_u03.bin" +#define FW_PATCH_BASE_NAME_8800D80X2_U03_EXT "fw_patch_8800d80x2_u03_ext" +#define FW_ADID_BASE_NAME_8800D80X2_U03 "fw_adid_8800d80x2_u03.bin" +#define FW_PATCH_TABLE_NAME_8800D80X2_U03 "fw_patch_table_8800d80x2_u03.bin" + +#define FW_PATCH_BASE_NAME_8800D80X2_U05 "fw_patch_8800d80x2_u05.bin" +#define FW_PATCH_BASE_NAME_8800D80X2_U05_EXT "fw_patch_8800d80x2_u05_ext" +#define FW_ADID_BASE_NAME_8800D80X2_U05 "fw_adid_8800d80x2_u05.bin" +#define FW_PATCH_TABLE_NAME_8800D80X2_U05 "fw_patch_table_8800d80x2_u05.bin" + +#define FLASH_BIN_8800M80X2 "host_wb_8800m80x2.bin" + +#define FW_USERCONFIG_NAME_8800D80X2 "aic_userconfig_8800d80x2.txt" + +#define RAM_FMAC_FW_ADDR_8800D80X2 0x120000 +#define RAM_FMAC_RF_FW_ADDR_8800D80X2 0x120000 + +#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U03 0x003018f8 +#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U03 0x0030b494 + +#define FW_RAM_ADID_BASE_ADDR_8800D80X2_U05 0x003018f8 +#define FW_RAM_PATCH_BASE_ADDR_8800D80X2_U05 0x0030b48c + +#define FLASH_BIN_ADDR_8800M80X2 0x8000000 + + +int aicwf_patch_config_8800d80x2(struct aic_usb_dev *usb_dev); +int rwnx_plat_userconfig_load_8800d80x2(struct aic_usb_dev *usbdev); +int system_config_8800d80x2(struct aic_usb_dev *usb_dev); +int aicfw_download_fw_8800d80x2(struct aic_usb_dev *usb_dev); + diff --git a/drivers/aic8800/aic_load_fw/aic_txrxif.h b/drivers/aic8800/aic_load_fw/aic_txrxif.h index d566a11..08df943 100644 --- a/drivers/aic8800/aic_load_fw/aic_txrxif.h +++ b/drivers/aic8800/aic_load_fw/aic_txrxif.h @@ -18,7 +18,7 @@ #define DATA_BUF_MAX 2048 #define TXPKT_BLOCKSIZE 512 #define MAX_AGGR_TXPKT_LEN (1536*32) -#define CMD_TX_TIMEOUT 5000 +#define CMD_TX_TIMEOUT 2000 #define TX_ALIGNMENT 4 #define RX_HWHRD_LEN 60 //58->60 word allined diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth.c b/drivers/aic8800/aic_load_fw/aicbluetooth.c index bda29b1..9ae9254 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth.c +++ b/drivers/aic8800/aic_load_fw/aicbluetooth.c @@ -5,6 +5,7 @@ #include "aic_txrxif.h" #include "md5.h" #include "aicbluetooth.h" +#include "aicwf_debug.h" #ifdef CONFIG_USE_FW_REQUEST #include #endif @@ -16,6 +17,8 @@ #define GET_VALUE 3 extern int flash_erase_len; +int flash_write_size = 0; +u32 flash_write_bin_crc = 0; typedef struct { @@ -146,7 +149,9 @@ enum aicbsp_cpmode_type { ///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl; ///pwr lvl:20(min), 30 , 40 , 50 , 60(max) #define AICBT_TXPWR_LVL 0x00006020 -#define AICBT_TXPWR_LVL_8800d80 0x00006F2F +#define AICBT_TXPWR_LVL_8800d80 0x00006F2F +#define AICBT_TXPWR_LVL_8800d80x2 0x00006F2F + #define AICBSP_MODE_BT_HCI_MODE_NULL 0 #define AICBSP_MODE_BT_HCI_MODE_MB 1 @@ -155,6 +160,7 @@ enum aicbsp_cpmode_type { #define AICBSP_HWINFO_DEFAULT (-1) #define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK +#define AICBT_BTMODE_DEFAULT_8800d80x2 AICBT_BTMODE_BT_ONLY_COANT #define AICBT_BTMODE_DEFAULT_8800d80 AICBT_BTMODE_BT_ONLY_COANT #define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_ONLY #define AICBT_BTPORT_DEFAULT AICBT_BTPORT_MB @@ -163,6 +169,7 @@ enum aicbsp_cpmode_type { #define AICBT_LPM_ENABLE_DEFAULT 0 #define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL #define AICBT_TXPWR_LVL_DEFAULT_8800d80 AICBT_TXPWR_LVL_8800d80 +#define AICBT_TXPWR_LVL_DEFAULT_8800d80x2 AICBT_TXPWR_LVL_8800d80x2 #define AIC_HW_INFO 0x21 @@ -181,6 +188,83 @@ module_param_string(saved_sdk_ver, saved_sdk_ver,64, 0660); #endif + +const u32 crc_tab[256] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, +}; +u32 aic_crc32(u8 *p, u32 len, u32 crc) +{ + while(len--) + { + crc = crc_tab[((crc & 0xFF) ^ *p++)] ^ (crc >> 8); + } + return crc; +} + int aic_bt_platform_init(struct aic_usb_dev *usbdev) { rwnx_cmd_mgr_init(&usbdev->cmd_mgr); @@ -274,7 +358,9 @@ static int aic_load_firmware(u32 ** fw_buf, const char *name, struct device *dev len = snprintf(path, FW_PATH_MAX, "%s/%s/%s",aic_default_fw_path, "aic8800", name); } else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80) { len = snprintf(path, FW_PATH_MAX, "%s/%s/%s",aic_default_fw_path, "aic8800D80", name); - } else { + } else if (usb_dev->chipid == PRODUCT_ID_AIC8800D80X2) { + len = snprintf(path, FW_PATH_MAX, "%s/%s/%s",aic_default_fw_path, "aic8800D80X2", name); + }else { printk("%s unknown chipid %d\n", __func__, usb_dev->chipid); } #else @@ -671,9 +757,11 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr, int err=0; const u32 mem_addr = fw_addr; struct dbg_mem_read_cfm rd_mem_addr_cfm; + u32 crc = ~0UL; /* load aic firmware */ size = aic_load_firmware(&dst, filename, dev); + flash_write_size = size; if(size<=0){ printk("wrong size of firmware file\n"); vfree(dst); @@ -716,6 +804,8 @@ int rwnx_plat_flash_bin_upload_android(struct aic_usb_dev *usbdev, u32 fw_addr, /* Copy the file on the Embedded side */ printk("### Upload %s firmware, @ = %x size=%d\n", filename, fw_addr, size); + crc = aic_crc32((u8 *)dst, size, crc); + flash_write_bin_crc = crc; if (size > 1024) {// > 1KB data for (i = 0; i < (size - 1024); i += 1024) {//each time write 1KB @@ -832,6 +922,16 @@ int get_adap_test(void){ return adap_test; } +int get_flash_bin_size(void) +{ + return flash_write_size; +} + +u32 get_flash_bin_crc(void) +{ + return flash_write_bin_crc; +} + EXPORT_SYMBOL(get_fw_path); EXPORT_SYMBOL(get_testmode); @@ -842,6 +942,9 @@ EXPORT_SYMBOL(get_hardware_info); EXPORT_SYMBOL(get_adap_test); +EXPORT_SYMBOL(get_flash_bin_size); +EXPORT_SYMBOL(get_flash_bin_crc); + void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap) { @@ -1172,6 +1275,14 @@ static struct aicbt_info_t aicbt_info[] = { },//PRODUCT_ID_AIC8800D80 { },//PRODUCT_ID_AIC8800D81 + { + .btmode = AICBT_BTMODE_DEFAULT_8800d80x2, + .btport = AICBT_BTPORT_DEFAULT, + .uart_baud = AICBT_UART_BAUD_DEFAULT, + .uart_flowctrl = AICBT_UART_FC_DEFAULT, + .lpm_enable = AICBT_LPM_ENABLE_DEFAULT, + .txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT_8800d80x2, + },//PRODUCT_ID_AIC8800D80X2 }; int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table *_head) @@ -1223,13 +1334,47 @@ int aicbt_patch_table_load(struct aic_usb_dev *usbdev, struct aicbt_patch_table int aicbt_patch_info_unpack(struct aicbt_patch_info_t *patch_info, struct aicbt_patch_table *head_t) { + uint8_t *patch_info_array = (uint8_t*)patch_info; + int base_len = 0; + int memcpy_len = 0; + if (AICBT_PT_INF == head_t->type) { - patch_info->info_len = head_t->len; - if(patch_info->info_len == 0) + base_len = ((offsetof(struct aicbt_patch_info_t, ext_patch_nb_addr) - offsetof(struct aicbt_patch_info_t, adid_addrinf) )/sizeof(uint32_t))/2; + AICWFDBG(LOGDEBUG, "%s head_t->len:%d base_len:%d \r\n", __func__, head_t->len, base_len); + + if (head_t->len > base_len){ + patch_info->info_len = base_len; + memcpy_len = patch_info->info_len + 1;//include ext patch nb + } else{ + patch_info->info_len = head_t->len; + memcpy_len = patch_info->info_len; + } + AICWFDBG(LOGDEBUG, "%s memcpy_len:%d \r\n", __func__, memcpy_len); + + if (patch_info->info_len == 0) return 0; - memcpy(&patch_info->adid_addrinf, head_t->data, patch_info->info_len * sizeof(uint32_t) * 2); + + memcpy(((patch_info_array) + sizeof(patch_info->info_len)), + head_t->data, + memcpy_len * sizeof(uint32_t) * 2); + AICWFDBG(LOGDEBUG, "%s adid_addrinf:%x addr_adid:%x \r\n", __func__, + ((struct aicbt_patch_info_t *)patch_info_array)->adid_addrinf, + ((struct aicbt_patch_info_t *)patch_info_array)->addr_adid); + + if (patch_info->ext_patch_nb > 0){ + int index = 0; + patch_info->ext_patch_param = (uint32_t *)(head_t->data + ((memcpy_len) * 2)); + + for(index = 0; index < patch_info->ext_patch_nb; index++){ + AICWFDBG(LOGDEBUG, "%s id:%x addr:%x \r\n", __func__, + *(patch_info->ext_patch_param + (index * 2)), + *(patch_info->ext_patch_param + (index * 2) + 1)); + } + } + } return 0; + } int rwnx_plat_bin_fw_patch_table_upload_android(struct aic_usb_dev *usbdev, char *filename){ diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c index 229b5ce..fe1f82e 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c +++ b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.c @@ -240,6 +240,7 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) struct aicwf_bus *bus = usbdev->bus_if; u8 *buffer = bus->cmd_buf; u16 index = 0; + int ret = 0; memset(buffer, 0, CMD_BUF_MAX); buffer[0] = (len+4) & 0x00ff; @@ -261,7 +262,10 @@ void aicwf_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len) index += 2; memcpy(&buffer[index], (u8 *)msg->param, msg->param_len); - aicwf_bus_txmsg(bus, buffer, len + 8); + ret = aicwf_bus_txmsg(bus, buffer, len + 8); + if (ret == -EIO) { + ret = aicwf_bus_txmsg(bus, buffer, len + 8); + } } static inline void *rwnx_msg_zalloc(lmac_msg_id_t const id, diff --git a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.h b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.h index 352258b..3b54bf9 100644 --- a/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.h +++ b/drivers/aic8800/aic_load_fw/aicbluetooth_cmds.h @@ -59,6 +59,7 @@ struct lmac_msg struct aicbt_patch_info_t { uint32_t info_len; +//base len start uint32_t adid_addrinf; uint32_t addr_adid; uint32_t patch_addrinf; @@ -67,6 +68,12 @@ struct aicbt_patch_info_t { uint32_t reset_val; uint32_t adid_flag_addr; uint32_t adid_flag; +//base len end +//ext patch nb + uint32_t ext_patch_nb_addr; + uint32_t ext_patch_nb; + uint32_t *ext_patch_param; + }; diff --git a/drivers/aic8800/aic_load_fw/aicwf_usb.c b/drivers/aic8800/aic_load_fw/aicwf_usb.c index 32a2243..9d91e47 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_usb.c +++ b/drivers/aic8800/aic_load_fw/aicwf_usb.c @@ -25,6 +25,7 @@ #include "aicbluetooth.h" #include "aicwf_debug.h" #include "aic_compat_8800d80.h" +#include "aic_compat_8800d80x2.h" #define JUMP_TABLE_BASE 0x161928 #define JUMP_TABLE_OFFSET(i) ((u32)(JUMP_TABLE_BASE+(i)*4)) @@ -37,6 +38,7 @@ extern uint32_t gpio_num;//default select gpiob2 for fw_wakeup_host extern uint32_t gpio_dft_lvl;//0:defalut pull down, 1:default pull up u8 chip_id = 0; u8 chip_sub_id = 0; +u8 chip_mcu_id = 0; int fw_loaded = 0; void aicwf_usb_tx_flowctrl(struct aic_usb_dev *usb_dev, bool state) @@ -820,8 +822,10 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in #ifdef CONFIG_USB_MSG_EP if ( usb_dev->msg_out_pipe != 0 && - (usb_dev->chipid == PRODUCT_ID_AIC8801 || - usb_dev->chipid == PRODUCT_ID_AIC8800D81)){ + (usb_dev->chipid == PRODUCT_ID_AIC8801 || + usb_dev->chipid == PRODUCT_ID_AIC8800D81|| + usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || + usb_dev->chipid == PRODUCT_ID_AIC8800D89X2)){ printk("TX Msg Bulk EP found\n"); usb_dev->use_msg_ep = 1; }else{ @@ -838,12 +842,11 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in #endif #endif - - if (usb->speed == USB_SPEED_HIGH) { - printk("Aic high speed USB device detected\n"); - } else { - printk("Aic full speed USB device detected\n"); - } + printk("Aic %s speed USB device detected\n", + (usb->speed == USB_SPEED_SUPER) ? "super" : + (usb->speed == USB_SPEED_HIGH) ? "high" : + (usb->speed == USB_SPEED_FULL) ? "full" : + (usb->speed == USB_SPEED_LOW) ? "low" : "NG"); exit: return ret; } @@ -981,6 +984,11 @@ u32 patch_tbl[][2] ={ #endif #ifdef CONFIG_USB_SUSPEND_REBOOT_TIME {0x0110, 0x03e80001}//reboot time when usb suspend,0001 enables reboot on suspend, default 0x3e8 = 1000ms reboot +#else +#ifdef CONFIG_SUPPORT_USB_SUSP +//USB SUSP keep working 0x0100:enable 0x0000:disable +{0x0110, 0x00000100} +#endif #endif }; @@ -1133,6 +1141,8 @@ static int system_config(struct aic_usb_dev *usb_dev) return system_config_8800(usb_dev); }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D80){ return system_config_8800d80(usb_dev); + }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D80X2){ + return system_config_8800d80x2(usb_dev); }else{ return -1; } @@ -1345,6 +1355,18 @@ static int aicloadfw_chipmatch(struct aic_usb_dev *usb_dev, u16 vid, u16 pid){ usb_dev->chipid = PRODUCT_ID_AIC8800D81; AICWFDBG(LOGINFO, "%s USE AIC8800D41\r\n", __func__); return 0; + }else if(pid == USB_DEVICE_ID_AIC_8800D80X2 && vid == USB_VENDOR_ID_AIC_V2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D80X2; + AICWFDBG(LOGINFO, "%s USE AIC8800D80X2\r\n", __func__); + return 0; + }else if(pid == USB_DEVICE_ID_AIC_8800D81X2 && vid == USB_VENDOR_ID_AIC_V2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D81X2; + AICWFDBG(LOGINFO, "%s USE AIC8800D81X2\r\n", __func__); + return 0; + }else if(pid == USB_DEVICE_ID_AIC_8800D89X2 && vid == USB_VENDOR_ID_AIC_V2){ + usb_dev->chipid = PRODUCT_ID_AIC8800D89X2; + AICWFDBG(LOGINFO, "%s USE AIC8800D89X2\r\n", __func__); + return 0; }else{ return -1; } @@ -1452,64 +1474,115 @@ int aicfw_download_fw_8800(struct aic_usb_dev *usb_dev){ wakeup_param->gpio_num[1] = 3;////default select gpiob2 for fw_wakeup_host wakeup_param->gpio_dft_lvl[1] = 1;////0:defalut pull down, 1:default pull up /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 0 - { - const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[0].ad_len = 12; - wakeup_param->ad_filter[0].ad_type = 0x09; - memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 - wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; - wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); - wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 1 - { - const uint8_t data[2] = {0x12,0x18}; - wakeup_param->ad_filter[1].ad_len = 3; - wakeup_param->ad_filter[1].ad_type = 0x3; - memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 - wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; - wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); - wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 2 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[2].ad_len = 0; - wakeup_param->ad_filter[2].ad_type = 0; - //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 - wakeup_param->ad_filter[2].ad_data_mask = 0; - wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; - wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 3 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[3].ad_len = 0; - wakeup_param->ad_filter[3].ad_type = 0; - //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 - wakeup_param->ad_filter[3].ad_data_mask = 0; - wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); - wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } - /********************************************************************/ - //MAX_AD_FILTER_NUM=5 :num 4 - { - //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; - wakeup_param->ad_filter[4].ad_len = 0; - wakeup_param->ad_filter[4].ad_type = 0x09; - //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 - wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; - wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); - wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] - } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 0 + { + const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[0].ad_len = 12; + wakeup_param->ad_filter[0].ad_type = 0x09; + memcpy(wakeup_param->ad_filter[0].ad_data, data,wakeup_param->ad_filter[0].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[0].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[0].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[0].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[0].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[0].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 1 + { + const uint8_t data[2] = {0x12,0x18}; + wakeup_param->ad_filter[1].ad_len = 3; + wakeup_param->ad_filter[1].ad_type = 0x3; + memcpy(wakeup_param->ad_filter[1].ad_data, data,wakeup_param->ad_filter[1].ad_len-1);// 1100 0000 0000 0000 0000 0000 0000 0000 //0xc0000000 + wakeup_param->ad_filter[1].ad_data_mask = 0xc0000000; + wakeup_param->ad_filter[1].ad_role = ROLE_COMBO|(COMBO_0<<4); + wakeup_param->ad_filter[1].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[1].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[1].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 2 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[2].ad_len = 0; + wakeup_param->ad_filter[2].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[2].ad_data_mask = 0; + wakeup_param->ad_filter[2].ad_role = ROLE_ONLY; + wakeup_param->ad_filter[2].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[2].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[2].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 3 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[3].ad_len = 0; + wakeup_param->ad_filter[3].ad_type = 0; + //memcpy(wakeup_param->ad_filter[2].ad_data, data,wakeup_param->ad_filter[2].ad_len-1);// 1100 0000 0111 1111 1100 0000 0000 0000 //0xc07fc000 + wakeup_param->ad_filter[3].ad_data_mask = 0; + wakeup_param->ad_filter[3].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[3].gpio_trigger_idx = TG_IDX_0;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[3].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[3].wl_addr.addr[5] = 0; + } + /********************************************************************/ + //MAX_AD_FILTER_NUM=5 :num 4 + { + //const uint8_t data[11] = {0x59,0x4B,0x32,0x42,0x41,0x5F,0x54,0x45,0x53,0x54,0x33}; + wakeup_param->ad_filter[4].ad_len = 0; + wakeup_param->ad_filter[4].ad_type = 0x09; + //memcpy(wakeup_param->ad_filter[4].ad_data, data,wakeup_param->ad_filter[4].ad_len-1);// 1111 1111 1110 0000 0000 0000 0000 0000 //0xffe00000 + wakeup_param->ad_filter[4].ad_data_mask = 0xffe00000; + wakeup_param->ad_filter[4].ad_role = ROLE_COMBO|(COMBO_1<<4); + wakeup_param->ad_filter[4].gpio_trigger_idx = TG_IDX_0|TG_IDX_1;//0: match for wakeup_param->gpio_num[0] 1: match for wakeup_param->gpio_num[1] + /********************************************************************/ + /*enable white list addr for paired remote ble addr. if all 0: all addr will use ad filter + wl_addr have value xx: only remote addr in white_list_addr will use ad filter + ********************************************************************/ + wakeup_param->ad_filter[4].wl_addr.addr[0] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[1] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[2] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[3] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[4] = 0; + wakeup_param->ad_filter[4].wl_addr.addr[5] = 0; + } for(i = 0; i < (sizeof(struct ble_wakeup_param_t)/4 +1); i++){ printk("write_blocks[%d]:0x%08X \r\n", i, write_blocks[i]); - rwnx_send_dbg_mem_write_req(usb_dev, 0x15FF00 + (4 * i), write_blocks[i]); + rwnx_send_dbg_mem_write_req(usb_dev, 0x15FE00 + (4 * i), write_blocks[i]); } rwnx_send_dbg_start_app_req(usb_dev, RAM_FW_BLE_SCAN_WAKEUP_ADDR, HOST_START_APP_AUTO); kfree(wakeup_param); @@ -1580,6 +1653,8 @@ int aicfw_download_fw(struct aic_usb_dev *usb_dev) return aicfw_download_fw_8800(usb_dev); }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D80){ return aicfw_download_fw_8800d80(usb_dev); + }else if(usb_dev->chipid == PRODUCT_ID_AIC8800D80X2){ + return aicfw_download_fw_8800d80x2(usb_dev); }else{ return -1; } @@ -1606,7 +1681,9 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i if(fw_loaded == 1 && (id->idProduct == USB_DEVICE_ID_AIC_8801 || id->idProduct == USB_DEVICE_ID_AIC_8800D81 || - id->idProduct == USB_DEVICE_ID_AIC_8800D41)){ + id->idProduct == USB_DEVICE_ID_AIC_8800D41 || + id->idProduct == USB_DEVICE_ID_AIC_8800D81X2 || + id->idProduct == USB_DEVICE_ID_AIC_8800D89X2)){ return -1; } @@ -1673,15 +1750,17 @@ static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_i aic_bt_platform_init(usb_dev); - if (usb->speed != USB_SPEED_HIGH) { - printk("Aic full speed USB device detected\n"); + if ((usb->speed != USB_SPEED_HIGH) && (usb->speed != USB_SPEED_SUPER)) { + printk("Aic USB device detected speed = %d\n", usb->speed); system_reboot(usb_dev); goto out_free_bus; } if(fw_loaded == 0 && - (usb_dev->chipid == PRODUCT_ID_AIC8801 || - usb_dev->chipid == PRODUCT_ID_AIC8800D81)){ + (usb_dev->chipid == PRODUCT_ID_AIC8801 || + usb_dev->chipid == PRODUCT_ID_AIC8800D81|| + usb_dev->chipid == PRODUCT_ID_AIC8800D81X2 || + usb_dev->chipid == PRODUCT_ID_AIC8800D89X2)){ rwnx_send_reboot(usb_dev); goto out_free_bus; } @@ -1764,6 +1843,9 @@ static struct usb_device_id aicwf_usb_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_AIC, USB_DEVICE_ID_AIC_8800D81)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_DEVICE_ID_AIC_8800D40)}, {USB_DEVICE(USB_VENDOR_ID_AIC, USB_DEVICE_ID_AIC_8800D41)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D80X2)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D81X2)}, + {USB_DEVICE(USB_VENDOR_ID_AIC_V2, USB_DEVICE_ID_AIC_8800D89X2)}, {} }; diff --git a/drivers/aic8800/aic_load_fw/aicwf_usb.h b/drivers/aic8800/aic_load_fw/aicwf_usb.h index adaac5b..759698d 100644 --- a/drivers/aic8800/aic_load_fw/aicwf_usb.h +++ b/drivers/aic8800/aic_load_fw/aicwf_usb.h @@ -21,26 +21,32 @@ /* USB Device ID */ #define USB_VENDOR_ID_AIC 0xA69C +#define USB_VENDOR_ID_AIC_V2 0x368B #define USB_DEVICE_ID_AIC 0x8800 -#define USB_DEVICE_ID_AIC_8801 0x8801 +#define USB_DEVICE_ID_AIC_8801 0x8801 #define CHIP_REV_U01 0x1 #define CHIP_REV_U02 0x3 #define CHIP_REV_U03 0x7 +#define CHIP_REV_U04 0xf +#define CHIP_REV_U05 0x1f #define CHIP_SUB_REV_U04 0x20 enum AICWF_IC{ PRODUCT_ID_AIC8800 = 0, - PRODUCT_ID_AIC8801, - PRODUCT_ID_AIC8800DC, - PRODUCT_ID_AIC8800DW, - PRODUCT_ID_AIC8800D80, - PRODUCT_ID_AIC8800D81, + PRODUCT_ID_AIC8801, + PRODUCT_ID_AIC8800DC, + PRODUCT_ID_AIC8800DW, + PRODUCT_ID_AIC8800D80, + PRODUCT_ID_AIC8800D81, + PRODUCT_ID_AIC8800D80X2, + PRODUCT_ID_AIC8800D81X2, + PRODUCT_ID_AIC8800D89X2, }; #define AICWF_USB_RX_URBS (20) -#define AICWF_USB_TX_URBS (100) +#define AICWF_USB_TX_URBS (30) #define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4) #define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3) #define AICWF_USB_MAX_PKT_SIZE (2048) @@ -84,6 +90,7 @@ enum AICWF_IC{ #define FW_RAM_PATCH_BASE_ADDR 0x00100000 #define FW_RAM_PATCH_BASE_ADDR_U03 0x00100000 #define FW_PATCH_TEST_BASE_ADDR 0x00100000 +#define RAM_FW_BLE_WAKEUP_OUT_ADDR 0x0015f000 enum { FW_NORMAL_MODE, @@ -118,6 +125,7 @@ enum aicwf_usb_state { #define MAX_GPIO_TRIGGER_NUM 2// Max user config num of gpio #define MAX_ROLE_COMNO_IDX_NUM 2// Max num of ad role type combo,form( enum gpio_combo_idx) + #define AD_ROLE_FLAG 0x0f #define ROLE_COMBO_IDX_FLAG 0xf0 @@ -136,6 +144,11 @@ enum gpio_trigger_bit { TG_IDX_1 = (1<<1), }; +/* BD Address */ +typedef struct { + uint8_t addr[6]; +}bdaddr_t; + struct wakeup_ad_data_filter { uint32_t ad_data_mask; uint8_t gpio_trigger_idx; @@ -143,6 +156,7 @@ struct wakeup_ad_data_filter { uint8_t ad_len; uint8_t ad_type; uint8_t ad_data[31]; + bdaddr_t wl_addr; }; struct ble_wakeup_param_t { diff --git a/drivers/aic8800/aic_load_fw/rwnx_version_gen.h b/drivers/aic8800/aic_load_fw/rwnx_version_gen.h index afc7528..f31bfce 100644 --- a/drivers/aic8800/aic_load_fw/rwnx_version_gen.h +++ b/drivers/aic8800/aic_load_fw/rwnx_version_gen.h @@ -1,4 +1,4 @@ #define RWNX_VERS_REV "1a4b0054d2M (master)" #define RWNX_VERS_MOD "6.4.3.0" #define RWNX_VERS_BANNER "rwnx v6.4.3.0 - 1a4b0054d2M (master)" -#define RELEASE_DATE "2024_0420_24c7777c" +#define RELEASE_DATE "2025_0423_71b66e7b" diff --git a/fw/aic8800D80/aic_powerlimit_8800d80.txt b/fw/aic8800D80/aic_powerlimit_8800d80.txt new file mode 100644 index 0000000..9a16186 --- /dev/null +++ b/fw/aic8800D80/aic_powerlimit_8800d80.txt @@ -0,0 +1,118 @@ +# AIC POWERLIMIT 2024/1108/1900 +# Max tx power reference: Linux wireless regulatory database for CRDA +# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt +# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment + +# Table 1: +## 2.4G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 15 15 15 15 15 +CH02 16 16 16 16 16 +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 12 12 12 12 12 +CH13 12 12 12 12 12 +CH14 NA NA NA 12 12 +## END + +# Table 2: +## 2.4G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 NA NA NA NA NA +CH02 NA NA NA NA NA +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 NA NA NA NA NA +CH13 NA NA NA NA NA +CH14 NA NA NA NA NA +## END + +# Table 3: +## 5G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH36 15 16 16 16 15 +CH40 15 16 16 16 15 +CH44 15 16 16 16 15 +CH48 15 16 16 16 15 +# 5G Band 2 +CH52 15 16 16 16 15 +CH56 15 16 16 16 15 +CH60 15 16 16 16 15 +CH64 15 16 16 16 15 +# 5G Band 3 +CH100 NA 16 16 16 15 +CH104 NA 16 16 16 15 +CH108 NA 16 16 16 15 +CH112 NA 16 16 16 15 +CH116 NA 16 16 16 15 +CH120 NA 16 16 16 15 +CH124 NA 16 16 16 15 +CH128 NA 16 16 16 15 +CH132 NA 16 16 16 15 +CH136 NA 16 16 16 15 +CH140 NA 16 16 16 15 +CH144 NA NA 16 16 15 +# 5G Band 4 +CH149 16 16 11 NA 11 +CH153 16 16 11 NA 11 +CH157 16 16 11 NA 11 +CH161 16 16 11 NA 11 +CH165 16 16 11 NA 11 +## END + +# Table 4: +## 5G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH38 15 16 16 16 15 +CH46 15 16 16 16 15 +# 5G Band 2 +CH54 15 16 16 16 15 +CH62 15 16 16 16 15 +# 5G Band 3 +CH102 NA 16 16 16 15 +CH110 NA 16 16 16 15 +CH118 NA 16 16 16 15 +CH126 NA 16 16 16 15 +CH134 NA 16 16 16 15 +CH142 NA 16 NA 16 15 +# 5G Band 4 +CH151 16 16 11 NA 11 +CH159 16 16 11 NA 11 +## END + +# Table 5: +## 5G, 80M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH42 15 16 16 16 15 +# 5G Band 2 +CH58 15 16 16 16 15 +# 5G Band 3 +CH106 NA 16 16 16 15 +CH122 NA 16 16 16 15 +CH138 NA 16 NA NA 15 +# 5G Band 4 +CH155 16 16 11 NA 11 +## END + diff --git a/fw/aic8800D80/aic_userconfig_8800d80.txt b/fw/aic8800D80/aic_userconfig_8800d80.txt index d8d6633..864efb4 100644 --- a/fw/aic8800D80/aic_userconfig_8800d80.txt +++ b/fw/aic8800D80/aic_userconfig_8800d80.txt @@ -2,74 +2,88 @@ # txpwr_lvl enable=1 -lvl_11b_11ag_1m_2g4=20 -lvl_11b_11ag_2m_2g4=20 -lvl_11b_11ag_5m5_2g4=20 -lvl_11b_11ag_11m_2g4=20 -lvl_11b_11ag_6m_2g4=20 -lvl_11b_11ag_9m_2g4=20 -lvl_11b_11ag_12m_2g4=20 -lvl_11b_11ag_18m_2g4=20 -lvl_11b_11ag_24m_2g4=20 -lvl_11b_11ag_36m_2g4=19 -lvl_11b_11ag_48m_2g4=18 -lvl_11b_11ag_54m_2g4=17 -lvl_11n_11ac_mcs0_2g4=20 -lvl_11n_11ac_mcs1_2g4=20 -lvl_11n_11ac_mcs2_2g4=20 -lvl_11n_11ac_mcs3_2g4=20 -lvl_11n_11ac_mcs4_2g4=20 -lvl_11n_11ac_mcs5_2g4=19 -lvl_11n_11ac_mcs6_2g4=18 -lvl_11n_11ac_mcs7_2g4=17 -lvl_11n_11ac_mcs8_2g4=17 -lvl_11n_11ac_mcs9_2g4=16 -lvl_11ax_mcs0_2g4=20 -lvl_11ax_mcs1_2g4=20 -lvl_11ax_mcs2_2g4=20 -lvl_11ax_mcs3_2g4=20 -lvl_11ax_mcs4_2g4=20 -lvl_11ax_mcs5_2g4=19 -lvl_11ax_mcs6_2g4=18 -lvl_11ax_mcs7_2g4=17 -lvl_11ax_mcs8_2g4=17 -lvl_11ax_mcs9_2g4=16 -lvl_11ax_mcs10_2g4=15 -lvl_11ax_mcs11_2g4=15 -lvl_11a_6m_5g=19 -lvl_11a_9m_5g=19 -lvl_11a_12m_5g=19 +lvl_11b_11ag_1m_2g4=18 +lvl_11b_11ag_2m_2g4=18 +lvl_11b_11ag_5m5_2g4=18 +lvl_11b_11ag_11m_2g4=18 +lvl_11b_11ag_6m_2g4=18 +lvl_11b_11ag_9m_2g4=18 +lvl_11b_11ag_12m_2g4=18 +lvl_11b_11ag_18m_2g4=18 +lvl_11b_11ag_24m_2g4=16 +lvl_11b_11ag_36m_2g4=16 +lvl_11b_11ag_48m_2g4=15 +lvl_11b_11ag_54m_2g4=15 +lvl_11n_11ac_mcs0_2g4=18 +lvl_11n_11ac_mcs1_2g4=18 +lvl_11n_11ac_mcs2_2g4=18 +lvl_11n_11ac_mcs3_2g4=18 +lvl_11n_11ac_mcs4_2g4=16 +lvl_11n_11ac_mcs5_2g4=16 +lvl_11n_11ac_mcs6_2g4=15 +lvl_11n_11ac_mcs7_2g4=15 +lvl_11n_11ac_mcs8_2g4=14 +lvl_11n_11ac_mcs9_2g4=14 +lvl_11ax_mcs0_2g4=18 +lvl_11ax_mcs1_2g4=18 +lvl_11ax_mcs2_2g4=18 +lvl_11ax_mcs3_2g4=18 +lvl_11ax_mcs4_2g4=16 +lvl_11ax_mcs5_2g4=16 +lvl_11ax_mcs6_2g4=15 +lvl_11ax_mcs7_2g4=15 +lvl_11ax_mcs8_2g4=14 +lvl_11ax_mcs9_2g4=14 +lvl_11ax_mcs10_2g4=13 +lvl_11ax_mcs11_2g4=13 +lvl_11a_6m_5g=18 +lvl_11a_9m_5g=18 +lvl_11a_12m_5g=18 lvl_11a_18m_5g=18 -lvl_11a_24m_5g=18 -lvl_11a_36m_5g=18 -lvl_11a_48m_5g=18 -lvl_11a_54m_5g=18 -lvl_11n_11ac_mcs0_5g=19 -lvl_11n_11ac_mcs1_5g=19 -lvl_11n_11ac_mcs2_5g=19 +lvl_11a_24m_5g=16 +lvl_11a_36m_5g=16 +lvl_11a_48m_5g=15 +lvl_11a_54m_5g=15 +lvl_11n_11ac_mcs0_5g=18 +lvl_11n_11ac_mcs1_5g=18 +lvl_11n_11ac_mcs2_5g=18 lvl_11n_11ac_mcs3_5g=18 -lvl_11n_11ac_mcs4_5g=18 -lvl_11n_11ac_mcs5_5g=18 -lvl_11n_11ac_mcs6_5g=18 -lvl_11n_11ac_mcs7_5g=17 -lvl_11n_11ac_mcs8_5g=15 -lvl_11n_11ac_mcs9_5g=15 -lvl_11ax_mcs0_5g=19 -lvl_11ax_mcs1_5g=19 -lvl_11ax_mcs2_5g=19 +lvl_11n_11ac_mcs4_5g=16 +lvl_11n_11ac_mcs5_5g=16 +lvl_11n_11ac_mcs6_5g=15 +lvl_11n_11ac_mcs7_5g=15 +lvl_11n_11ac_mcs8_5g=14 +lvl_11n_11ac_mcs9_5g=14 +lvl_11ax_mcs0_5g=18 +lvl_11ax_mcs1_5g=18 +lvl_11ax_mcs2_5g=18 lvl_11ax_mcs3_5g=18 -lvl_11ax_mcs4_5g=18 -lvl_11ax_mcs5_5g=18 -lvl_11ax_mcs6_5g=18 -lvl_11ax_mcs7_5g=17 -lvl_11ax_mcs8_5g=15 -lvl_11ax_mcs9_5g=15 -lvl_11ax_mcs10_5g=13 -lvl_11ax_mcs11_5g=13 +lvl_11ax_mcs4_5g=16 +lvl_11ax_mcs5_5g=16 +lvl_11ax_mcs6_5g=14 +lvl_11ax_mcs7_5g=14 +lvl_11ax_mcs8_5g=13 +lvl_11ax_mcs9_5g=13 +lvl_11ax_mcs10_5g=12 +lvl_11ax_mcs11_5g=12 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 +lvl_adj_5g_chan_42=0 +lvl_adj_5g_chan_58=0 +lvl_adj_5g_chan_106=0 +lvl_adj_5g_chan_122=0 +lvl_adj_5g_chan_138=0 +lvl_adj_5g_chan_155=0 # txpwr_loss -loss_enable=0 -loss_value=2 +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 # txpwr_ofst ofst_enable=0 diff --git a/fw/aic8800D80/aic_userconfig_8800d80_u11.txt b/fw/aic8800D80/aic_userconfig_8800d80_u11.txt new file mode 100644 index 0000000..5bf7827 --- /dev/null +++ b/fw/aic8800D80/aic_userconfig_8800d80_u11.txt @@ -0,0 +1,124 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=20 +lvl_11b_11ag_2m_2g4=20 +lvl_11b_11ag_5m5_2g4=20 +lvl_11b_11ag_11m_2g4=20 +lvl_11b_11ag_6m_2g4=20 +lvl_11b_11ag_9m_2g4=20 +lvl_11b_11ag_12m_2g4=20 +lvl_11b_11ag_18m_2g4=20 +lvl_11b_11ag_24m_2g4=20 +lvl_11b_11ag_36m_2g4=19 +lvl_11b_11ag_48m_2g4=18 +lvl_11b_11ag_54m_2g4=17 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=20 +lvl_11n_11ac_mcs5_2g4=19 +lvl_11n_11ac_mcs6_2g4=18 +lvl_11n_11ac_mcs7_2g4=17 +lvl_11n_11ac_mcs8_2g4=17 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=20 +lvl_11ax_mcs1_2g4=20 +lvl_11ax_mcs2_2g4=20 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=20 +lvl_11ax_mcs5_2g4=19 +lvl_11ax_mcs6_2g4=18 +lvl_11ax_mcs7_2g4=17 +lvl_11ax_mcs8_2g4=17 +lvl_11ax_mcs9_2g4=16 +lvl_11ax_mcs10_2g4=15 +lvl_11ax_mcs11_2g4=15 +lvl_11a_6m_5g=19 +lvl_11a_9m_5g=19 +lvl_11a_12m_5g=19 +lvl_11a_18m_5g=18 +lvl_11a_24m_5g=18 +lvl_11a_36m_5g=18 +lvl_11a_48m_5g=18 +lvl_11a_54m_5g=18 +lvl_11n_11ac_mcs0_5g=19 +lvl_11n_11ac_mcs1_5g=19 +lvl_11n_11ac_mcs2_5g=19 +lvl_11n_11ac_mcs3_5g=18 +lvl_11n_11ac_mcs4_5g=18 +lvl_11n_11ac_mcs5_5g=18 +lvl_11n_11ac_mcs6_5g=18 +lvl_11n_11ac_mcs7_5g=17 +lvl_11n_11ac_mcs8_5g=15 +lvl_11n_11ac_mcs9_5g=15 +lvl_11ax_mcs0_5g=19 +lvl_11ax_mcs1_5g=19 +lvl_11ax_mcs2_5g=19 +lvl_11ax_mcs3_5g=18 +lvl_11ax_mcs4_5g=18 +lvl_11ax_mcs5_5g=18 +lvl_11ax_mcs6_5g=18 +lvl_11ax_mcs7_5g=17 +lvl_11ax_mcs8_5g=15 +lvl_11ax_mcs9_5g=15 +lvl_11ax_mcs10_5g=13 +lvl_11ax_mcs11_5g=13 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 +lvl_adj_5g_chan_42=0 +lvl_adj_5g_chan_58=0 +lvl_adj_5g_chan_106=0 +lvl_adj_5g_chan_122=0 +lvl_adj_5g_chan_138=0 +lvl_adj_5g_chan_155=0 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_2g4_11b_chan_1_4=0 +ofst_2g4_11b_chan_5_9=0 +ofst_2g4_11b_chan_10_13=0 +ofst_2g4_ofdm_highrate_chan_1_4=0 +ofst_2g4_ofdm_highrate_chan_5_9=0 +ofst_2g4_ofdm_highrate_chan_10_13=0 +ofst_2g4_ofdm_lowrate_chan_1_4=0 +ofst_2g4_ofdm_lowrate_chan_5_9=0 +ofst_2g4_ofdm_lowrate_chan_10_13=0 +ofst_5g_ofdm_lowrate_chan_42=0 +ofst_5g_ofdm_lowrate_chan_58=0 +ofst_5g_ofdm_lowrate_chan_106=0 +ofst_5g_ofdm_lowrate_chan_122=0 +ofst_5g_ofdm_lowrate_chan_138=0 +ofst_5g_ofdm_lowrate_chan_155=0 +ofst_5g_ofdm_highrate_chan_42=0 +ofst_5g_ofdm_highrate_chan_58=0 +ofst_5g_ofdm_highrate_chan_106=0 +ofst_5g_ofdm_highrate_chan_122=0 +ofst_5g_ofdm_highrate_chan_138=0 +ofst_5g_ofdm_highrate_chan_155=0 +ofst_5g_ofdm_midrate_chan_42=0 +ofst_5g_ofdm_midrate_chan_58=0 +ofst_5g_ofdm_midrate_chan_106=0 +ofst_5g_ofdm_midrate_chan_122=0 +ofst_5g_ofdm_midrate_chan_138=0 +ofst_5g_ofdm_midrate_chan_155=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800D80/aic_userconfig_8800d80_u11_cus.txt b/fw/aic8800D80/aic_userconfig_8800d80_u11_cus.txt new file mode 100644 index 0000000..f58796c --- /dev/null +++ b/fw/aic8800D80/aic_userconfig_8800d80_u11_cus.txt @@ -0,0 +1,124 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=18 +lvl_11b_11ag_2m_2g4=18 +lvl_11b_11ag_5m5_2g4=18 +lvl_11b_11ag_11m_2g4=18 +lvl_11b_11ag_6m_2g4=18 +lvl_11b_11ag_9m_2g4=18 +lvl_11b_11ag_12m_2g4=18 +lvl_11b_11ag_18m_2g4=18 +lvl_11b_11ag_24m_2g4=18 +lvl_11b_11ag_36m_2g4=18 +lvl_11b_11ag_48m_2g4=18 +lvl_11b_11ag_54m_2g4=17 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=20 +lvl_11n_11ac_mcs5_2g4=19 +lvl_11n_11ac_mcs6_2g4=18 +lvl_11n_11ac_mcs7_2g4=18 +lvl_11n_11ac_mcs8_2g4=17 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=20 +lvl_11ax_mcs1_2g4=20 +lvl_11ax_mcs2_2g4=20 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=20 +lvl_11ax_mcs5_2g4=19 +lvl_11ax_mcs6_2g4=18 +lvl_11ax_mcs7_2g4=18 +lvl_11ax_mcs8_2g4=17 +lvl_11ax_mcs9_2g4=17 +lvl_11ax_mcs10_2g4=16 +lvl_11ax_mcs11_2g4=16 +lvl_11a_6m_5g=18 +lvl_11a_9m_5g=18 +lvl_11a_12m_5g=18 +lvl_11a_18m_5g=18 +lvl_11a_24m_5g=18 +lvl_11a_36m_5g=18 +lvl_11a_48m_5g=18 +lvl_11a_54m_5g=18 +lvl_11n_11ac_mcs0_5g=20 +lvl_11n_11ac_mcs1_5g=19 +lvl_11n_11ac_mcs2_5g=19 +lvl_11n_11ac_mcs3_5g=18 +lvl_11n_11ac_mcs4_5g=18 +lvl_11n_11ac_mcs5_5g=18 +lvl_11n_11ac_mcs6_5g=18 +lvl_11n_11ac_mcs7_5g=17 +lvl_11n_11ac_mcs8_5g=16 +lvl_11n_11ac_mcs9_5g=16 +lvl_11ax_mcs0_5g=20 +lvl_11ax_mcs1_5g=19 +lvl_11ax_mcs2_5g=19 +lvl_11ax_mcs3_5g=18 +lvl_11ax_mcs4_5g=18 +lvl_11ax_mcs5_5g=18 +lvl_11ax_mcs6_5g=18 +lvl_11ax_mcs7_5g=17 +lvl_11ax_mcs8_5g=16 +lvl_11ax_mcs9_5g=16 +lvl_11ax_mcs10_5g=15 +lvl_11ax_mcs11_5g=15 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 +lvl_adj_5g_chan_42=0 +lvl_adj_5g_chan_58=0 +lvl_adj_5g_chan_106=0 +lvl_adj_5g_chan_122=0 +lvl_adj_5g_chan_138=0 +lvl_adj_5g_chan_155=0 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_2g4_11b_chan_1_4=0 +ofst_2g4_11b_chan_5_9=0 +ofst_2g4_11b_chan_10_13=0 +ofst_2g4_ofdm_highrate_chan_1_4=0 +ofst_2g4_ofdm_highrate_chan_5_9=0 +ofst_2g4_ofdm_highrate_chan_10_13=0 +ofst_2g4_ofdm_lowrate_chan_1_4=0 +ofst_2g4_ofdm_lowrate_chan_5_9=0 +ofst_2g4_ofdm_lowrate_chan_10_13=0 +ofst_5g_ofdm_lowrate_chan_42=0 +ofst_5g_ofdm_lowrate_chan_58=0 +ofst_5g_ofdm_lowrate_chan_106=0 +ofst_5g_ofdm_lowrate_chan_122=0 +ofst_5g_ofdm_lowrate_chan_138=0 +ofst_5g_ofdm_lowrate_chan_155=0 +ofst_5g_ofdm_highrate_chan_42=0 +ofst_5g_ofdm_highrate_chan_58=0 +ofst_5g_ofdm_highrate_chan_106=0 +ofst_5g_ofdm_highrate_chan_122=0 +ofst_5g_ofdm_highrate_chan_138=0 +ofst_5g_ofdm_highrate_chan_155=0 +ofst_5g_ofdm_midrate_chan_42=0 +ofst_5g_ofdm_midrate_chan_58=0 +ofst_5g_ofdm_midrate_chan_106=0 +ofst_5g_ofdm_midrate_chan_122=0 +ofst_5g_ofdm_midrate_chan_138=0 +ofst_5g_ofdm_midrate_chan_155=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800D80/aic_userconfig_8800d80_u11_pro.txt b/fw/aic8800D80/aic_userconfig_8800d80_u11_pro.txt new file mode 100644 index 0000000..f6de9fd --- /dev/null +++ b/fw/aic8800D80/aic_userconfig_8800d80_u11_pro.txt @@ -0,0 +1,124 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=20 +lvl_11b_11ag_2m_2g4=20 +lvl_11b_11ag_5m5_2g4=20 +lvl_11b_11ag_11m_2g4=20 +lvl_11b_11ag_6m_2g4=20 +lvl_11b_11ag_9m_2g4=20 +lvl_11b_11ag_12m_2g4=20 +lvl_11b_11ag_18m_2g4=20 +lvl_11b_11ag_24m_2g4=20 +lvl_11b_11ag_36m_2g4=19 +lvl_11b_11ag_48m_2g4=18 +lvl_11b_11ag_54m_2g4=17 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=20 +lvl_11n_11ac_mcs5_2g4=19 +lvl_11n_11ac_mcs6_2g4=18 +lvl_11n_11ac_mcs7_2g4=17 +lvl_11n_11ac_mcs8_2g4=17 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=20 +lvl_11ax_mcs1_2g4=20 +lvl_11ax_mcs2_2g4=20 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=20 +lvl_11ax_mcs5_2g4=19 +lvl_11ax_mcs6_2g4=18 +lvl_11ax_mcs7_2g4=17 +lvl_11ax_mcs8_2g4=17 +lvl_11ax_mcs9_2g4=16 +lvl_11ax_mcs10_2g4=15 +lvl_11ax_mcs11_2g4=15 +lvl_11a_6m_5g=19 +lvl_11a_9m_5g=19 +lvl_11a_12m_5g=19 +lvl_11a_18m_5g=18 +lvl_11a_24m_5g=18 +lvl_11a_36m_5g=18 +lvl_11a_48m_5g=18 +lvl_11a_54m_5g=18 +lvl_11n_11ac_mcs0_5g=19 +lvl_11n_11ac_mcs1_5g=19 +lvl_11n_11ac_mcs2_5g=19 +lvl_11n_11ac_mcs3_5g=18 +lvl_11n_11ac_mcs4_5g=18 +lvl_11n_11ac_mcs5_5g=18 +lvl_11n_11ac_mcs6_5g=18 +lvl_11n_11ac_mcs7_5g=17 +lvl_11n_11ac_mcs8_5g=15 +lvl_11n_11ac_mcs9_5g=15 +lvl_11ax_mcs0_5g=19 +lvl_11ax_mcs1_5g=19 +lvl_11ax_mcs2_5g=19 +lvl_11ax_mcs3_5g=18 +lvl_11ax_mcs4_5g=18 +lvl_11ax_mcs5_5g=18 +lvl_11ax_mcs6_5g=18 +lvl_11ax_mcs7_5g=17 +lvl_11ax_mcs8_5g=15 +lvl_11ax_mcs9_5g=15 +lvl_11ax_mcs10_5g=14 +lvl_11ax_mcs11_5g=14 + +# txpwr_lvl_adj +lvl_adj_enable=0 +lvl_adj_2g4_chan_1_4=0 +lvl_adj_2g4_chan_5_9=0 +lvl_adj_2g4_chan_10_13=0 +lvl_adj_5g_chan_42=0 +lvl_adj_5g_chan_58=0 +lvl_adj_5g_chan_106=0 +lvl_adj_5g_chan_122=0 +lvl_adj_5g_chan_138=0 +lvl_adj_5g_chan_155=0 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_2g4_11b_chan_1_4=0 +ofst_2g4_11b_chan_5_9=0 +ofst_2g4_11b_chan_10_13=0 +ofst_2g4_ofdm_highrate_chan_1_4=0 +ofst_2g4_ofdm_highrate_chan_5_9=0 +ofst_2g4_ofdm_highrate_chan_10_13=0 +ofst_2g4_ofdm_lowrate_chan_1_4=0 +ofst_2g4_ofdm_lowrate_chan_5_9=0 +ofst_2g4_ofdm_lowrate_chan_10_13=0 +ofst_5g_ofdm_lowrate_chan_42=0 +ofst_5g_ofdm_lowrate_chan_58=0 +ofst_5g_ofdm_lowrate_chan_106=0 +ofst_5g_ofdm_lowrate_chan_122=0 +ofst_5g_ofdm_lowrate_chan_138=0 +ofst_5g_ofdm_lowrate_chan_155=0 +ofst_5g_ofdm_highrate_chan_42=0 +ofst_5g_ofdm_highrate_chan_58=0 +ofst_5g_ofdm_highrate_chan_106=0 +ofst_5g_ofdm_highrate_chan_122=0 +ofst_5g_ofdm_highrate_chan_138=0 +ofst_5g_ofdm_highrate_chan_155=0 +ofst_5g_ofdm_midrate_chan_42=0 +ofst_5g_ofdm_midrate_chan_58=0 +ofst_5g_ofdm_midrate_chan_106=0 +ofst_5g_ofdm_midrate_chan_122=0 +ofst_5g_ofdm_midrate_chan_138=0 +ofst_5g_ofdm_midrate_chan_155=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800D80/fmacfw_8800d80_h_u02.bin b/fw/aic8800D80/fmacfw_8800d80_h_u02.bin new file mode 100644 index 0000000..e6bab41 Binary files /dev/null and b/fw/aic8800D80/fmacfw_8800d80_h_u02.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin b/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin new file mode 100644 index 0000000..18490aa Binary files /dev/null and b/fw/aic8800D80/fmacfw_8800d80_h_u02_ipc.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_u02.bin b/fw/aic8800D80/fmacfw_8800d80_u02.bin index b5b4271..b65b6bc 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_u02.bin and b/fw/aic8800D80/fmacfw_8800d80_u02.bin differ diff --git a/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin b/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin index 4b03cd3..1256572 100644 Binary files a/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin and b/fw/aic8800D80/fmacfw_8800d80_u02_ipc.bin differ diff --git a/fw/aic8800D80/fw_ble_scan_ad_filter.bin b/fw/aic8800D80/fw_ble_scan_ad_filter.bin index ca17f67..2ae7835 100644 Binary files a/fw/aic8800D80/fw_ble_scan_ad_filter.bin and b/fw/aic8800D80/fw_ble_scan_ad_filter.bin differ diff --git a/fw/aic8800D80/fw_patch_8800d80_u02.bin b/fw/aic8800D80/fw_patch_8800d80_u02.bin index b3234d9..1db68ca 100644 Binary files a/fw/aic8800D80/fw_patch_8800d80_u02.bin and b/fw/aic8800D80/fw_patch_8800d80_u02.bin differ diff --git a/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin b/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin new file mode 100644 index 0000000..f407e2f Binary files /dev/null and b/fw/aic8800D80/fw_patch_8800d80_u02_ext0.bin differ diff --git a/fw/aic8800D80/fw_patch_table_8800d80_u02.bin b/fw/aic8800D80/fw_patch_table_8800d80_u02.bin index 4907160..67d5414 100644 Binary files a/fw/aic8800D80/fw_patch_table_8800d80_u02.bin and b/fw/aic8800D80/fw_patch_table_8800d80_u02.bin differ diff --git a/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin b/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin index 07716a6..8c1a583 100644 Binary files a/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin and b/fw/aic8800D80/lmacfw_rf_8800d80_u02.bin differ diff --git a/fw/aic8800DC/aic_powerlimit_8800dc.txt b/fw/aic8800DC/aic_powerlimit_8800dc.txt new file mode 100644 index 0000000..9a16186 --- /dev/null +++ b/fw/aic8800DC/aic_powerlimit_8800dc.txt @@ -0,0 +1,118 @@ +# AIC POWERLIMIT 2024/1108/1900 +# Max tx power reference: Linux wireless regulatory database for CRDA +# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt +# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment + +# Table 1: +## 2.4G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 15 15 15 15 15 +CH02 16 16 16 16 16 +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 12 12 12 12 12 +CH13 12 12 12 12 12 +CH14 NA NA NA 12 12 +## END + +# Table 2: +## 2.4G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 NA NA NA NA NA +CH02 NA NA NA NA NA +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 NA NA NA NA NA +CH13 NA NA NA NA NA +CH14 NA NA NA NA NA +## END + +# Table 3: +## 5G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH36 15 16 16 16 15 +CH40 15 16 16 16 15 +CH44 15 16 16 16 15 +CH48 15 16 16 16 15 +# 5G Band 2 +CH52 15 16 16 16 15 +CH56 15 16 16 16 15 +CH60 15 16 16 16 15 +CH64 15 16 16 16 15 +# 5G Band 3 +CH100 NA 16 16 16 15 +CH104 NA 16 16 16 15 +CH108 NA 16 16 16 15 +CH112 NA 16 16 16 15 +CH116 NA 16 16 16 15 +CH120 NA 16 16 16 15 +CH124 NA 16 16 16 15 +CH128 NA 16 16 16 15 +CH132 NA 16 16 16 15 +CH136 NA 16 16 16 15 +CH140 NA 16 16 16 15 +CH144 NA NA 16 16 15 +# 5G Band 4 +CH149 16 16 11 NA 11 +CH153 16 16 11 NA 11 +CH157 16 16 11 NA 11 +CH161 16 16 11 NA 11 +CH165 16 16 11 NA 11 +## END + +# Table 4: +## 5G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH38 15 16 16 16 15 +CH46 15 16 16 16 15 +# 5G Band 2 +CH54 15 16 16 16 15 +CH62 15 16 16 16 15 +# 5G Band 3 +CH102 NA 16 16 16 15 +CH110 NA 16 16 16 15 +CH118 NA 16 16 16 15 +CH126 NA 16 16 16 15 +CH134 NA 16 16 16 15 +CH142 NA 16 NA 16 15 +# 5G Band 4 +CH151 16 16 11 NA 11 +CH159 16 16 11 NA 11 +## END + +# Table 5: +## 5G, 80M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH42 15 16 16 16 15 +# 5G Band 2 +CH58 15 16 16 16 15 +# 5G Band 3 +CH106 NA 16 16 16 15 +CH122 NA 16 16 16 15 +CH138 NA 16 NA NA 15 +# 5G Band 4 +CH155 16 16 11 NA 11 +## END + diff --git a/fw/aic8800DC/aic_powerlimit_8800dw.txt b/fw/aic8800DC/aic_powerlimit_8800dw.txt new file mode 100644 index 0000000..9a16186 --- /dev/null +++ b/fw/aic8800DC/aic_powerlimit_8800dw.txt @@ -0,0 +1,118 @@ +# AIC POWERLIMIT 2024/1108/1900 +# Max tx power reference: Linux wireless regulatory database for CRDA +# https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/tree/db.txt +# If loss_value in aic_userconfig_8800d80.txt is enabled, the power value in this document will be subtracted from loss_value in actual judgment + +# Table 1: +## 2.4G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 15 15 15 15 15 +CH02 16 16 16 16 16 +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 12 12 12 12 12 +CH13 12 12 12 12 12 +CH14 NA NA NA 12 12 +## END + +# Table 2: +## 2.4G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +CH01 NA NA NA NA NA +CH02 NA NA NA NA NA +CH03 16 16 16 16 16 +CH04 16 16 16 16 16 +CH05 16 16 16 16 16 +CH06 16 16 16 16 16 +CH07 16 16 16 16 16 +CH08 16 16 16 16 16 +CH09 16 16 16 16 16 +CH10 16 16 16 16 16 +CH11 16 16 16 16 16 +CH12 NA NA NA NA NA +CH13 NA NA NA NA NA +CH14 NA NA NA NA NA +## END + +# Table 3: +## 5G, 20M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH36 15 16 16 16 15 +CH40 15 16 16 16 15 +CH44 15 16 16 16 15 +CH48 15 16 16 16 15 +# 5G Band 2 +CH52 15 16 16 16 15 +CH56 15 16 16 16 15 +CH60 15 16 16 16 15 +CH64 15 16 16 16 15 +# 5G Band 3 +CH100 NA 16 16 16 15 +CH104 NA 16 16 16 15 +CH108 NA 16 16 16 15 +CH112 NA 16 16 16 15 +CH116 NA 16 16 16 15 +CH120 NA 16 16 16 15 +CH124 NA 16 16 16 15 +CH128 NA 16 16 16 15 +CH132 NA 16 16 16 15 +CH136 NA 16 16 16 15 +CH140 NA 16 16 16 15 +CH144 NA NA 16 16 15 +# 5G Band 4 +CH149 16 16 11 NA 11 +CH153 16 16 11 NA 11 +CH157 16 16 11 NA 11 +CH161 16 16 11 NA 11 +CH165 16 16 11 NA 11 +## END + +# Table 4: +## 5G, 40M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH38 15 16 16 16 15 +CH46 15 16 16 16 15 +# 5G Band 2 +CH54 15 16 16 16 15 +CH62 15 16 16 16 15 +# 5G Band 3 +CH102 NA 16 16 16 15 +CH110 NA 16 16 16 15 +CH118 NA 16 16 16 15 +CH126 NA 16 16 16 15 +CH134 NA 16 16 16 15 +CH142 NA 16 NA 16 15 +# 5G Band 4 +CH151 16 16 11 NA 11 +CH159 16 16 11 NA 11 +## END + +# Table 5: +## 5G, 80M,#5# +## START +## SRRC FCC ETSI JP UNSET +# 5G Band 1 +CH42 15 16 16 16 15 +# 5G Band 2 +CH58 15 16 16 16 15 +# 5G Band 3 +CH106 NA 16 16 16 15 +CH122 NA 16 16 16 15 +CH138 NA 16 NA NA 15 +# 5G Band 4 +CH155 16 16 11 NA 11 +## END + diff --git a/fw/aic8800DC/aic_userconfig_8800dc.txt b/fw/aic8800DC/aic_userconfig_8800dc.txt new file mode 100644 index 0000000..9e4bea6 --- /dev/null +++ b/fw/aic8800DC/aic_userconfig_8800dc.txt @@ -0,0 +1,62 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=20 +lvl_11b_11ag_2m_2g4=20 +lvl_11b_11ag_5m5_2g4=20 +lvl_11b_11ag_11m_2g4=20 +lvl_11b_11ag_6m_2g4=20 +lvl_11b_11ag_9m_2g4=20 +lvl_11b_11ag_12m_2g4=20 +lvl_11b_11ag_18m_2g4=20 +lvl_11b_11ag_24m_2g4=18 +lvl_11b_11ag_36m_2g4=18 +lvl_11b_11ag_48m_2g4=16 +lvl_11b_11ag_54m_2g4=16 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=18 +lvl_11n_11ac_mcs5_2g4=18 +lvl_11n_11ac_mcs6_2g4=16 +lvl_11n_11ac_mcs7_2g4=16 +lvl_11n_11ac_mcs8_2g4=16 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=20 +lvl_11ax_mcs1_2g4=20 +lvl_11ax_mcs2_2g4=20 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=18 +lvl_11ax_mcs5_2g4=18 +lvl_11ax_mcs6_2g4=16 +lvl_11ax_mcs7_2g4=16 +lvl_11ax_mcs8_2g4=16 +lvl_11ax_mcs9_2g4=16 +lvl_11ax_mcs10_2g4=15 +lvl_11ax_mcs11_2g4=15 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_chan_1_4=0 +ofst_chan_5_9=0 +ofst_chan_10_13=0 +ofst_chan_36_64=0 +ofst_chan_100_120=0 +ofst_chan_122_140=0 +ofst_chan_142_165=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800DC/aic_userconfig_8800dw.txt b/fw/aic8800DC/aic_userconfig_8800dw.txt new file mode 100644 index 0000000..9e4bea6 --- /dev/null +++ b/fw/aic8800DC/aic_userconfig_8800dw.txt @@ -0,0 +1,62 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=20 +lvl_11b_11ag_2m_2g4=20 +lvl_11b_11ag_5m5_2g4=20 +lvl_11b_11ag_11m_2g4=20 +lvl_11b_11ag_6m_2g4=20 +lvl_11b_11ag_9m_2g4=20 +lvl_11b_11ag_12m_2g4=20 +lvl_11b_11ag_18m_2g4=20 +lvl_11b_11ag_24m_2g4=18 +lvl_11b_11ag_36m_2g4=18 +lvl_11b_11ag_48m_2g4=16 +lvl_11b_11ag_54m_2g4=16 +lvl_11n_11ac_mcs0_2g4=20 +lvl_11n_11ac_mcs1_2g4=20 +lvl_11n_11ac_mcs2_2g4=20 +lvl_11n_11ac_mcs3_2g4=20 +lvl_11n_11ac_mcs4_2g4=18 +lvl_11n_11ac_mcs5_2g4=18 +lvl_11n_11ac_mcs6_2g4=16 +lvl_11n_11ac_mcs7_2g4=16 +lvl_11n_11ac_mcs8_2g4=16 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=20 +lvl_11ax_mcs1_2g4=20 +lvl_11ax_mcs2_2g4=20 +lvl_11ax_mcs3_2g4=20 +lvl_11ax_mcs4_2g4=18 +lvl_11ax_mcs5_2g4=18 +lvl_11ax_mcs6_2g4=16 +lvl_11ax_mcs7_2g4=16 +lvl_11ax_mcs8_2g4=16 +lvl_11ax_mcs9_2g4=16 +lvl_11ax_mcs10_2g4=15 +lvl_11ax_mcs11_2g4=15 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_chan_1_4=0 +ofst_chan_5_9=0 +ofst_chan_10_13=0 +ofst_chan_36_64=0 +ofst_chan_100_120=0 +ofst_chan_122_140=0 +ofst_chan_142_165=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800DC/aic_userconfig_8800dw_u2.txt b/fw/aic8800DC/aic_userconfig_8800dw_u2.txt new file mode 100644 index 0000000..868dffb --- /dev/null +++ b/fw/aic8800DC/aic_userconfig_8800dw_u2.txt @@ -0,0 +1,62 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=19 +lvl_11b_11ag_2m_2g4=19 +lvl_11b_11ag_5m5_2g4=19 +lvl_11b_11ag_11m_2g4=19 +lvl_11b_11ag_6m_2g4=19 +lvl_11b_11ag_9m_2g4=19 +lvl_11b_11ag_12m_2g4=19 +lvl_11b_11ag_18m_2g4=19 +lvl_11b_11ag_24m_2g4=18 +lvl_11b_11ag_36m_2g4=18 +lvl_11b_11ag_48m_2g4=16 +lvl_11b_11ag_54m_2g4=16 +lvl_11n_11ac_mcs0_2g4=18 +lvl_11n_11ac_mcs1_2g4=18 +lvl_11n_11ac_mcs2_2g4=18 +lvl_11n_11ac_mcs3_2g4=18 +lvl_11n_11ac_mcs4_2g4=18 +lvl_11n_11ac_mcs5_2g4=18 +lvl_11n_11ac_mcs6_2g4=18 +lvl_11n_11ac_mcs7_2g4=17 +lvl_11n_11ac_mcs8_2g4=16 +lvl_11n_11ac_mcs9_2g4=16 +lvl_11ax_mcs0_2g4=17 +lvl_11ax_mcs1_2g4=17 +lvl_11ax_mcs2_2g4=17 +lvl_11ax_mcs3_2g4=17 +lvl_11ax_mcs4_2g4=17 +lvl_11ax_mcs5_2g4=17 +lvl_11ax_mcs6_2g4=16 +lvl_11ax_mcs7_2g4=16 +lvl_11ax_mcs8_2g4=16 +lvl_11ax_mcs9_2g4=16 +lvl_11ax_mcs10_2g4=15 +lvl_11ax_mcs11_2g4=15 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_chan_1_4=0 +ofst_chan_5_9=0 +ofst_chan_10_13=0 +ofst_chan_36_64=0 +ofst_chan_100_120=0 +ofst_chan_122_140=0 +ofst_chan_142_165=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800DC/aic_userconfig_8800dw_w311.txt b/fw/aic8800DC/aic_userconfig_8800dw_w311.txt new file mode 100644 index 0000000..13154ef --- /dev/null +++ b/fw/aic8800DC/aic_userconfig_8800dw_w311.txt @@ -0,0 +1,62 @@ +# AIC USERCONFIG 2022/0803/1707 + +# txpwr_lvl +enable=1 +lvl_11b_11ag_1m_2g4=21 +lvl_11b_11ag_2m_2g4=21 +lvl_11b_11ag_5m5_2g4=21 +lvl_11b_11ag_11m_2g4=21 +lvl_11b_11ag_6m_2g4=21 +lvl_11b_11ag_9m_2g4=21 +lvl_11b_11ag_12m_2g4=21 +lvl_11b_11ag_18m_2g4=21 +lvl_11b_11ag_24m_2g4=21 +lvl_11b_11ag_36m_2g4=20 +lvl_11b_11ag_48m_2g4=19 +lvl_11b_11ag_54m_2g4=19 +lvl_11n_11ac_mcs0_2g4=21 +lvl_11n_11ac_mcs1_2g4=21 +lvl_11n_11ac_mcs2_2g4=21 +lvl_11n_11ac_mcs3_2g4=21 +lvl_11n_11ac_mcs4_2g4=21 +lvl_11n_11ac_mcs5_2g4=20 +lvl_11n_11ac_mcs6_2g4=19 +lvl_11n_11ac_mcs7_2g4=19 +lvl_11n_11ac_mcs8_2g4=18 +lvl_11n_11ac_mcs9_2g4=18 +lvl_11ax_mcs0_2g4=21 +lvl_11ax_mcs1_2g4=21 +lvl_11ax_mcs2_2g4=21 +lvl_11ax_mcs3_2g4=21 +lvl_11ax_mcs4_2g4=21 +lvl_11ax_mcs5_2g4=20 +lvl_11ax_mcs6_2g4=19 +lvl_11ax_mcs7_2g4=19 +lvl_11ax_mcs8_2g4=18 +lvl_11ax_mcs9_2g4=18 +lvl_11ax_mcs10_2g4=17 +lvl_11ax_mcs11_2g4=17 + +# txpwr_loss +loss_enable_2g4=0 +loss_value_2g4=2 +loss_enable_5g=0 +loss_value_5g=5 + +# txpwr_ofst +ofst_enable=0 +ofst_chan_1_4=0 +ofst_chan_5_9=0 +ofst_chan_10_13=0 +ofst_chan_36_64=0 +ofst_chan_100_120=0 +ofst_chan_122_140=0 +ofst_chan_142_165=0 + +# xtal cap +xtal_enable=0 +xtal_cap=24 +xtal_cap_fine=31 + + + diff --git a/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin new file mode 100644 index 0000000..a067e5a Binary files /dev/null and b/fw/aic8800DC/fmacfw_calib_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin b/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin new file mode 100644 index 0000000..7fdf39a Binary files /dev/null and b/fw/aic8800DC/fmacfw_calib_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin new file mode 100644 index 0000000..69a64e6 Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_8800dc_ipc_u02.bin b/fw/aic8800DC/fmacfw_patch_8800dc_ipc_u02.bin new file mode 100644 index 0000000..819be58 Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_8800dc_ipc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin b/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin new file mode 100644 index 0000000..ccb91b3 Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin new file mode 100644 index 0000000..1265375 Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_h_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_ipc_u02.bin b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_ipc_u02.bin new file mode 100644 index 0000000..df2573d Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_ipc_u02.bin differ diff --git a/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin new file mode 100644 index 0000000..5461565 Binary files /dev/null and b/fw/aic8800DC/fmacfw_patch_tbl_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_adid_8800dc_u02.bin b/fw/aic8800DC/fw_adid_8800dc_u02.bin new file mode 100644 index 0000000..3e90e35 Binary files /dev/null and b/fw/aic8800DC/fw_adid_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_adid_8800dc_u02h.bin b/fw/aic8800DC/fw_adid_8800dc_u02h.bin new file mode 100644 index 0000000..e3bc1f0 Binary files /dev/null and b/fw/aic8800DC/fw_adid_8800dc_u02h.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02.bin b/fw/aic8800DC/fw_patch_8800dc_u02.bin new file mode 100644 index 0000000..0d6131f Binary files /dev/null and b/fw/aic8800DC/fw_patch_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin b/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin new file mode 100644 index 0000000..ca18b59 Binary files /dev/null and b/fw/aic8800DC/fw_patch_8800dc_u02_ext0.bin differ diff --git a/fw/aic8800DC/fw_patch_8800dc_u02h.bin b/fw/aic8800DC/fw_patch_8800dc_u02h.bin new file mode 100644 index 0000000..8e48ba8 Binary files /dev/null and b/fw/aic8800DC/fw_patch_8800dc_u02h.bin differ diff --git a/fw/aic8800DC/fw_patch_table_8800dc_u02.bin b/fw/aic8800DC/fw_patch_table_8800dc_u02.bin new file mode 100644 index 0000000..c56a80e Binary files /dev/null and b/fw/aic8800DC/fw_patch_table_8800dc_u02.bin differ diff --git a/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin b/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin new file mode 100644 index 0000000..eb7aae1 Binary files /dev/null and b/fw/aic8800DC/fw_patch_table_8800dc_u02h.bin differ diff --git a/fw/aic8800DC/lmacfw_rf_8800dc.bin b/fw/aic8800DC/lmacfw_rf_8800dc.bin new file mode 100644 index 0000000..1373376 Binary files /dev/null and b/fw/aic8800DC/lmacfw_rf_8800dc.bin differ