mirror of
https://github.com/shenmintao/aic8800d80.git
synced 2026-11-10 16:49:17 +00:00
feat: update new aic driver version
This commit is contained in:
1 parent
99210d657b
commit
3800c225ac
101 files changed
+12814
-4038
No files matched your search
@@ -0,0 +1,10 @@
|
||||
*.o
|
||||
*.ko
|
||||
*.order
|
||||
*.symvers
|
||||
*.o.d
|
||||
*.o.cmd
|
||||
*.ko.cmd
|
||||
*.mod
|
||||
*.mod.c
|
||||
*.mod.cmd
|
||||
@@ -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
|
||||
|
||||
@@ -11,16 +11,31 @@
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/ctype.h>
|
||||
#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 <linux/ctype.h>
|
||||
@@ -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> 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,
|
||||
"<func> <freq> <tx_pwr> = use pll test to measure saturation power" },
|
||||
{ "set_ant", aic_priv_cmd_set_ant_mode,
|
||||
"<val> = 0/ant0, 1/ant1, 2/both" },
|
||||
{ "rdwr_bt_efuse_pwrofst", aic_priv_cmd_rdwr_bt_efuse_pwrofst,
|
||||
"<pwrofst> = read/write bt tx power offset into efuse" },
|
||||
{ "exec_flash_oper",aic_priv_cmd_exec_flash_oper,
|
||||
"<val> = 0 check, 1 rec, 2 prot 3 rd_wcr0 4 er_wcr0 "},
|
||||
{"country_set", aic_priv_cmd_country_set, "<ccode>"},
|
||||
{"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);
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2020 AIC semiconductor.
|
||||
*
|
||||
* @file aicwf_manager.c
|
||||
*
|
||||
* @brief netlink msg definitions
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <net/sock.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef _AICWF_STEERING_H_
|
||||
#define _AICWF_STEERING_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
|
||||
+2208
-2204
File diff suppressed because it is too large.
Load diff
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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 <RSSI_THD_0
|
||||
#define PWR_LOSS_LVL2 (0) //RSSI_THD_2 < RSSI <RSSI_THD_1
|
||||
#define PWR_LOSS_LVL3 (0)//(2) //RSSI <RSSI_THD_2
|
||||
|
||||
#define PWR_DELAY_TIME (10 * 1000) //pwr reduced latency time (ms)
|
||||
|
||||
struct rwnx_sta *rwnx_retrieve_sta(struct rwnx_hw *rwnx_hw,
|
||||
struct rwnx_vif *rwnx_vif, u8 *addr,
|
||||
__le16 fc, bool ap);
|
||||
|
||||
|
||||
#ifdef CONFIG_BAND_STEERING
|
||||
void aicwf_steering_work(struct work_struct *work);
|
||||
#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
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_PERPWR
|
||||
void rssi_update_txpwrloss(struct rwnx_sta *sta, s8_l rssi);
|
||||
void aicwf_txpwer_per_sta_worker(struct work_struct *work);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_PWR
|
||||
void set_txpwrloss_ctrl(struct rwnx_hw *rwnx_hw, s8 value);
|
||||
void aicwf_pwrloss_worker(struct work_struct *work);
|
||||
#endif
|
||||
|
||||
#endif /* _RWNX_MAIN_H_ */
|
||||
@@ -27,6 +27,8 @@
|
||||
#define FULLMAC_PARAM(name, default) .name = default,
|
||||
#endif /* CONFIG_RWNX_FULLMAC */
|
||||
|
||||
extern int reg_regdb_size;
|
||||
|
||||
struct rwnx_mod_params rwnx_mod_params = {
|
||||
/* common parameters */
|
||||
COMMON_PARAM(ht_on, true, true)
|
||||
@@ -44,8 +46,8 @@ struct rwnx_mod_params rwnx_mod_params = {
|
||||
COMMON_PARAM(sgi, true, true)
|
||||
COMMON_PARAM(sgi80, true, true)
|
||||
COMMON_PARAM(use_2040, 1, 1)
|
||||
COMMON_PARAM(nss, 1, 1)
|
||||
COMMON_PARAM(amsdu_rx_max, 2, 2)
|
||||
COMMON_PARAM(nss, 2, 2)
|
||||
COMMON_PARAM(amsdu_rx_max, 1, 1)
|
||||
COMMON_PARAM(bfmee, true, true)
|
||||
COMMON_PARAM(bfmer, false, false)
|
||||
COMMON_PARAM(mesh, true, true)
|
||||
@@ -355,7 +357,7 @@ struct ieee80211_regdomain *getRegdomainFromRwnxDB(struct wiphy *wiphy,
|
||||
|
||||
idx = 0;
|
||||
|
||||
while (reg_regdb[idx]){
|
||||
while (reg_regdb[idx] && idx < reg_regdb_size){
|
||||
if((reg_regdb[idx]->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;
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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; i<pulses->cnt; 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)] = {
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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_ */
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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);
|
||||
|
||||
@@ -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; k<RWNX_RADARR_DUMP_NB; k++) {
|
||||
AICWFDBG(LOGINFO, "\t %2d: %8x %10llu %10llu\n", rm->idx, 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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)
|
||||
|
||||
@@ -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)] = {
|
||||
|
||||
@@ -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 <net/ieee80211_radiotap.h>
|
||||
#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);
|
||||
|
||||
@@ -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_ */
|
||||
@@ -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"
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/platform_device.h>
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#else
|
||||
#include <linux/pm_wakeup.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef __RWNX_WAKELOCK_H
|
||||
#define __RWNX_WAKELOCK_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
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
|
||||
Reference in new issue
Block a user