merge aic800 driver from android
This commit is contained in:
parent
fce40362dc
commit
9e6beaa2e4
@ -10,6 +10,8 @@ obj-m := aic8800_bsp.o
|
||||
aic8800_bsp-y := \
|
||||
aic_bsp_main.o \
|
||||
aic_bsp_driver.o \
|
||||
aic_bsp_8800d.o \
|
||||
aic_bsp_8800dc.o \
|
||||
aicsdio.o \
|
||||
aicsdio_txrxif.o
|
||||
|
||||
|
||||
336
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_8800d.c
Normal file
336
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_8800d.c
Normal file
@ -0,0 +1,336 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* aic_bsp_8800d.c
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2014-2019
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "aicsdio_txrxif.h"
|
||||
#include "aicsdio.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
#define RAM_FMAC_FW_ADDR 0x00120000
|
||||
#define FW_RAM_ADID_BASE_ADDR 0x00161928
|
||||
#define FW_RAM_ADID_BASE_ADDR_U03 0x00161928
|
||||
#define FW_RAM_PATCH_BASE_ADDR 0x00100000
|
||||
|
||||
static u32 patch_tbl[][2] = {
|
||||
};
|
||||
|
||||
static u32 syscfg_tbl_masked[][3] = {
|
||||
{0x40506024, 0x000000FF, 0x000000DF}, // for clk gate lp_level
|
||||
};
|
||||
|
||||
static u32 rf_tbl_masked[][3] = {
|
||||
{0x40344058, 0x00800000, 0x00000000},// pll trx
|
||||
};
|
||||
|
||||
static u32 aicbsp_syscfg_tbl[][2] = {
|
||||
{0x40500014, 0x00000101}, // 1)
|
||||
{0x40500018, 0x00000109}, // 2)
|
||||
{0x40500004, 0x00000010}, // 3) the order should not be changed
|
||||
|
||||
// def CONFIG_PMIC_SETTING
|
||||
// U02 bootrom only
|
||||
{0x40040000, 0x00001AC8}, // 1) fix panic
|
||||
{0x40040084, 0x00011580},
|
||||
{0x40040080, 0x00000001},
|
||||
{0x40100058, 0x00000000},
|
||||
|
||||
{0x50000000, 0x03220204}, // 2) pmic interface init
|
||||
{0x50019150, 0x00000002}, // 3) for 26m xtal, set div1
|
||||
{0x50017008, 0x00000000}, // 4) stop wdg
|
||||
};
|
||||
|
||||
static const struct aicbsp_firmware fw_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u02)",
|
||||
.bt_adid = "fw_adid.bin",
|
||||
.bt_patch = "fw_patch.bin",
|
||||
.bt_table = "fw_patch_table.bin",
|
||||
.wl_fw = "fmacfw.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u02)",
|
||||
.bt_adid = "fw_adid.bin",
|
||||
.bt_patch = "fw_patch.bin",
|
||||
.bt_table = "fw_patch_table.bin",
|
||||
.wl_fw = "fmacfw_rf.bin"
|
||||
},
|
||||
};
|
||||
|
||||
static const struct aicbsp_firmware fw_u03[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u03/u04)",
|
||||
.bt_adid = "fw_adid_u03.bin",
|
||||
.bt_patch = "fw_patch_u03.bin",
|
||||
.bt_table = "fw_patch_table_u03.bin",
|
||||
.wl_fw = "fmacfw.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u03/u04)",
|
||||
.bt_adid = "fw_adid_u03.bin",
|
||||
.bt_patch = "fw_patch_u03.bin",
|
||||
.bt_table = "fw_patch_table_u03.bin",
|
||||
.wl_fw = "fmacfw_rf.bin"
|
||||
},
|
||||
};
|
||||
|
||||
static int aicbt_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
struct aicbt_info_t btcfg = {
|
||||
.btmode = AICBT_BTMODE_DEFAULT,
|
||||
.btport = AICBT_BTPORT_DEFAULT,
|
||||
.uart_baud = AICBT_UART_BAUD_DEFAULT,
|
||||
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
|
||||
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
|
||||
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
|
||||
};
|
||||
|
||||
struct aicbt_patch_table *head = aicbt_patch_table_alloc(aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
|
||||
int ret = aicbt_patch_info_unpack(head, &btcfg);
|
||||
|
||||
if (head == NULL)
|
||||
return -1;
|
||||
|
||||
if (ret) {
|
||||
btcfg.addr_adid = FW_RAM_ADID_BASE_ADDR;
|
||||
btcfg.addr_patch = FW_RAM_PATCH_BASE_ADDR;
|
||||
if (aicbsp_info.chipinfo->rev != CHIP_REV_U02)
|
||||
btcfg.addr_adid = FW_RAM_ADID_BASE_ADDR_U03;
|
||||
}
|
||||
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, btcfg.addr_adid, aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, btcfg.addr_patch, aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = aicbt_patch_table_load(sdiodev, &btcfg, head);
|
||||
if (ret)
|
||||
printk("aicbt_patch_table_load fail\n");
|
||||
|
||||
err:
|
||||
aicbt_patch_table_free(&head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aicwifi_start_from_bootrom(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* memory access */
|
||||
const u32 fw_addr = RAM_FMAC_FW_ADDR;
|
||||
struct dbg_start_app_cfm start_app_cfm;
|
||||
|
||||
/* fw start */
|
||||
ret = rwnx_send_dbg_start_app_req(sdiodev, fw_addr, HOST_START_APP_AUTO, &start_app_cfm);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
aicbsp_info.hwinfo_r = start_app_cfm.bootstatus & 0xFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwifi_sys_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret, cnt;
|
||||
int syscfg_num = sizeof(syscfg_tbl_masked) / sizeof(u32) / 3;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
syscfg_tbl_masked[cnt][0], syscfg_tbl_masked[cnt][1], syscfg_tbl_masked[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
rf_tbl_masked[0][0], rf_tbl_masked[0][1], rf_tbl_masked[0][2]);
|
||||
if (ret) {
|
||||
printk("rf config %x write fail: %d\n", rf_tbl_masked[0][0], ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwifi_patch_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
const u32 rd_patch_addr = RAM_FMAC_FW_ADDR + 0x0180;
|
||||
u32 config_base;
|
||||
uint32_t start_addr = 0x1e6000;
|
||||
u32 patch_addr = start_addr;
|
||||
u32 patch_num = sizeof(patch_tbl)/4;
|
||||
struct dbg_mem_read_cfm rd_patch_addr_cfm;
|
||||
int ret = 0;
|
||||
u16 cnt = 0;
|
||||
u32 patch_addr_reg = 0x1e5318;
|
||||
u32 patch_num_reg = 0x1e531c;
|
||||
|
||||
if (aicbsp_info.cpmode == AICBSP_CPMODE_TEST) {
|
||||
patch_addr_reg = 0x1e5304;
|
||||
patch_num_reg = 0x1e5308;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_patch_addr, &rd_patch_addr_cfm);
|
||||
if (ret) {
|
||||
printk("patch rd fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
config_base = rd_patch_addr_cfm.memdata;
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_addr_reg, patch_addr);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", patch_addr_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_num_reg, patch_num);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", patch_num_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < patch_num/2; cnt += 1) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, patch_tbl[cnt][0]+config_base);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt+4, patch_tbl[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt+4);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwifi_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) {
|
||||
printk("download wifi fw fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_patch_config(sdiodev)) {
|
||||
printk("aicwifi_patch_config fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_sys_config(sdiodev)) {
|
||||
printk("aicwifi_sys_config fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_start_from_bootrom(sdiodev)) {
|
||||
printk("wifi start fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicbsp_system_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int syscfg_num = sizeof(aicbsp_syscfg_tbl) / sizeof(u32) / 2;
|
||||
int ret, cnt;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, aicbsp_syscfg_tbl[cnt][0], aicbsp_syscfg_tbl[cnt][1]);
|
||||
if (ret) {
|
||||
sdio_err("%x write fail: %d\n", aicbsp_syscfg_tbl[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicbsp_8800d_fw_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
const u32 mem_addr = 0x40500000;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
|
||||
uint8_t binding_status;
|
||||
uint8_t dout[16];
|
||||
|
||||
need_binding_verify = false;
|
||||
aicbsp_firmware_list = fw_u02;
|
||||
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
|
||||
aicbsp_info.chipinfo->rev = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||
if (aicbsp_info.chipinfo->rev != CHIP_REV_U02 &&
|
||||
aicbsp_info.chipinfo->rev != CHIP_REV_U03 &&
|
||||
aicbsp_info.chipinfo->rev != CHIP_REV_U04) {
|
||||
pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chipinfo->rev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("aicbsp: %s, chip rev: %d\n", __func__, aicbsp_info.chipinfo->rev);
|
||||
|
||||
if (aicbsp_info.chipinfo->rev != CHIP_REV_U02)
|
||||
aicbsp_firmware_list = fw_u03;
|
||||
|
||||
if (aicbsp_system_config(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (aicbt_init(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (aicwifi_init(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (need_binding_verify) {
|
||||
printk("aicbsp: crypto data %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
binding_enc_data[0], binding_enc_data[1], binding_enc_data[2], binding_enc_data[3],
|
||||
binding_enc_data[4], binding_enc_data[5], binding_enc_data[6], binding_enc_data[7],
|
||||
binding_enc_data[8], binding_enc_data[9], binding_enc_data[10], binding_enc_data[11],
|
||||
binding_enc_data[12], binding_enc_data[13], binding_enc_data[14], binding_enc_data[15]);
|
||||
|
||||
/* calculate verify data from crypto data */
|
||||
if (wcn_bind_verify_calculate_verify_data(binding_enc_data, dout)) {
|
||||
pr_err("aicbsp: %s, binding encrypt data incorrect\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("aicbsp: verify data %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
dout[0], dout[1], dout[2], dout[3],
|
||||
dout[4], dout[5], dout[6], dout[7],
|
||||
dout[8], dout[9], dout[10], dout[11],
|
||||
dout[12], dout[13], dout[14], dout[15]);
|
||||
|
||||
if (rwnx_send_dbg_binding_req(sdiodev, dout, &binding_status)) {
|
||||
pr_err("aicbsp: %s, send binding request failn", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (binding_status) {
|
||||
pr_err("aicbsp: %s, binding verify fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_WAKEUP_REG, 4)) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_WAKEUP_REG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
791
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_8800dc.c
Normal file
791
drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_8800dc.c
Normal file
@ -0,0 +1,791 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* aic_bsp_8800dc.c
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2014-2019
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "aicsdio_txrxif.h"
|
||||
#include "aicsdio.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
#define RAM_LMAC_FW_ADDR 0x00150000
|
||||
#define RAM_FMAC_FW_ADDR 0x00120000
|
||||
#define ROM_FMAC_PATCH_ADDR 0x00180000
|
||||
#define RAM_8800DC_ADID_ADDR 0x001017d8
|
||||
#define RAM_8800DC_FW_PATCH_ADDR 0x00184000
|
||||
#define RF_PATCH_NAME_8800DC "aic8800dc/fmacfw_rf_patch.bin"
|
||||
|
||||
typedef u32 (*array2_tbl_t)[2];
|
||||
|
||||
static u32 syscfg_tbl_masked_8800dc[][3] = {
|
||||
//#ifdef CONFIG_PMIC_SETTING
|
||||
#if defined(CONFIG_VRF_DCDC_MODE)
|
||||
{0x7000216C, (0x3 << 2), (0x1 << 2)}, // pmic_pmu_init
|
||||
{0x700021BC, (0x3 << 2), (0x1 << 2)},
|
||||
{0x70002118, ((0x7 << 4) | (0x1 << 7)), ((0x2 << 4) | (0x1 << 7))},
|
||||
{0x70002104, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))},
|
||||
{0x7000210C, ((0x3F << 0) | (0x1 << 6)), ((0x2 << 0) | (0x1 << 6))},
|
||||
{0x70002190, (0x3F << 0), (24 << 0)},
|
||||
{0x700021CC, ((0x7 << 4) | (0x1 << 7)), ((0x0 << 4) | (0x0 << 7))},
|
||||
{0x700010A0, (0x1 << 11), (0x1 << 11)},
|
||||
{0x70001038, (0x1 << 8), (0x1 << 8)},
|
||||
{0x70001094, (0x3 << 2), (0x0 << 2)},
|
||||
{0x700021D0, ((0x1 << 5) | (0x1 << 6)), ((0x1 << 5) | (0x1 << 6))},
|
||||
{0x70001000, ((0x1 << 0) | (0x1 << 20) | (0x1 << 22)),
|
||||
((0x1 << 0) | (0x1 << 20) | (0x0 << 22))},
|
||||
#endif
|
||||
//#endif /* CONFIG_PMIC_SETTING */
|
||||
{0x00000000, 0x00000000, 0x00000000}, // last one
|
||||
};
|
||||
|
||||
static u32 syscfg_tbl_masked_8800dc_u01[][3] = {
|
||||
//#ifdef CONFIG_PMIC_SETTING
|
||||
{0x70001000, (0x1 << 16), (0x1 << 16)}, // for low temperature
|
||||
{0x70001028, (0x1 << 6), (0x1 << 6)},
|
||||
{0x70001000, (0x1 << 16), (0x0 << 16)},
|
||||
//#endif /* CONFIG_PMIC_SETTING */
|
||||
};
|
||||
|
||||
static u32 syscfg_tbl_8800dc[][2] = {
|
||||
{0x40500010, 0x00000004},
|
||||
{0x40500010, 0x00000006},//160m clk
|
||||
};
|
||||
|
||||
static u32 syscfg_tbl_8800dc_sdio_u01[][2] = {
|
||||
{0x40030000, 0x00036724}, // loop forever after assert_err
|
||||
{0x0011E800, 0xE7FE4070},
|
||||
{0x40030084, 0x0011E800},
|
||||
{0x40030080, 0x00000001},
|
||||
{0x4010001C, 0x00000000},
|
||||
};
|
||||
|
||||
static u32 syscfg_tbl_8800dc_sdio_u02[][2] = {
|
||||
{0x40030000, 0x00036DA4}, // loop forever after assert_err
|
||||
{0x0011E800, 0xE7FE4070},
|
||||
{0x40030084, 0x0011E800},
|
||||
{0x40030080, 0x00000001},
|
||||
{0x4010001C, 0x00000000},
|
||||
};
|
||||
|
||||
static u32 patch_tbl_wifisetting_8800dc_u01[][2] = {
|
||||
{0x010c, 0x01001E01}
|
||||
};
|
||||
|
||||
static u32 patch_tbl_wifisetting_8800dc_u02[][2] = {
|
||||
{0x0124, 0x01001E01}
|
||||
};
|
||||
|
||||
static u32 jump_tbl[][2] = {
|
||||
#ifndef CONFIG_FOR_IPCOM
|
||||
{296, 0x180001},
|
||||
{137, 0x180011},
|
||||
{303, 0x1810f9},
|
||||
{168, 0x18186d},
|
||||
{308, 0x181bbd},
|
||||
{288, 0x1820c1},
|
||||
#else
|
||||
{308, 0x181001},
|
||||
{288, 0x181031},
|
||||
{296, 0x18120d},
|
||||
{137, 0x18121d},
|
||||
{303, 0x182305},
|
||||
{168, 0x182a79},
|
||||
{258, 0x182ae1},
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint32_t ldpc_cfg_ram[] = {
|
||||
#ifdef CONFIG_FPGA_VERIFICATION
|
||||
0x00363638, 0x1DF8F834, 0x1DF8F834, 0x1DF8F834, 0x1DF8F834, 0x002F2F31, 0x1DF8F82C, 0x1DF8F82C,
|
||||
0x1DF8F82C, 0x1DF8F82C, 0x00363639, 0x1AA5F834, 0x1AA5F834, 0x1ADEF834, 0x1ADEF834, 0x003A3A3E,
|
||||
0x1578F436, 0x1578F436, 0x1578F436, 0x15B6F436, 0x003B3B40, 0x1DF8F838, 0x1DF8F838, 0x1DF8F838,
|
||||
0x1DF8F838, 0x003B3B41, 0x1DC4F838, 0x1DC4F838, 0x1DF8F838, 0x1DF8F838, 0x003B3B40, 0x1781F838,
|
||||
0x1781F838, 0x1781F838, 0x17C4F838, 0x003B3B40, 0x0E81F838, 0x0E81F838, 0x0E81F838, 0x0E82F838,
|
||||
0x003F3F43, 0x1A92F83D, 0x1A92F83E, 0x1A92F83D, 0x1ADDF83D, 0x00272729, 0x1DF8F824, 0x1DF8F824,
|
||||
0x1DF8F843, 0x1DF8F843, 0x00272729, 0x1DF8F824, 0x1DF8F824, 0x1DF8F842, 0x1DF8F842, 0x00262628,
|
||||
0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x00252528, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823,
|
||||
0x1DF8F823, 0x00262628, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x00242427, 0x1DF8F821,
|
||||
0x1DF8F821, 0x1DF8F821, 0x1DF8F821, 0x00232326, 0x1DF8F821, 0x1DF8F820, 0x1DF8F820, 0x1DF8F820,
|
||||
0x00262628, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823, 0x00242427, 0x1DF8F821, 0x1DF8F821,
|
||||
0x1DF8F821, 0x1DF8F821, 0x001F1F21, 0x1DF8F81D, 0x1DF8F81D, 0x1DF8F81D, 0x1DF8F81D, 0x00262643,
|
||||
0x1DF8F822, 0x1DF8F821, 0x1DF8F821, 0x1DF8F821, 0x0018182B, 0x1DF8F816, 0x1DBDF815, 0x1DF8F815,
|
||||
0x1DF8F815, 0x0018182A, 0x1195F836, 0x1195F815, 0x1195F815, 0x1196F815, 0x0028282C, 0x1DF8F824,
|
||||
0x1DF8F824, 0x1DF8F824, 0x1DF8F824, 0x0027272C, 0x1DF8F824, 0x1DF8F823, 0x1DF8F823, 0x1DF8F823,
|
||||
0x0082824A, 0x1ADFF841, 0x1ADDF822, 0x1ADEF822, 0x1ADFF822, 0x003E3E40, 0x09D1F81D, 0x095BF81D,
|
||||
0x095BF81D, 0x095BF81D, 0x0029292D, 0x1DF8F825, 0x1DF8F825, 0x1DF8F825, 0x1DF8F825, 0x0028282C,
|
||||
0x1DF8F824, 0x1DF8F824, 0x1DF8F824, 0x1DF8F824, 0x0029292D, 0x1DF8F825, 0x1DF8F825, 0x1DF8F825,
|
||||
0x1DF8F825, 0x0028282E, 0x1DF8F825, 0x1DF8F824, 0x1DF8F824, 0x1DF8F824, 0x0026262C, 0x1DF8F823,
|
||||
0x1DF8F822, 0x1DF8F822, 0x1DF8F822, 0x0028282D, 0x1DF8F825, 0x1DF8F824, 0x1DF8F824, 0x1DF8F824,
|
||||
0x00282852, 0x1DF8F827, 0x1DF8F824, 0x1DF8F824, 0x1DF8F824, 0x0029294E, 0x1DF8F823, 0x1DF8F822,
|
||||
0x1DF8F822, 0x1DF8F822, 0x00212143, 0x1DF8F821, 0x1DECF81D, 0x1DF4F81D, 0x1DF8F81D, 0x0086864D,
|
||||
0x1CF0F844, 0x1CEDF823, 0x1CEFF822, 0x1CF0F822, 0x0047474D, 0x1BE8F823, 0x1BE8F823, 0x1BE9F822,
|
||||
0x1BEAF822, 0x0018182F, 0x14B0F83C, 0x14B0F814, 0x14B0F814, 0x14B0F814, 0x00404040, 0x0AE1F81E,
|
||||
0x0A61F81D, 0x0A61F81D, 0x0A61F81D, 0x002C2C40, 0x09555526, 0x09555512, 0x09555513, 0x09555512,
|
||||
0x00181840, 0x06333329, 0x06333314, 0x06333314, 0x06333314, 0x002B2B2F, 0x1DF8F828, 0x1DF8F828,
|
||||
0x1DF8F828, 0x1DF8F828, 0x002B2B32, 0x1DF8F829, 0x1DF8F828, 0x1DF8F828, 0x1DF8F828, 0x002A2A2F,
|
||||
0x1DF8F827, 0x1DF8F827, 0x1DF8F827, 0x1DF8F827, 0x002A2A57, 0x1DF8F82B, 0x1DF8F827, 0x1DF8F827,
|
||||
0x1DF8F827, 0x00919152, 0x1DF8F84B, 0x1DF8F825, 0x1DF8F825, 0x1DF8F825, 0x004C4C51, 0x1DF8F826,
|
||||
0x1DF8F825, 0x1DF8F825, 0x1DF8F825, 0x00444440, 0x0CF8F820, 0x0C6EF81F, 0x0C6EF81F, 0x0C6EF81F,
|
||||
0x00424240, 0x0D75753E, 0x0D75751E, 0x0D75751E, 0x0D75751E, 0x00191940, 0x0539392E, 0x05393914,
|
||||
0x05393914, 0x05393914, 0x002F2F32, 0x1AA5F82C, 0x1AA5F82C, 0x1ADEF82C, 0x1ADEF82C, 0x002F2F40,
|
||||
0x0C6EDE2C, 0x0C6EDE2C, 0x0C6EDE2C, 0x0C6EDE2C, 0x00323240, 0x053BB62E, 0x053BB62E, 0x053BB62E,
|
||||
0x053BB62E, 0x00333339, 0x1DC4F82F, 0x1DC4F82F, 0x1DF8F82F, 0x1DF8F82F, 0x00333340, 0x0E81F82F,
|
||||
0x0E81F82F, 0x0E81F82F, 0x0E82F82F, 0x00333340, 0x063FC42F, 0x063FC42F, 0x063FC42F, 0x063FC42F,
|
||||
0x00404040, 0x063FC42F, 0x063FC42F, 0x063FC42F, 0x063FC42F, 0x00363640, 0x0747DD33, 0x0747DD33,
|
||||
0x0747DD33, 0x0747DD33, 0x00404040, 0x0747DD33, 0x0747DD33, 0x0747DD33, 0x0747DD33, 0x00292940,
|
||||
0x07484825, 0x07484812, 0x07484812, 0x07484812, 0x00404040, 0x07343428, 0x07343414, 0x07343414,
|
||||
0x07343414, 0x00404040, 0x0538382A, 0x05383814, 0x05383814, 0x05383814, 0x00404040, 0x05292914,
|
||||
0x05292909, 0x05292909, 0x05292909, 0x000B0B40, 0x02111108, 0x0211110E, 0x02111108, 0x02111108,
|
||||
0x00404040, 0x063E3E2E, 0x063E3E15, 0x063E3E14, 0x063E3E14, 0x00404040, 0x062E2E14, 0x062E2E09,
|
||||
0x062E2E09, 0x062E2E09, 0x000B0B40, 0x02131308, 0x0213130F, 0x02131308, 0x02131308,
|
||||
#else
|
||||
0x00767679, 0x1DF8F870, 0x1DF8F870, 0x1DF8F870, 0x1DF8F870, 0x006E6E72, 0x1DF8F869, 0x1DF8F869,
|
||||
0x1DF8F869, 0x1DF8F869, 0x0076767B, 0x1DF8F870, 0x1DF8F870, 0x1DF8F870, 0x1DF8F870, 0x007E7E85,
|
||||
0x1DF4F876, 0x1DF4F876, 0x1DF4F876, 0x1DF8F876, 0x0081818A, 0x1DF8F87B, 0x1DF8F87B, 0x1DF8F87B,
|
||||
0x1DF8F87B, 0x0081818D, 0x1DF8F87B, 0x1DF8F87B, 0x1DF8F87B, 0x1DF8F87B, 0x0081818A, 0x1DF8F87B,
|
||||
0x1DF8F87C, 0x1DF8F87B, 0x1DF8F87B, 0x007E7E40, 0x1DF8F87B, 0x1DF8F87B, 0x1DF8F87B, 0x1DF8F87B,
|
||||
0x008B8B92, 0x1DF8F887, 0x1DF8F889, 0x1DF8F887, 0x1DF8F887, 0x00515155, 0x1DF8F84C, 0x1DF8F84C,
|
||||
0x1DF8F889, 0x1DF8F889, 0x00515154, 0x1DF8F84C, 0x1DF8F84C, 0x1DF8F888, 0x1DF8F888, 0x004F4F53,
|
||||
0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x004F4F53, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A,
|
||||
0x1DF8F84A, 0x004F4F53, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x004E4E53, 0x1DF8F849,
|
||||
0x1DF8F848, 0x1DF8F848, 0x1DF8F848, 0x004D4D52, 0x1DF8F847, 0x1DF8F847, 0x1DF8F847, 0x1DF8F847,
|
||||
0x004F4F55, 0x1DF8F84B, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x004E4E53, 0x1DF8F849, 0x1DF8F848,
|
||||
0x1DF8F848, 0x1DF8F848, 0x0049494D, 0x1DF8F844, 0x1DF8F844, 0x1DF8F844, 0x1DF8F844, 0x0051518F,
|
||||
0x1DF8F849, 0x1DF8F848, 0x1DF8F848, 0x1DF8F848, 0x00424277, 0x1DF8F83F, 0x1DF8F83C, 0x1DF8F83C,
|
||||
0x1DF8F83C, 0x00424275, 0x1DF8F89E, 0x1DF8F83C, 0x1DF8F83C, 0x1DF8F83C, 0x0055555C, 0x1DF8F84C,
|
||||
0x1DF8F84C, 0x1DF8F84C, 0x1DF8F84C, 0x0053535C, 0x1DF8F84C, 0x1DF8F84B, 0x1DF8F84B, 0x1DF8F84B,
|
||||
0x00F8F89E, 0x1DF8F88C, 0x1DF8F84A, 0x1DF8F84A, 0x1DF8F84A, 0x00898940, 0x18F8F846, 0x18CFF845,
|
||||
0x18CFF844, 0x18CFF844, 0x0056565F, 0x1DF8F84F, 0x1DF8F84F, 0x1DF8F84F, 0x1DF8F84F, 0x0055555E,
|
||||
0x1DF8F84E, 0x1DF8F84E, 0x1DF8F84E, 0x1DF8F84E, 0x0056565F, 0x1DF8F84F, 0x1DF8F84F, 0x1DF8F84F,
|
||||
0x1DF8F84F, 0x00555561, 0x1DF8F850, 0x1DF8F84E, 0x1DF8F84E, 0x1DF8F84E, 0x0053535F, 0x1DF8F84D,
|
||||
0x1DF8F84C, 0x1DF8F84C, 0x1DF8F84C, 0x0055555F, 0x1DF8F84F, 0x1DF8F84E, 0x1DF8F84E, 0x1DF8F84E,
|
||||
0x005555AA, 0x1DF8F854, 0x1DF8F84E, 0x1DF8F84E, 0x1DF8F84E, 0x005959A6, 0x1DF8F84D, 0x1DF8F84C,
|
||||
0x1DF8F84C, 0x1DF8F84C, 0x004F4F9B, 0x1DF8F84E, 0x1DF8F846, 0x1DF8F846, 0x1DF8F846, 0x00F8F8A5,
|
||||
0x1DF8F894, 0x1DF8F84C, 0x1DF8F84C, 0x1DF8F84C, 0x009898A4, 0x1DF8F84D, 0x1DF8F84C, 0x1DF8F84C,
|
||||
0x1DF8F84C, 0x00464686, 0x1DF8F8B3, 0x1DF8F83D, 0x1DF8F83D, 0x1DF8F83D, 0x008E8E40, 0x1AF8F848,
|
||||
0x1ADFF848, 0x1ADFF846, 0x1ADFF846, 0x007F7F40, 0x18D2D275, 0x18D2D23A, 0x18D2D23A, 0x18D2D239,
|
||||
0x00454540, 0x0F868664, 0x0F86863E, 0x0F86863D, 0x0F86863D, 0x005C5C64, 0x1DF8F856, 0x1DF8F855,
|
||||
0x1DF8F855, 0x1DF8F855, 0x005B5B68, 0x1DF8F858, 0x1DF8F855, 0x1DF8F855, 0x1DF8F855, 0x005A5A64,
|
||||
0x1DF8F855, 0x1DF8F854, 0x1DF8F854, 0x1DF8F854, 0x005A5AB5, 0x1DF8F85B, 0x1DF8F855, 0x1DF8F854,
|
||||
0x1DF8F854, 0x00F8F8B0, 0x1DF8F8A3, 0x1DF8F852, 0x1DF8F852, 0x1DF8F852, 0x00A4A4AE, 0x1DF8F854,
|
||||
0x1DF8F852, 0x1DF8F852, 0x1DF8F852, 0x009A9A40, 0x1DF8F84E, 0x1DF8F84D, 0x1DF8F84C, 0x1DF8F84C,
|
||||
0x009C9C40, 0x1DF8F895, 0x1DF8F849, 0x1DF8F84A, 0x1DF8F84A, 0x00494940, 0x1197976F, 0x11979742,
|
||||
0x11979741, 0x11979741, 0x006E6E74, 0x1DF8F869, 0x1DF8F869, 0x1DF8F869, 0x1DF8F869, 0x006E6E40,
|
||||
0x1ADEF869, 0x1ADEF869, 0x1ADEF869, 0x1ADEF869, 0x00757540, 0x0D78F86E, 0x0D78F86E, 0x0D78F86E,
|
||||
0x0D79F86E, 0x00787885, 0x1DF8F873, 0x1DF8F873, 0x1DF8F873, 0x1DF8F873, 0x00787840, 0x1DF8F873,
|
||||
0x1DF8F873, 0x1DF8F873, 0x1DF8F873, 0x00787840, 0x0E81F873, 0x0E81F873, 0x0E81F873, 0x0E82F873,
|
||||
0x00404040, 0x0E82F873, 0x0E82F873, 0x0E82F873, 0x0E82F873, 0x00818140, 0x1092F87E, 0x1092F87E,
|
||||
0x1092F87E, 0x1092F87E, 0x00404040, 0x1092F87E, 0x1092F87E, 0x1092F87E, 0x1092F87E, 0x00737340,
|
||||
0x14B2B26B, 0x14B2B235, 0x14B2B235, 0x14B2B235, 0x00404040, 0x0E828260, 0x0E82823D, 0x0E82823C,
|
||||
0x0E82823C, 0x00404040, 0x0F8B8B66, 0x0F8B8B3F, 0x0F8B8B3D, 0x0F8B8B3D, 0x00404040, 0x0B68683D,
|
||||
0x0B68681E, 0x0B68681E, 0x0B68681E, 0x00222240, 0x06434318, 0x06434329, 0x06434318, 0x06434318,
|
||||
0x00404040, 0x129D9D72, 0x129D9D43, 0x129D9D41, 0x129D9D41, 0x00404040, 0x0D757542, 0x0D757520,
|
||||
0x0D757520, 0x0D757520, 0x00232340, 0x084C4C19, 0x084C4C2C, 0x084C4C19, 0x084C4C19,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint32_t agc_cfg_ram[] = {
|
||||
0x20000000, 0x0400000E, 0x3000200E, 0x5B000000, 0x0400004B, 0x3000008E, 0x32000000, 0x0400007B,
|
||||
0x40000000, 0xF8000026, 0x04000011, 0x4819008E, 0x9C000020, 0x08000191, 0x38008000, 0x0A000000,
|
||||
0x08104411, 0x38018000, 0x0C004641, 0x08D00014, 0x30000000, 0x01000000, 0x04000017, 0x30000000,
|
||||
0x3C000000, 0x0400001A, 0x38020000, 0x40000001, 0x0800001D, 0x3808008E, 0x14000050, 0x08000020,
|
||||
0x4000008E, 0xA400007B, 0x00000101, 0x3000339F, 0x41000700, 0x04104420, 0x90000000, 0x49000000,
|
||||
0xF00E842F, 0xEC0E842C, 0xEC0E842C, 0x04000032, 0x30000000, 0x48000101, 0x04000032, 0x30000000,
|
||||
0x48000202, 0x04000032, 0x30000000, 0x46000000, 0x04000011, 0x58010006, 0x3D040472, 0xDC204439,
|
||||
0x081DD4D2, 0x480A0006, 0xDC2044DC, 0x081DD43C, 0x38050004, 0x0EF1F1C3, 0x342044DC, 0x30000000,
|
||||
0x01000000, 0x04000042, 0x30000000, 0x33000000, 0x04104445, 0x38008000, 0x2200109C, 0x08104448,
|
||||
0x38008000, 0x23D4509C, 0x08104417, 0x9000A000, 0x32000000, 0x18000063, 0x14000060, 0x1C000051,
|
||||
0x10000057, 0x38028000, 0x0C000001, 0x08D04466, 0x3000200F, 0x00000000, 0x00000000, 0x38030000,
|
||||
0x0C002601, 0x08D0445A, 0x30000000, 0x3D020230, 0x0400005D, 0x30000000, 0x3E000100, 0x04000066,
|
||||
0x38028000, 0x0C001601, 0x34204466, 0x38028000, 0x0C000A01, 0x34204466, 0x38008004, 0xFF000000,
|
||||
0x0800007B, 0x3800802F, 0x26000000, 0x0800006C, 0x380404AF, 0x1F191010, 0x0800006F, 0x20000CAF,
|
||||
0x04000071, 0x60000CAF, 0x18700079, 0x14000077, 0x10000075, 0x28140CAF, 0x09B00084, 0x280A0CAF,
|
||||
0x09B00084, 0x28060CAF, 0x09B00084, 0x28048086, 0x0800007D, 0x38000086, 0x22800000, 0x04000080,
|
||||
0x30000000, 0x0EF1F101, 0x36004883, 0x28020000, 0x08000085, 0x3802008E, 0x3D040431, 0x08000088,
|
||||
0x3805008E, 0x1F241821, 0x0800008B, 0x3000008E, 0xA0163021, 0x0400008E, 0x3000008E, 0x0EF10012,
|
||||
0x34000091, 0x300000CC, 0x50000000, 0x04000094, 0x380095FE, 0x32010000, 0x04000097, 0x50001FFE,
|
||||
0x5A010000, 0x6DC9989B, 0xFC19D4B9, 0x30000186, 0x3D840373, 0x0400009E, 0x3000008E, 0x0A000000,
|
||||
0x040000A1, 0x3000008E, 0x22C00000, 0x040000A4, 0x9000028E, 0x32010001, 0x8E4000AA, 0xC80000B0,
|
||||
0x00000000, 0x00000000, 0x3000008E, 0x32010001, 0x040000CB, 0x3000008E, 0x29000000, 0x94045011,
|
||||
0x300019B6, 0x32010000, 0x040000B3, 0x300019B6, 0x3D040431, 0x040000B6, 0x300019B6, 0x22800000,
|
||||
0x04000097, 0x30000186, 0x3D840473, 0x040000BC, 0x3000008E, 0x29030000, 0x040000BF, 0x9AEE028E,
|
||||
0x32010100, 0x7C0000C5, 0xCC0000B0, 0x080000B0, 0x00000000, 0x3000008E, 0x32010100, 0x040000C8,
|
||||
0x3000028E, 0x29000000, 0x94045011, 0x5000038E, 0x29000000, 0x94045011, 0xC0000035, 0x38010006,
|
||||
0x3D040472, 0x080000D2, 0x30000004, 0x0EF1F141, 0x340000D5, 0x28040004, 0x080000D7, 0x2808000E,
|
||||
0x080000D9, 0x3000018E, 0x0EF10052, 0x340000DC, 0x3000038E, 0x29000000, 0x94045011, 0x38020000,
|
||||
0x32000000, 0x080000E2, 0x60000000, 0xD80000E6, 0xD40000E9, 0x040000EC, 0x30000000, 0x0EF1F121,
|
||||
0x360048EF, 0x30000000, 0x0C002421, 0x360048EF, 0x30000000, 0x0C000021, 0x360048EF, 0x28020000,
|
||||
0x0800007B, 0x50001EFE, 0x5A010000, 0x6DC998F5, 0xFC19D4F8, 0x3000028E, 0x32000040, 0x040000FB,
|
||||
0x3AEE028E, 0x32000080, 0x040000FB, 0x30000000, 0x0EF1F101, 0x360048FE, 0x28020000, 0x08000100,
|
||||
0x3802008E, 0x3D040431, 0x08000103, 0x3805008E, 0x1F241821, 0x08000106, 0x3000008E, 0xA0163021,
|
||||
0x04000109, 0x3000008E, 0x0EF10012, 0x3400010C, 0x300014F6, 0x32010000, 0x04000114, 0x20000000,
|
||||
0x04000111, 0x300000EC, 0x50000000, 0x040000F1, 0x300014F6, 0x32030000, 0x04000117, 0x30001086,
|
||||
0x3D840473, 0x0400011A, 0x5000108E, 0x22C00000, 0x8E47C0CB, 0xCB30011E, 0x300019B6, 0x32040000,
|
||||
0x04000121, 0x300019B6, 0x3D040431, 0x04000124, 0x300019B6, 0x22800000, 0x04000111, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x30000186, 0x3D840473, 0x0400012D, 0x5000038E, 0x29000000, 0x94045011,
|
||||
0xC0000131, 0x380C800E, 0xFF000000, 0x08000134, 0x30000004, 0x0FF1F103, 0x34000137, 0x28020000,
|
||||
0x08000139, 0x3000038E, 0x29000000, 0x94045011, 0x00000000, 0x00000000, 0x00000000, 0x58010006,
|
||||
0x3D040472, 0xDC204543, 0x081DD4D2, 0x480A0006, 0xDC2044DC, 0x081DD546, 0x38050004, 0x0EF1F141,
|
||||
0x342044DC, 0x2802800E, 0x080000DC, 0x48000035, 0x0400014A, 0x7896638F, 0x4100000F, 0x8C00014F,
|
||||
0x080450C4, 0x90104574, 0x88C8620F, 0xC000015A, 0x90104574, 0x08104554, 0x94104557, 0x3000628F,
|
||||
0x29000000, 0x9404517A, 0x3000638F, 0x29000000, 0x0410457A, 0x3800E005, 0x3D010131, 0x0810455D,
|
||||
0xA832600F, 0x90104574, 0x08000154, 0x94104557, 0xC6104567, 0xC4185563, 0x5802E00F, 0x0FEEEA07,
|
||||
0x80000174, 0x3420456B, 0x5802E00F, 0x0EEEEA07, 0x80000174, 0x3420456B, 0x30004000, 0x33000001,
|
||||
0x0400016E, 0x38034005, 0x3D030373, 0x08000171, 0x30006007, 0x33000000, 0x04000174, 0x3000608F,
|
||||
0x29000000, 0x94045177, 0x4000608F, 0xA010457D, 0x0410457A, 0x3000608F, 0x64000101, 0x04104411,
|
||||
0x3000608F, 0x64000101, 0x04104580, 0x3000618F, 0x42000001, 0x04000183, 0x38028000, 0x32000000,
|
||||
0x08104586, 0x280A618F, 0x08000188, 0x480A618F, 0xBC00018B, 0x0800018E, 0x3000618F, 0x34000001,
|
||||
0x04000005, 0x3000618F, 0x34000000, 0x04000008, 0x3000008F, 0x0EEAED0F, 0x36000194, 0x38038000,
|
||||
0x34000000, 0x08000197, 0x38028005, 0x29010002, 0x0800019A, 0x3000028F, 0x2200209C, 0x0400019D,
|
||||
0x3000028F, 0x23D4509C, 0x040001A0, 0x2814028F, 0x080001A2, 0x3000028F, 0x43010201, 0x040001A5,
|
||||
0x3000128F, 0x32000100, 0x040001A8, 0x5AEE138F, 0x4100000F, 0x7C0001AC, 0x080000F9, 0x592C138F,
|
||||
0x29000000, 0x8C0001B0, 0x080000F9, 0x2000138F, 0x94045011, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
};
|
||||
|
||||
static uint32_t txgain_map[96] = {
|
||||
#ifdef CONFIG_FPGA_VERIFICATION
|
||||
0x20c0c971, 0x20c0c980, 0x20c0c992, 0x20c0c9a6, 0x20c0c9bf, 0x20c0caa5, 0x20c0cabd, 0x20c0cba0,
|
||||
0x20c0cbb6, 0x20c0cbea, 0x20c0ccc5, 0x20c0cdac, 0x20c0cdd0, 0x20c0ceb2, 0x20c0ceff, 0x20c0cfff,
|
||||
0x20c0c922, 0x20c0c922, 0x20c0c922, 0x20c0c922, 0x20c0c922, 0x20c0c922, 0x20c0c922, 0x20c0c927,
|
||||
0x20c0c92c, 0x20c0c931, 0x20c0c937, 0x20c0c93f, 0x20c0c946, 0x20c0c94f, 0x20c0c959, 0x20c0c964,
|
||||
0x20c0cbee, 0x20c0cce0, 0x20c0ccff, 0x20c0cde2, 0x20c0cdfe, 0x20c0cede, 0x20c0cefc, 0x20c0cfd9,
|
||||
0x20c0cff8, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff,
|
||||
0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c98c,
|
||||
0x20c0ca79, 0x20c0ca89, 0x20c0cb74, 0x20c0cb84, 0x20c0cb94, 0x20c0cba8, 0x20c0cbbb, 0x20c0cbd2,
|
||||
0x20c0cbee, 0x20c0cce0, 0x20c0ccff, 0x20c0cde2, 0x20c0cdfe, 0x20c0cede, 0x20c0cefc, 0x20c0cfd9,
|
||||
0x20c0cff8, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff, 0x20c0cfff,
|
||||
0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c97c, 0x20c0c98c,
|
||||
0x20c0ca79, 0x20c0ca89, 0x20c0cb74, 0x20c0cb84, 0x20c0cb94, 0x20c0cba8, 0x20c0cbbb, 0x20c0cbd2,
|
||||
#else
|
||||
0x00ffc772, 0x00ffc780, 0x00ffc872, 0x00ffc880, 0x00ffc970, 0x00ffc980, 0x00ffc990, 0x00ffca80,
|
||||
0x00ffca9a, 0x00ffcb90, 0x00ffcc95, 0x00ffce80, 0x00ffcf80, 0x00ffcf80, 0x00ffcf80, 0x00ffcf80,
|
||||
0x00ffc05b, 0x00ffc066, 0x00ffc070, 0x00ffc080, 0x00ffc175, 0x00ffc185, 0x00ffc272, 0x00ffc280,
|
||||
0x00ffc290, 0x00ffc380, 0x00ffc472, 0x00ffc483, 0x00ffc572, 0x00ffc580, 0x00ffc590, 0x00ffc680,
|
||||
0x00ffc87d, 0x00ffc88b, 0x00ffc979, 0x00ffc989, 0x00ffca7d, 0x00ffca8d, 0x00ffcb7a, 0x00ffcb8a,
|
||||
0x00ffcc7d, 0x00ffcc8d, 0x00ffcd79, 0x00ffcd89, 0x00ffce7d, 0x00ffce8d, 0x00ffcf80, 0x00ffcf99,
|
||||
0x00ffc080, 0x00ffc090, 0x00ffc180, 0x00ffc190, 0x00ffc27b, 0x00ffc28b, 0x00ffc37b, 0x00ffc38b,
|
||||
0x00ffc480, 0x00ffc490, 0x00ffc579, 0x00ffc589, 0x00ffc679, 0x00ffc689, 0x00ffc780, 0x00ffc790,
|
||||
0x00ffc87d, 0x00ffc88b, 0x00ffc979, 0x00ffc989, 0x00ffca7d, 0x00ffca8d, 0x00ffcb7a, 0x00ffcb8a,
|
||||
0x00ffcc7d, 0x00ffcc8d, 0x00ffcd79, 0x00ffcd89, 0x00ffce7d, 0x00ffce8d, 0x00ffcf80, 0x00ffcf99,
|
||||
0x00ffc080, 0x00ffc090, 0x00ffc180, 0x00ffc190, 0x00ffc27b, 0x00ffc28b, 0x00ffc37b, 0x00ffc38b,
|
||||
0x00ffc480, 0x00ffc490, 0x00ffc579, 0x00ffc589, 0x00ffc679, 0x00ffc689, 0x00ffc780, 0x00ffc790,
|
||||
#endif
|
||||
};
|
||||
|
||||
static uint32_t txgain_table[32] = {
|
||||
0xA4B22189, 0x00007825, 0xA4B2214B, 0x00007825, 0xA4B2214F, 0x00007825, 0xA4B221D5, 0x00007825,
|
||||
0xA4B221DC, 0x00007825, 0xA4B221E5, 0x00007825, 0xAC9221E5, 0x00006825, 0xAC9221EF, 0x00006825,
|
||||
0xBC9221EE, 0x00006825, 0xBC9221FF, 0x00006825, 0xBC9221FF, 0x00004025, 0xB792203F, 0x00004026,
|
||||
0xDC92203F, 0x00004025, 0xE692203F, 0x00004025, 0xFF92203F, 0x00004035, 0xFFFE203F, 0x00004832,
|
||||
};
|
||||
|
||||
static uint32_t rxgain_table_24g_20m[64] = {
|
||||
0x82f282d1, 0x9591a324, 0x80808419, 0x000000f0, 0x42f282d1, 0x95923524, 0x80808419, 0x000000f0,
|
||||
0x22f282d1, 0x9592c724, 0x80808419, 0x000000f0, 0x02f282d1, 0x9591a324, 0x80808419, 0x000000f0,
|
||||
0x06f282d1, 0x9591a324, 0x80808419, 0x000000f0, 0x0ef29ad1, 0x9591a324, 0x80808419, 0x000000f0,
|
||||
0x0ef29ad3, 0x95923524, 0x80808419, 0x000000f0, 0x0ef29ad7, 0x9595a324, 0x80808419, 0x000000f0,
|
||||
0x06f282d2, 0x95911124, 0x80808419, 0x000000f0, 0x06f282f4, 0x95911124, 0x80808419, 0x000000f0,
|
||||
0x06f282e6, 0x9591a324, 0x80808419, 0x000000f0, 0x06f282e6, 0x9595a324, 0x80808419, 0x000000f0,
|
||||
0x06f282e6, 0x9599a324, 0x80808419, 0x000000f0, 0x06f282e6, 0x959b5924, 0x80808419, 0x000000f0,
|
||||
0x06f282e6, 0x959f5924, 0x80808419, 0x000000f0, 0x0ef29ae6, 0x959f5924, 0x80808419, 0x000000f0,
|
||||
};
|
||||
|
||||
static uint32_t rxgain_table_24g_40m[64] = {
|
||||
0x83428151, 0x9631a328, 0x80808419, 0x000000f0, 0x43428151, 0x96323528, 0x80808419, 0x000000f0,
|
||||
0x23428151, 0x9632c728, 0x80808419, 0x000000f0, 0x03428151, 0x9631a328, 0x80808419, 0x000000f0,
|
||||
0x07429951, 0x9631a328, 0x80808419, 0x000000f0, 0x0f42d151, 0x9631a328, 0x80808419, 0x000000f0,
|
||||
0x0f42d153, 0x96323528, 0x80808419, 0x000000f0, 0x0f42d157, 0x9635a328, 0x80808419, 0x000000f0,
|
||||
0x07429952, 0x96311128, 0x80808419, 0x000000f0, 0x07429974, 0x96311128, 0x80808419, 0x000000f0,
|
||||
0x07429966, 0x9631a328, 0x80808419, 0x000000f0, 0x07429966, 0x9635a328, 0x80808419, 0x000000f0,
|
||||
0x07429966, 0x9639a328, 0x80808419, 0x000000f0, 0x07429966, 0x963b5928, 0x80808419, 0x000000f0,
|
||||
0x07429966, 0x963f5928, 0x80808419, 0x000000f0, 0x0f42d166, 0x963f5928, 0x80808419, 0x000000f0,
|
||||
};
|
||||
|
||||
static u32 patch_tbl_func[][2] = {
|
||||
#ifndef CONFIG_FOR_IPCOM
|
||||
{0x00110054, 0x0018186D}, // same as jump_tbl idx 168
|
||||
{0x0011005C, 0x0018186D}, // same as jump_tbl idx 168
|
||||
#else
|
||||
{0x00110054, 0x00182A79}, // same as jump_tbl idx 168
|
||||
{0x0011005C, 0x00182A79}, // same as jump_tbl idx 168
|
||||
{0x001118D4, 0x00000011},
|
||||
#endif
|
||||
};
|
||||
|
||||
static u32 patch_tbl_rf_func[][2] = {
|
||||
{0x00110bf0, 0x00180001},
|
||||
};
|
||||
|
||||
static const struct aicbsp_firmware fw_u01[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u01)",
|
||||
.bt_adid = "aic8800dc/fw_adid.bin",
|
||||
.bt_patch = "aic8800dc/fw_patch.bin",
|
||||
.bt_table = "aic8800dc/fw_patch_table.bin",
|
||||
.wl_fw = "aic8800dc/fmacfw_patch.bin",
|
||||
.wl_table = "aic8800dc/fmacfw_patch_tbl.bin",
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u01)",
|
||||
.bt_adid = "aic8800dc/fw_adid.bin",
|
||||
.bt_patch = "aic8800dc/fw_patch.bin",
|
||||
.bt_table = "aic8800dc/fw_patch_table.bin",
|
||||
.wl_fw = "aic8800dc/lmacfw_rf.bin",
|
||||
.wl_table = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct aicbsp_firmware fw_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u02)",
|
||||
.bt_adid = "aic8800dc/fw_adid_u02.bin",
|
||||
.bt_patch = "aic8800dc/fw_patch_u02.bin",
|
||||
.bt_table = "aic8800dc/fw_patch_table_u02.bin",
|
||||
.wl_fw = "aic8800dc/fmacfw_patch_u02.bin",
|
||||
.wl_table = "aic8800dc/fmacfw_patch_tbl_u02.bin",
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u02)",
|
||||
.bt_adid = "aic8800dc/fw_adid_u02.bin",
|
||||
.bt_patch = "aic8800dc/fw_patch_u02.bin",
|
||||
.bt_table = "aic8800dc/fw_patch_table_u02.bin",
|
||||
.wl_fw = "aic8800dc/lmacfw_rf.bin",
|
||||
.wl_table = NULL,
|
||||
},
|
||||
};
|
||||
|
||||
static int aic8800dc_wifi_patch_table_load(struct aic_sdio_dev *sdiodev, const char *filename)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
int size;
|
||||
u32 *dst = NULL;
|
||||
int err = 0;
|
||||
|
||||
const struct firmware *fw = NULL;
|
||||
int ret = request_firmware(&fw, filename, NULL);
|
||||
|
||||
u32 FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE = 0X183E00;
|
||||
u32 FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_SIZE = 128;
|
||||
|
||||
printk("rwnx_request_firmware, name: %s\n", filename);
|
||||
if (ret < 0) {
|
||||
printk("Load %s fail\n", filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size = fw->size;
|
||||
dst = (u32 *)fw->data;
|
||||
|
||||
if (size <= 0) {
|
||||
printk("wrong size of firmware file\n");
|
||||
release_firmware(fw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!err && (i < size)) {
|
||||
err = rwnx_send_dbg_mem_block_write_req(sdiodev, FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_BASE, FMACFW_PATCH_TBL_8800DC_U02_DESCRIBE_SIZE, &dst[0]);
|
||||
if (err)
|
||||
printk("write describe information fail\n");
|
||||
|
||||
printk("wifi patch version: %s", (char *)dst);
|
||||
}
|
||||
|
||||
if (!err && (i < size)) {// <1KB data
|
||||
for (i = 128 / 4; i < size / 4; i += 2)
|
||||
err = rwnx_send_dbg_mem_write_req(sdiodev, dst[i], dst[i+1]);
|
||||
|
||||
if (err)
|
||||
printk("bin upload fail: %x, err:%d\n", dst[i], err);
|
||||
}
|
||||
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aic8800dc_wifi_patch_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = 0;
|
||||
int cnt = 0;
|
||||
if (aicbsp_info.cpmode == AICBSP_CPMODE_WORK) {
|
||||
const u32 cfg_base = 0x10164;
|
||||
|
||||
u32 wifisetting_cfg_addr;
|
||||
u32 ldpc_cfg_addr;
|
||||
u32 agc_cfg_addr;
|
||||
u32 txgain_cfg_addr;
|
||||
u32 jump_tbl_addr;
|
||||
|
||||
u32 patch_tbl_wifisetting_num;
|
||||
u32 ldpc_cfg_size = sizeof(ldpc_cfg_ram);
|
||||
u32 agc_cfg_size = sizeof(agc_cfg_ram);
|
||||
u32 txgain_cfg_size = sizeof(txgain_map);
|
||||
u32 jump_tbl_size = sizeof(jump_tbl)/2;
|
||||
u32 patch_tbl_func_num = sizeof(patch_tbl_func)/sizeof(u32)/2;
|
||||
|
||||
struct dbg_mem_read_cfm cfm;
|
||||
int i;
|
||||
|
||||
array2_tbl_t jump_tbl_base = NULL;
|
||||
array2_tbl_t patch_tbl_func_base = NULL;
|
||||
array2_tbl_t patch_tbl_wifisetting_8800dc_base = NULL;
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
jump_tbl_base = jump_tbl;
|
||||
jump_tbl_size = sizeof(jump_tbl)/2;
|
||||
patch_tbl_func_base = patch_tbl_func;
|
||||
patch_tbl_func_num = sizeof(patch_tbl_func)/sizeof(u32)/2;
|
||||
patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u01)/sizeof(u32)/2;
|
||||
patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u01;
|
||||
} else if (aicbsp_info.chipinfo->subrev == 1) {
|
||||
patch_tbl_wifisetting_num = sizeof(patch_tbl_wifisetting_8800dc_u02)/sizeof(u32)/2;
|
||||
patch_tbl_wifisetting_8800dc_base = patch_tbl_wifisetting_8800dc_u02;
|
||||
} else {
|
||||
printk("unsupported id: %d", aicbsp_info.chipinfo->subrev);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base, &cfm);
|
||||
if (ret) {
|
||||
pr_err("setting base[0x%x] rd fail: %d\n", cfg_base, ret);
|
||||
goto out;
|
||||
}
|
||||
wifisetting_cfg_addr = cfm.memdata;
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 4, &cfm);
|
||||
if (ret) {
|
||||
pr_err("setting base[0x%x] rd fail: %d\n", cfg_base + 4, ret);
|
||||
goto out;
|
||||
}
|
||||
jump_tbl_addr = cfm.memdata;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 8, &cfm);
|
||||
if (ret) {
|
||||
pr_err("setting base[0x%x] rd fail: %d\n", cfg_base + 8, ret);
|
||||
goto out;
|
||||
}
|
||||
ldpc_cfg_addr = cfm.memdata;
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0xc, &cfm);
|
||||
if (ret) {
|
||||
pr_err("setting base[0x%x] rd fail: %d\n", cfg_base + 0xc, ret);
|
||||
goto out;
|
||||
}
|
||||
agc_cfg_addr = cfm.memdata;
|
||||
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, cfg_base + 0x10, &cfm)) {
|
||||
pr_err("setting base[0x%x] rd fail: %d\n", cfg_base + 0x10, ret);
|
||||
goto out;
|
||||
}
|
||||
txgain_cfg_addr = cfm.memdata;
|
||||
|
||||
printk("wifisetting_cfg_addr=%x, ldpc_cfg_addr=%x, agc_cfg_addr=%x, txgain_cfg_addr=%x\n", wifisetting_cfg_addr, ldpc_cfg_addr, agc_cfg_addr, txgain_cfg_addr);
|
||||
|
||||
for (cnt = 0; cnt < patch_tbl_wifisetting_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, wifisetting_cfg_addr + patch_tbl_wifisetting_8800dc_base[cnt][0], patch_tbl_wifisetting_8800dc_base[cnt][1]);
|
||||
if (ret) {
|
||||
pr_err("wifisetting %x write fail\n", patch_tbl_wifisetting_8800dc_base[cnt][0]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (ldpc_cfg_size > 512) {// > 0.5KB data
|
||||
for (i = 0; i < (ldpc_cfg_size - 512); i += 512) {//each time write 0.5KB
|
||||
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ldpc_cfg_addr + i, 512, ldpc_cfg_ram + i / 4);
|
||||
if (ret) {
|
||||
pr_err("ldpc upload fail: %x, err:%d\r\n", ldpc_cfg_addr + i, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && (i < ldpc_cfg_size)) {// < 0.5KB data
|
||||
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, ldpc_cfg_addr + i, ldpc_cfg_size - i, ldpc_cfg_ram + i / 4);
|
||||
if (ret) {
|
||||
pr_err("ldpc upload fail: %x, err:%d\r\n", ldpc_cfg_addr + i, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (agc_cfg_size > 512) {// > 0.5KB data
|
||||
for (i = 0; i < (agc_cfg_size - 512); i += 512) {//each time write 0.5KB
|
||||
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, agc_cfg_addr + i, 512, agc_cfg_ram + i / 4);
|
||||
if (ret) {
|
||||
pr_err("agc upload fail: %x, err:%d\r\n", agc_cfg_addr + i, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret && (i < agc_cfg_size)) {// < 0.5KB data
|
||||
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, agc_cfg_addr + i, agc_cfg_size - i, agc_cfg_ram + i / 4);
|
||||
if (ret) {
|
||||
pr_err("agc upload fail: %x, err:%d\r\n", agc_cfg_addr + i, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_FPGA_VERIFICATION)
|
||||
ret = rwnx_send_dbg_mem_block_write_req(sdiodev, txgain_cfg_addr, txgain_cfg_size, txgain_map);
|
||||
if (ret) {
|
||||
pr_err("txgain upload fail: %x, err:%d\r\n", txgain_cfg_addr, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
for (cnt = 0; cnt < jump_tbl_size/4; cnt += 1) {
|
||||
//printk("%x = %x\n", jump_tbl[cnt][0]*4+jump_tbl_addr, jump_tbl[cnt][1]);
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, jump_tbl_base[cnt][0]*4+jump_tbl_addr, jump_tbl_base[cnt][1]);
|
||||
if (ret) {
|
||||
pr_err("%x write fail\n", jump_tbl_addr+8*cnt);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
for (cnt = 0; cnt < patch_tbl_func_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_tbl_func_base[cnt][0], patch_tbl_func_base[cnt][1]);
|
||||
if (ret) {
|
||||
pr_err("patch_tbl_func %x write fail\n", patch_tbl_func_base[cnt][0]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = aic8800dc_wifi_patch_table_load(sdiodev, aicbsp_firmware_list[aicbsp_info.cpmode].wl_table);
|
||||
if (ret) {
|
||||
printk("patch_tbl upload fail: err:%d\r\n", ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
ret = rwnx_send_rf_config_req(sdiodev, 0, 1, (u8 *)txgain_table, 128);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = rwnx_send_rf_config_req(sdiodev, 0, 0, (u8 *)rxgain_table_24g_20m, 256);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = rwnx_send_rf_config_req(sdiodev, 32, 0, (u8 *)rxgain_table_24g_40m, 256);
|
||||
} else {
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
u32 patch_tbl_rf_func_num = sizeof(patch_tbl_rf_func)/sizeof(u32)/2;
|
||||
for (cnt = 0; cnt < patch_tbl_rf_func_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_tbl_rf_func[cnt][0], patch_tbl_rf_func[cnt][1]);
|
||||
if (ret) {
|
||||
pr_err("patch_tbl_rf_func %x write fail\n", patch_tbl_rf_func[cnt][0]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aic8800dc_bt_patch_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
struct aicbt_info_t btcfg = {
|
||||
.btmode = AICBT_BTMODE_BT_WIFI_COMBO,
|
||||
.btport = AICBT_BTPORT_DEFAULT,
|
||||
.uart_baud = AICBT_UART_BAUD_DEFAULT,
|
||||
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
|
||||
.lpm_enable = AICBT_LPM_ENABLE_DEFAULT,
|
||||
.txpwr_lvl = AICBT_TXPWR_LVL_DEFAULT,
|
||||
};
|
||||
|
||||
struct aicbt_patch_table *head = aicbt_patch_table_alloc(aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
|
||||
int ret = aicbt_patch_info_unpack(head, &btcfg);
|
||||
|
||||
if (head == NULL)
|
||||
return -1;
|
||||
|
||||
if (ret) {
|
||||
btcfg.addr_adid = RAM_8800DC_ADID_ADDR;
|
||||
btcfg.addr_patch = RAM_8800DC_FW_PATCH_ADDR;
|
||||
}
|
||||
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, btcfg.addr_adid, aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, btcfg.addr_patch, aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = aicbt_patch_table_load(sdiodev, &btcfg, head);
|
||||
if (ret)
|
||||
printk("aicbt_patch_table_load fail\n");
|
||||
|
||||
err:
|
||||
aicbt_patch_table_free(&head);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicbsp_8800dc_fw_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
u32 mem_addr = 0x40500000;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
|
||||
int syscfg_num, cnt, ret;
|
||||
u32 boot_type = HOST_START_APP_DUMMY;
|
||||
u32 rd_addr, fw_addr, ld_addr;
|
||||
|
||||
if (aicbsp_info.cpmode == AICBSP_CPMODE_TEST) {
|
||||
rd_addr = RAM_LMAC_FW_ADDR;
|
||||
fw_addr = RAM_LMAC_FW_ADDR;
|
||||
ld_addr = RAM_LMAC_FW_ADDR;
|
||||
} else {
|
||||
rd_addr = RAM_FMAC_FW_ADDR;
|
||||
fw_addr = RAM_FMAC_FW_ADDR;
|
||||
ld_addr = ROM_FMAC_PATCH_ADDR;
|
||||
}
|
||||
|
||||
aicbsp_firmware_list = fw_u01;
|
||||
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
aicbsp_info.chipinfo->rev = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||
|
||||
aicbsp_info.chipinfo->mcuid = 0;
|
||||
if (((rd_mem_addr_cfm.memdata >> 25) & 0x01UL) == 0x00UL)
|
||||
aicbsp_info.chipinfo->mcuid = 1;
|
||||
|
||||
mem_addr = 0x00000020;
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
aicbsp_info.chipinfo->subrev = (u8)rd_mem_addr_cfm.memdata;
|
||||
|
||||
printk("%s(%d), rev: %d, subrev: %d, mucid: %d\n", __func__, __LINE__,
|
||||
aicbsp_info.chipinfo->rev, aicbsp_info.chipinfo->subrev, aicbsp_info.chipinfo->mcuid);
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev != 0 && aicbsp_info.chipinfo->subrev != 1) {
|
||||
printk("%s(%d), unsupported subrev: %d\n", __func__, __LINE__, aicbsp_info.chipinfo->subrev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicbsp_info.chipinfo->rev == CHIP_REV_U02)
|
||||
aicbsp_firmware_list = fw_u02;
|
||||
|
||||
mem_addr = 0x40500010;
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
|
||||
aic8800dc_bt_patch_config(sdiodev);
|
||||
|
||||
syscfg_num = sizeof(syscfg_tbl_8800dc) / sizeof(u32) / 2;
|
||||
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, syscfg_tbl_8800dc[cnt][0], syscfg_tbl_8800dc[cnt][1]);
|
||||
if (ret) {
|
||||
sdio_err("%x write fail: %d\n", syscfg_tbl_8800dc[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (aicbsp_info.chipinfo->mcuid == 0) {
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
syscfg_num = sizeof(syscfg_tbl_8800dc_sdio_u01) / sizeof(u32) / 2;
|
||||
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, syscfg_tbl_8800dc_sdio_u01[cnt][0], syscfg_tbl_8800dc_sdio_u01[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", syscfg_tbl_8800dc_sdio_u01[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} else if (aicbsp_info.chipinfo->subrev == 1) {
|
||||
syscfg_num = sizeof(syscfg_tbl_8800dc_sdio_u02) / sizeof(u32) / 2;
|
||||
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, syscfg_tbl_8800dc_sdio_u02[cnt][0], syscfg_tbl_8800dc_sdio_u02[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", syscfg_tbl_8800dc_sdio_u02[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syscfg_num = sizeof(syscfg_tbl_masked_8800dc) / sizeof(u32) / 3;
|
||||
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
if (syscfg_tbl_masked_8800dc[cnt][0] == 0x00000000)
|
||||
break;
|
||||
|
||||
if (syscfg_tbl_masked_8800dc[cnt][0] == 0x70001000) {
|
||||
if (aicbsp_info.chipinfo->mcuid == 0) {
|
||||
syscfg_tbl_masked_8800dc[cnt][1] |= ((0x1 << 8) | (0x1 << 15)); // mask
|
||||
syscfg_tbl_masked_8800dc[cnt][2] |= ((0x1 << 8) | (0x1 << 15));
|
||||
}
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
syscfg_tbl_masked_8800dc[cnt][0], syscfg_tbl_masked_8800dc[cnt][1], syscfg_tbl_masked_8800dc[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800dc[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev == 0) {
|
||||
syscfg_num = sizeof(syscfg_tbl_masked_8800dc_u01) / sizeof(u32) / 3;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
syscfg_tbl_masked_8800dc_u01[cnt][0], syscfg_tbl_masked_8800dc_u01[cnt][1], syscfg_tbl_masked_8800dc_u01[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked_8800dc_u01[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aicbsp_info.chipinfo->subrev == 0 && aicbsp_info.cpmode == AICBSP_CPMODE_TEST) {
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, ROM_FMAC_PATCH_ADDR, RF_PATCH_NAME_8800DC);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_plat_bin_fw_upload_android(sdiodev, ld_addr, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
aic8800dc_wifi_patch_config(sdiodev);
|
||||
|
||||
printk("Read FW mem: %08x\n", rd_addr);
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, rd_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
|
||||
printk("cfm: [%08x] = %08x\n", rd_mem_addr_cfm.memaddr, rd_mem_addr_cfm.memdata);
|
||||
|
||||
boot_type = HOST_START_APP_DUMMY;
|
||||
if (aicbsp_info.cpmode == AICBSP_CPMODE_TEST)
|
||||
boot_type = HOST_START_APP_AUTO;
|
||||
|
||||
/* fw start */
|
||||
printk("Start app: %08x, %d\n", fw_addr, boot_type);
|
||||
if (rwnx_send_dbg_start_app_req(sdiodev, fw_addr, boot_type, NULL))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,10 +1,7 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* rwnx_cmds.c
|
||||
*
|
||||
* Handles queueing (push to IPC, ack/cfm from IPC) of commands issued to
|
||||
* LMAC FW
|
||||
* aic_bsp_driver.c
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2014-2019
|
||||
*
|
||||
@ -18,10 +15,9 @@
|
||||
#include "aicsdio.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
static u8 binding_enc_data[16];
|
||||
static bool need_binding_verify;
|
||||
u8 binding_enc_data[16];
|
||||
bool need_binding_verify;
|
||||
|
||||
int wcn_bind_verify_calculate_verify_data(uint8_t *din, uint8_t *dout);
|
||||
#ifndef CONFIG_PLATFORM_ALLWINNER
|
||||
int wcn_bind_verify_calculate_verify_data(uint8_t *din, uint8_t *dout)
|
||||
{
|
||||
@ -460,6 +456,32 @@ int rwnx_send_dbg_start_app_req(struct aic_sdio_dev *sdiodev, u32 boot_addr, u32
|
||||
return rwnx_send_msg(sdiodev, start_app_req, 1, DBG_START_APP_CFM, start_app_cfm);
|
||||
}
|
||||
|
||||
int rwnx_send_rf_config_req(struct aic_sdio_dev *sdiodev, u8 ofst, u8 sel, u8 *tbl, u16 len)
|
||||
{
|
||||
struct mm_set_rf_config_req *rf_config_req;
|
||||
int error;
|
||||
|
||||
/* Build the MM_SET_RF_CONFIG_REQ message */
|
||||
rf_config_req = rwnx_msg_zalloc(MM_SET_RF_CONFIG_REQ, TASK_MM, DRV_TASK_ID,
|
||||
sizeof(struct mm_set_rf_config_req));
|
||||
|
||||
if (!rf_config_req) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rf_config_req->table_sel = sel;
|
||||
rf_config_req->table_ofst = ofst;
|
||||
rf_config_req->table_num = 16;
|
||||
rf_config_req->deft_page = 0;
|
||||
|
||||
memcpy(rf_config_req->data, tbl, len);
|
||||
|
||||
/* Send the MM_SET_RF_CONFIG_REQ message to UMAC FW */
|
||||
error = rwnx_send_msg(sdiodev, rf_config_req, 1, MM_SET_RF_CONFIG_CFM, NULL);
|
||||
|
||||
return error;
|
||||
};
|
||||
|
||||
static inline int dbg_binding_ind(struct rwnx_cmd *cmd, struct ipc_e2a_msg *msg)
|
||||
{
|
||||
struct dbg_binding_ind *ind = (struct dbg_binding_ind *)msg->param;
|
||||
@ -473,7 +495,11 @@ static msg_cb_fct dbg_hdlrs[MSG_I(DBG_MAX)] = {
|
||||
[MSG_I(DBG_BINDING_IND)] = (msg_cb_fct)dbg_binding_ind,
|
||||
};
|
||||
|
||||
static msg_cb_fct mm_hdlrs[MSG_I(MM_MAX)] = {
|
||||
};
|
||||
|
||||
static msg_cb_fct *msg_hdlrs[] = {
|
||||
[TASK_MM] = mm_hdlrs,
|
||||
[TASK_DBG] = dbg_hdlrs,
|
||||
};
|
||||
|
||||
@ -609,32 +635,36 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int aicbt_patch_trap_data_load(struct aic_sdio_dev *sdiodev)
|
||||
int aicbt_patch_info_unpack(struct aicbt_patch_table *head, struct aicbt_info_t *aicbt_info)
|
||||
{
|
||||
uint32_t fw_ram_adid_base_addr = FW_RAM_ADID_BASE_ADDR;
|
||||
if (aicbsp_info.chip_rev != CHIP_REV_U02)
|
||||
fw_ram_adid_base_addr = FW_RAM_ADID_BASE_ADDR_U03;
|
||||
struct aicbt_patch_table *p;
|
||||
int ret = -1;
|
||||
|
||||
if (rwnx_plat_bin_fw_upload_android(sdiodev, fw_ram_adid_base_addr, aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid))
|
||||
return -1;
|
||||
if (rwnx_plat_bin_fw_upload_android(sdiodev, FW_RAM_PATCH_BASE_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch))
|
||||
return -1;
|
||||
return 0;
|
||||
for (p = head; p != NULL; p = p->next) {
|
||||
if (AICBT_PT_INF == p->type) {
|
||||
aicbt_info->addr_adid = *(p->data + 1);
|
||||
aicbt_info->addr_patch = *(p->data + 3);
|
||||
printk("%s bt adid addr: 0x%08x, patch addr: 0x%08x\n", __func__, aicbt_info->addr_adid, aicbt_info->addr_patch);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (AICBT_PT_VER == p->type) {
|
||||
printk("%s bt patch version: %s\n", __func__, (char *)p->data);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct aicbt_info_t aicbt_info = {
|
||||
.btmode = AICBT_BTMODE_DEFAULT,
|
||||
.btport = AICBT_BTPORT_DEFAULT,
|
||||
.uart_baud = AICBT_UART_BAUD_DEFAULT,
|
||||
.uart_flowctrl = AICBT_UART_FC_DEFAULT,
|
||||
};
|
||||
|
||||
int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev)
|
||||
int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_info_t *aicbt_info, struct aicbt_patch_table *head)
|
||||
{
|
||||
struct aicbt_patch_table *head, *p;
|
||||
struct aicbt_patch_table *p;
|
||||
int ret = 0, i;
|
||||
uint32_t *data = NULL;
|
||||
head = aicbt_patch_table_alloc(aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
|
||||
|
||||
printk("%s bt uart baud: %d, flowctrl: %d, lpm_enable: %d, tx_pwr: %d\n", __func__,
|
||||
aicbt_info->uart_baud, aicbt_info->uart_flowctrl, aicbt_info->lpm_enable, aicbt_info->txpwr_lvl);
|
||||
|
||||
for (p = head; p != NULL; p = p->next) {
|
||||
data = p->data;
|
||||
if (AICBT_PT_BTMODE == p->type) {
|
||||
@ -642,14 +672,16 @@ int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev)
|
||||
*(data + 3) = aicbsp_info.hwinfo;
|
||||
*(data + 5) = aicbsp_info.cpmode;
|
||||
|
||||
*(data + 7) = aicbt_info.btmode;
|
||||
*(data + 9) = aicbt_info.btport;
|
||||
*(data + 11) = aicbt_info.uart_baud;
|
||||
*(data + 13) = aicbt_info.uart_flowctrl;
|
||||
*(data + 7) = aicbt_info->btmode;
|
||||
*(data + 9) = aicbt_info->btport;
|
||||
*(data + 11) = aicbt_info->uart_baud;
|
||||
*(data + 13) = aicbt_info->uart_flowctrl;
|
||||
*(data + 15) = aicbt_info->lpm_enable;
|
||||
*(data + 17) = aicbt_info->txpwr_lvl;
|
||||
|
||||
}
|
||||
|
||||
if (AICBT_PT_VER == p->type) {
|
||||
printk("aicbsp: bt patch version: %s\n", (char *)p->data);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -662,185 +694,6 @@ int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev)
|
||||
if (p->type == AICBT_PT_PWRON)
|
||||
udelay(500);
|
||||
}
|
||||
aicbt_patch_table_free(&head);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicbt_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
if (aicbt_patch_trap_data_load(sdiodev)) {
|
||||
printk("aicbt_patch_trap_data_load fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicbt_patch_table_load(sdiodev)) {
|
||||
printk("aicbt_patch_table_load fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwifi_start_from_bootrom(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* memory access */
|
||||
const u32 fw_addr = RAM_FMAC_FW_ADDR;
|
||||
struct dbg_start_app_cfm start_app_cfm;
|
||||
|
||||
/* fw start */
|
||||
ret = rwnx_send_dbg_start_app_req(sdiodev, fw_addr, HOST_START_APP_AUTO, &start_app_cfm);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
aicbsp_info.hwinfo_r = start_app_cfm.bootstatus & 0xFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 patch_tbl[][2] = {
|
||||
};
|
||||
|
||||
u32 syscfg_tbl_masked[][3] = {
|
||||
{0x40506024, 0x000000FF, 0x000000DF}, // for clk gate lp_level
|
||||
};
|
||||
|
||||
u32 rf_tbl_masked[][3] = {
|
||||
{0x40344058, 0x00800000, 0x00000000},// pll trx
|
||||
};
|
||||
|
||||
static int aicwifi_sys_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret, cnt;
|
||||
int syscfg_num = sizeof(syscfg_tbl_masked) / sizeof(u32) / 3;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
syscfg_tbl_masked[cnt][0], syscfg_tbl_masked[cnt][1], syscfg_tbl_masked[cnt][2]);
|
||||
if (ret) {
|
||||
printk("%x mask write fail: %d\n", syscfg_tbl_masked[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_mask_write_req(sdiodev,
|
||||
rf_tbl_masked[0][0], rf_tbl_masked[0][1], rf_tbl_masked[0][2]);
|
||||
if (ret) {
|
||||
printk("rf config %x write fail: %d\n", rf_tbl_masked[0][0], ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwifi_patch_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
const u32 rd_patch_addr = RAM_FMAC_FW_ADDR + 0x0180;
|
||||
u32 config_base;
|
||||
uint32_t start_addr = 0x1e6000;
|
||||
u32 patch_addr = start_addr;
|
||||
u32 patch_num = sizeof(patch_tbl)/4;
|
||||
struct dbg_mem_read_cfm rd_patch_addr_cfm;
|
||||
int ret = 0;
|
||||
u16 cnt = 0;
|
||||
u32 patch_addr_reg = 0x1e4d80;
|
||||
u32 patch_num_reg = 0x1e4d84;
|
||||
|
||||
if (aicbsp_info.cpmode == AICBSP_CPMODE_TEST) {
|
||||
patch_addr_reg = 0x1e4d74;
|
||||
patch_num_reg = 0x1e4d78;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_read_req(sdiodev, rd_patch_addr, &rd_patch_addr_cfm);
|
||||
if (ret) {
|
||||
printk("patch rd fail\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
config_base = rd_patch_addr_cfm.memdata;
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_addr_reg, patch_addr);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", patch_addr_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, patch_num_reg, patch_num);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", patch_num_reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < patch_num/2; cnt += 1) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, patch_tbl[cnt][0]+config_base);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt+4, patch_tbl[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt+4);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicwifi_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
if (rwnx_plat_bin_fw_upload_android(sdiodev, RAM_FMAC_FW_ADDR, aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw)) {
|
||||
printk("download wifi fw fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_patch_config(sdiodev)) {
|
||||
printk("aicwifi_patch_config fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_sys_config(sdiodev)) {
|
||||
printk("aicwifi_sys_config fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (aicwifi_start_from_bootrom(sdiodev)) {
|
||||
printk("wifi start fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 aicbsp_syscfg_tbl[][2] = {
|
||||
{0x40500014, 0x00000101}, // 1)
|
||||
{0x40500018, 0x00000109}, // 2)
|
||||
{0x40500004, 0x00000010}, // 3) the order should not be changed
|
||||
|
||||
// def CONFIG_PMIC_SETTING
|
||||
// U02 bootrom only
|
||||
{0x40040000, 0x00001AC8}, // 1) fix panic
|
||||
{0x40040084, 0x00011580},
|
||||
{0x40040080, 0x00000001},
|
||||
{0x40100058, 0x00000000},
|
||||
|
||||
{0x50000000, 0x03220204}, // 2) pmic interface init
|
||||
{0x50019150, 0x00000002}, // 3) for 26m xtal, set div1
|
||||
{0x50017008, 0x00000000}, // 4) stop wdg
|
||||
};
|
||||
|
||||
static int aicbsp_system_config(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int syscfg_num = sizeof(aicbsp_syscfg_tbl) / sizeof(u32) / 2;
|
||||
int ret, cnt;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, aicbsp_syscfg_tbl[cnt][0], aicbsp_syscfg_tbl[cnt][1]);
|
||||
if (ret) {
|
||||
sdio_err("%x write fail: %d\n", aicbsp_syscfg_tbl[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -858,79 +711,24 @@ void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev)
|
||||
|
||||
int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
const u32 mem_addr = 0x40500000;
|
||||
struct dbg_mem_read_cfm rd_mem_addr_cfm;
|
||||
if (aicbsp_info.chipinfo == NULL)
|
||||
goto err;
|
||||
|
||||
uint8_t binding_status;
|
||||
uint8_t dout[16];
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800D)
|
||||
return aicbsp_8800d_fw_init(sdiodev);
|
||||
|
||||
need_binding_verify = false;
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC || aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DW)
|
||||
return aicbsp_8800dc_fw_init(sdiodev);
|
||||
|
||||
if (rwnx_send_dbg_mem_read_req(sdiodev, mem_addr, &rd_mem_addr_cfm))
|
||||
return -1;
|
||||
|
||||
aicbsp_info.chip_rev = (u8)(rd_mem_addr_cfm.memdata >> 16);
|
||||
if (aicbsp_info.chip_rev != CHIP_REV_U02 &&
|
||||
aicbsp_info.chip_rev != CHIP_REV_U03 &&
|
||||
aicbsp_info.chip_rev != CHIP_REV_U04) {
|
||||
pr_err("aicbsp: %s, unsupport chip rev: %d\n", __func__, aicbsp_info.chip_rev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("aicbsp: %s, chip rev: %d\n", __func__, aicbsp_info.chip_rev);
|
||||
|
||||
if (aicbsp_info.chip_rev != CHIP_REV_U02)
|
||||
aicbsp_firmware_list = fw_u03;
|
||||
|
||||
if (aicbsp_system_config(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (aicbt_init(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (aicwifi_init(sdiodev))
|
||||
return -1;
|
||||
|
||||
if (need_binding_verify) {
|
||||
printk("aicbsp: crypto data %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
binding_enc_data[0], binding_enc_data[1], binding_enc_data[2], binding_enc_data[3],
|
||||
binding_enc_data[4], binding_enc_data[5], binding_enc_data[6], binding_enc_data[7],
|
||||
binding_enc_data[8], binding_enc_data[9], binding_enc_data[10], binding_enc_data[11],
|
||||
binding_enc_data[12], binding_enc_data[13], binding_enc_data[14], binding_enc_data[15]);
|
||||
|
||||
/* calculate verify data from crypto data */
|
||||
if (wcn_bind_verify_calculate_verify_data(binding_enc_data, dout)) {
|
||||
pr_err("aicbsp: %s, binding encrypt data incorrect\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printk("aicbsp: verify data %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
||||
dout[0], dout[1], dout[2], dout[3],
|
||||
dout[4], dout[5], dout[6], dout[7],
|
||||
dout[8], dout[9], dout[10], dout[11],
|
||||
dout[12], dout[13], dout[14], dout[15]);
|
||||
|
||||
if (rwnx_send_dbg_binding_req(sdiodev, dout, &binding_status)) {
|
||||
pr_err("aicbsp: %s, send binding request failn", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (binding_status) {
|
||||
pr_err("aicbsp: %s, binding verify fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (aicwf_sdio_writeb(sdiodev, SDIOWIFI_WAKEUP_REG, 4)) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_WAKEUP_REG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
pr_err("%s no matched chip found\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int aicbsp_get_feature(struct aicbsp_feature_t *feature)
|
||||
{
|
||||
feature->cpmode = aicbsp_info.cpmode;
|
||||
feature->chipinfo = aicbsp_info.chipinfo;
|
||||
feature->sdio_clock = FEATURE_SDIO_CLOCK;
|
||||
feature->sdio_phase = FEATURE_SDIO_PHASE;
|
||||
feature->hwinfo = aicbsp_info.hwinfo;
|
||||
@ -938,3 +736,81 @@ int aicbsp_get_feature(struct aicbsp_feature_t *feature)
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aicbsp_get_feature);
|
||||
|
||||
#ifdef AICBSP_RESV_MEM_SUPPORT
|
||||
static struct skb_buff_pool resv_skb[] = {
|
||||
{AIC_RESV_MEM_TXDATA, 1536*64, "resv_mem_txdata", 0, NULL},
|
||||
};
|
||||
|
||||
int aicbsp_resv_mem_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < sizeof(resv_skb) / sizeof(resv_skb[0]); i++) {
|
||||
resv_skb[i].skb = dev_alloc_skb(resv_skb[i].size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicbsp_resv_mem_deinit(void)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < sizeof(resv_skb) / sizeof(resv_skb[0]); i++) {
|
||||
if (resv_skb[i].used == 0 && resv_skb[i].skb)
|
||||
dev_kfree_skb(resv_skb[i].skb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id)
|
||||
{
|
||||
if (resv_skb[id].size < length) {
|
||||
pr_err("aicbsp: %s, no enough mem\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (resv_skb[id].used) {
|
||||
pr_err("aicbsp: %s, mem in use\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (resv_skb[id].skb == NULL) {
|
||||
pr_err("aicbsp: %s, mem not initialazed\n", __func__);
|
||||
resv_skb[id].skb = dev_alloc_skb(resv_skb[id].size);
|
||||
if (resv_skb[id].skb == NULL) {
|
||||
pr_err("aicbsp: %s, mem reinitial still fail\n", __func__);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
printk("aicbsp: %s, alloc %s succuss, id: %d, size: %d\n", __func__,
|
||||
resv_skb[id].name, resv_skb[id].id, resv_skb[id].size);
|
||||
|
||||
resv_skb[id].used = 1;
|
||||
return resv_skb[id].skb;
|
||||
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aicbsp_resv_mem_alloc_skb);
|
||||
|
||||
void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id)
|
||||
{
|
||||
resv_skb[id].used = 0;
|
||||
printk("aicbsp: %s, free %s succuss, id: %d, size: %d\n", __func__,
|
||||
resv_skb[id].name, resv_skb[id].id, resv_skb[id].size);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(aicbsp_resv_mem_kfree_skb);
|
||||
|
||||
#else
|
||||
|
||||
int aicbsp_resv_mem_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicbsp_resv_mem_deinit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -201,9 +201,17 @@ enum dbg_msg_tag {
|
||||
DBG_MAX,
|
||||
};
|
||||
|
||||
enum mm_msg_tag {
|
||||
MM_SET_RF_CONFIG_REQ = 103,
|
||||
MM_SET_RF_CONFIG_CFM,
|
||||
MM_MAX
|
||||
};
|
||||
|
||||
enum {
|
||||
HOST_START_APP_AUTO = 1,
|
||||
HOST_START_APP_CUSTOM
|
||||
HOST_START_APP_CUSTOM,
|
||||
HOST_START_APP_FNCALL = 4,
|
||||
HOST_START_APP_DUMMY = 5,
|
||||
};
|
||||
|
||||
struct dbg_mem_block_write_req {
|
||||
@ -272,6 +280,14 @@ struct dbg_binding_req {
|
||||
u8 driver_data[16];
|
||||
};
|
||||
|
||||
struct mm_set_rf_config_req {
|
||||
u8 table_sel;
|
||||
u8 table_ofst;
|
||||
u8 table_num;
|
||||
u8 deft_page;
|
||||
u32 data[64];
|
||||
};
|
||||
|
||||
int rwnx_send_dbg_mem_read_req(struct aic_sdio_dev *sdiodev, u32 mem_addr,
|
||||
struct dbg_mem_read_cfm *cfm);
|
||||
int rwnx_send_dbg_mem_block_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr,
|
||||
@ -283,19 +299,18 @@ int rwnx_send_dbg_start_app_req(struct aic_sdio_dev *sdiodev, u32 boot_addr, u32
|
||||
|
||||
int rwnx_send_dbg_binding_req(struct aic_sdio_dev *sdiodev, u8 *dout, u8 *binding_status);
|
||||
void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg);
|
||||
int rwnx_send_rf_config_req(struct aic_sdio_dev *sdiodev, u8 ofst, u8 sel, u8 *tbl, u16 len);
|
||||
|
||||
int aicbsp_platform_init(struct aic_sdio_dev *sdiodev);
|
||||
void aicbsp_platform_deinit(struct aic_sdio_dev *sdiodev);
|
||||
int aicbsp_driver_fw_init(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
#define RAM_FMAC_FW_ADDR 0x00120000
|
||||
#define FW_RAM_ADID_BASE_ADDR 0x00161928
|
||||
#define FW_RAM_ADID_BASE_ADDR_U03 0x00161928
|
||||
#define FW_RAM_PATCH_BASE_ADDR 0x00100000
|
||||
int aicbsp_resv_mem_init(void);
|
||||
int aicbsp_resv_mem_deinit(void);
|
||||
|
||||
#define AICBT_PT_TAG "AICBT_PT_TAG"
|
||||
|
||||
enum aicbt_patch_table_type {
|
||||
AICBT_PT_INF = 0x0,
|
||||
AICBT_PT_TRAP = 0x1,
|
||||
AICBT_PT_B4,
|
||||
AICBT_PT_BTMODE,
|
||||
@ -339,18 +354,16 @@ enum aicbt_uart_flowctrl_type {
|
||||
AICBT_UART_FLOWCTRL_ENABLE, // uart with flow ctrl
|
||||
};
|
||||
|
||||
enum aicbsp_cpmode_type {
|
||||
AICBSP_CPMODE_WORK,
|
||||
AICBSP_CPMODE_TEST,
|
||||
AICBSP_CPMODE_MAX,
|
||||
};
|
||||
|
||||
enum chip_rev {
|
||||
CHIP_REV_U02 = 3,
|
||||
CHIP_REV_U03 = 7,
|
||||
CHIP_REV_U04 = 7,
|
||||
};
|
||||
|
||||
///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl;
|
||||
///pwr lvl:20(min), 30 , 40 , 50 , 60(max)
|
||||
#define AICBT_TXPWR_LVL 0x00006020
|
||||
|
||||
#define AICBSP_HWINFO_DEFAULT (-1)
|
||||
#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK
|
||||
|
||||
@ -358,6 +371,8 @@ enum chip_rev {
|
||||
#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_UART
|
||||
#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_1_5M
|
||||
#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
|
||||
#define AICBT_LPM_ENABLE_DEFAULT 0
|
||||
#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL
|
||||
|
||||
#define FEATURE_SDIO_CLOCK 70000000 // 0: default, other: target clock rate
|
||||
#define FEATURE_SDIO_PHASE 2 // 0: default, 2: 180°
|
||||
@ -375,6 +390,10 @@ struct aicbt_info_t {
|
||||
uint32_t btport;
|
||||
uint32_t uart_baud;
|
||||
uint32_t uart_flowctrl;
|
||||
uint32_t lpm_enable;
|
||||
uint32_t txpwr_lvl;
|
||||
uint32_t addr_adid;
|
||||
uint32_t addr_patch;
|
||||
};
|
||||
|
||||
struct aicbsp_firmware {
|
||||
@ -383,20 +402,32 @@ struct aicbsp_firmware {
|
||||
const char *bt_patch;
|
||||
const char *bt_table;
|
||||
const char *wl_fw;
|
||||
const char *wl_table;
|
||||
};
|
||||
|
||||
struct aicbsp_info_t {
|
||||
int hwinfo;
|
||||
int hwinfo_r;
|
||||
uint32_t cpmode;
|
||||
uint32_t chip_rev;
|
||||
bool fwlog_en;
|
||||
struct device_match_entry *chipinfo;
|
||||
};
|
||||
|
||||
int aicbsp_8800d_fw_init(struct aic_sdio_dev *sdiodev);
|
||||
int aicbsp_8800dc_fw_init(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
int wcn_bind_verify_calculate_verify_data(uint8_t *din, uint8_t *dout);
|
||||
int rwnx_plat_bin_fw_upload_android(struct aic_sdio_dev *sdiodev, u32 fw_addr, const char *filename);
|
||||
int aicbt_patch_table_free(struct aicbt_patch_table **head);
|
||||
struct aicbt_patch_table *aicbt_patch_table_alloc(const char *filename);
|
||||
int aicbt_patch_info_unpack(struct aicbt_patch_table *head, struct aicbt_info_t *aicbt_info);
|
||||
int aicbt_patch_table_load(struct aic_sdio_dev *sdiodev, struct aicbt_info_t *btcfg, struct aicbt_patch_table *head);
|
||||
|
||||
extern u8 binding_enc_data[16];
|
||||
extern bool need_binding_verify;
|
||||
|
||||
extern struct aicbsp_info_t aicbsp_info;
|
||||
extern struct mutex aicbsp_power_lock;
|
||||
extern const struct aicbsp_firmware *aicbsp_firmware_list;
|
||||
extern const struct aicbsp_firmware fw_u02[];
|
||||
extern const struct aicbsp_firmware fw_u03[];
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef __AIC_BSP_EXPORT_H
|
||||
#define __AIC_BSP_EXPORT_H
|
||||
|
||||
#define AICBSP_RESV_MEM_SUPPORT
|
||||
|
||||
enum aicbsp_subsys {
|
||||
AIC_BLUETOOTH,
|
||||
AIC_WIFI,
|
||||
@ -11,14 +13,53 @@ enum aicbsp_pwr_state {
|
||||
AIC_PWR_ON,
|
||||
};
|
||||
|
||||
enum skb_buff_id {
|
||||
AIC_RESV_MEM_TXDATA,
|
||||
};
|
||||
|
||||
enum AIC_PRODUCT_ID {
|
||||
PRODUCT_ID_AIC8800D = 0,
|
||||
PRODUCT_ID_AIC8800DC,
|
||||
PRODUCT_ID_AIC8800DW,
|
||||
PRODUCT_ID_AIC8800D80
|
||||
};
|
||||
|
||||
enum aicbsp_cpmode_type {
|
||||
AICBSP_CPMODE_WORK,
|
||||
AICBSP_CPMODE_TEST,
|
||||
AICBSP_CPMODE_MAX,
|
||||
};
|
||||
|
||||
struct device_match_entry {
|
||||
u16 vid;
|
||||
u16 pid;
|
||||
u16 chipid;
|
||||
char *name;
|
||||
u16 rev;
|
||||
u16 subrev;
|
||||
u16 mcuid;
|
||||
};
|
||||
|
||||
struct skb_buff_pool {
|
||||
uint32_t id;
|
||||
uint32_t size;
|
||||
const char *name;
|
||||
uint8_t used;
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
struct aicbsp_feature_t {
|
||||
int hwinfo;
|
||||
uint32_t sdio_clock;
|
||||
uint8_t sdio_phase;
|
||||
bool fwlog_en;
|
||||
struct device_match_entry *chipinfo;
|
||||
uint8_t cpmode;
|
||||
};
|
||||
|
||||
int aicbsp_set_subsys(int, int);
|
||||
int aicbsp_get_feature(struct aicbsp_feature_t *feature);
|
||||
struct sk_buff *aicbsp_resv_mem_alloc_skb(unsigned int length, uint32_t id);
|
||||
void aicbsp_resv_mem_kfree_skb(struct sk_buff *skb, uint32_t id);
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,45 +13,21 @@
|
||||
#define DRV_AUTHOR "AICSemi"
|
||||
#define DRV_VERS_MOD "1.0"
|
||||
|
||||
#if defined(AICWF_SDIO_SUPPORT)
|
||||
#define DRV_TYPE_NAME "sdio"
|
||||
#elif defined(AICWF_USB_SUPPORT)
|
||||
#define DRV_TYPE_NAME "usb"
|
||||
#else
|
||||
#define DRV_TYPE_NAME "unknow"
|
||||
#endif
|
||||
|
||||
#define DRV_RELEASE_DATE "20221108"
|
||||
#define DRV_PATCH_LEVEL "001"
|
||||
#define DRV_RELEASE_TAG "aic-bsp-" DRV_TYPE_NAME "-" DRV_RELEASE_DATE "-" DRV_PATCH_LEVEL
|
||||
|
||||
static struct platform_device *aicbsp_pdev;
|
||||
|
||||
const struct aicbsp_firmware *aicbsp_firmware_list = fw_u02;
|
||||
|
||||
const struct aicbsp_firmware fw_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u02)",
|
||||
.bt_adid = "fw_adid.bin",
|
||||
.bt_patch = "fw_patch.bin",
|
||||
.bt_table = "fw_patch_table.bin",
|
||||
.wl_fw = "fmacfw.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u02)",
|
||||
.bt_adid = "fw_adid.bin",
|
||||
.bt_patch = "fw_patch.bin",
|
||||
.bt_table = "fw_patch_table.bin",
|
||||
.wl_fw = "fmacfw_rf.bin"
|
||||
},
|
||||
};
|
||||
|
||||
const struct aicbsp_firmware fw_u03[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u03/u04)",
|
||||
.bt_adid = "fw_adid_u03.bin",
|
||||
.bt_patch = "fw_patch_u03.bin",
|
||||
.bt_table = "fw_patch_table_u03.bin",
|
||||
.wl_fw = "fmacfw.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u03/u04)",
|
||||
.bt_adid = "fw_adid_u03.bin",
|
||||
.bt_patch = "fw_patch_u03.bin",
|
||||
.bt_table = "fw_patch_table_u03.bin",
|
||||
.wl_fw = "fmacfw_rf.bin"
|
||||
},
|
||||
};
|
||||
const struct aicbsp_firmware *aicbsp_firmware_list;
|
||||
|
||||
struct aicbsp_info_t aicbsp_info = {
|
||||
.hwinfo_r = AICBSP_HWINFO_DEFAULT,
|
||||
@ -80,6 +56,11 @@ static ssize_t cpmode_show(struct device *dev,
|
||||
ssize_t count = 0;
|
||||
uint8_t i = 0;
|
||||
|
||||
if (aicbsp_firmware_list == NULL) {
|
||||
count += sprintf(&buf[count], "Wi-Fi not opened since system power on\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
count += sprintf(&buf[count], "Support mode value:\n");
|
||||
|
||||
for (i = 0; i < AICBSP_CPMODE_MAX; i++) {
|
||||
@ -109,7 +90,7 @@ static ssize_t cpmode_store(struct device *dev,
|
||||
}
|
||||
|
||||
aicbsp_info.cpmode = val;
|
||||
printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc);
|
||||
printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list ? aicbsp_firmware_list[val].desc : "unknow");
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -119,11 +100,12 @@ static ssize_t hwinfo_show(struct device *dev,
|
||||
{
|
||||
ssize_t count = 0;
|
||||
|
||||
count += sprintf(&buf[count], "chip hw rev: ");
|
||||
if (aicbsp_info.hwinfo_r < 0)
|
||||
count += sprintf(&buf[count], "-1(not avalible)\n");
|
||||
if (aicbsp_info.chipinfo == NULL)
|
||||
count += sprintf(&buf[count], "chip info not avalible)\n");
|
||||
else
|
||||
count += sprintf(&buf[count], "0x%02X\n", aicbsp_info.chip_rev);
|
||||
count += sprintf(&buf[count], "chip name: %s, id: 0x%02X, rev: 0x%02X, subrev: 0x%02X\n",
|
||||
aicbsp_info.chipinfo->name, aicbsp_info.chipinfo->chipid,
|
||||
aicbsp_info.chipinfo->rev, aicbsp_info.chipinfo->subrev);
|
||||
|
||||
count += sprintf(&buf[count], "hwinfo read: ");
|
||||
if (aicbsp_info.hwinfo_r < 0)
|
||||
@ -270,7 +252,9 @@ static int __init aicbsp_init(void)
|
||||
{
|
||||
int ret;
|
||||
printk("%s\n", __func__);
|
||||
printk("%s, Driver Release Tag: %s\n", __func__, DRV_RELEASE_TAG);
|
||||
|
||||
aicbsp_resv_mem_init();
|
||||
mutex_init(&aicbsp_power_lock);
|
||||
ret = platform_driver_register(&aicbsp_driver);
|
||||
if (ret) {
|
||||
@ -312,6 +296,7 @@ err1:
|
||||
platform_driver_unregister(&aicbsp_driver);
|
||||
err0:
|
||||
mutex_destroy(&aicbsp_power_lock);
|
||||
aicbsp_resv_mem_deinit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -322,6 +307,7 @@ static void __exit aicbsp_exit(void)
|
||||
platform_device_del(aicbsp_pdev);
|
||||
platform_driver_unregister(&aicbsp_driver);
|
||||
mutex_destroy(&aicbsp_power_lock);
|
||||
aicbsp_resv_mem_deinit();
|
||||
printk("%s\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
@ -33,6 +33,15 @@ static struct aic_sdio_dev *aicbsp_sdiodev;
|
||||
static struct semaphore *aicbsp_notify_semaphore;
|
||||
static const struct sdio_device_id aicbsp_sdmmc_ids[];
|
||||
|
||||
static struct device_match_entry aicdev_match_table[] = {
|
||||
{0x544a, 0x0146, PRODUCT_ID_AIC8800D, "aic8800d", 0, 0}, // 8800d in bootloader mode
|
||||
{0xc8a1, 0xc18d, PRODUCT_ID_AIC8800DC, "aic8800dc", 0, 0}, // 8800dc in bootloader mode
|
||||
// {0x5449, 0x0145, PRODUCT_ID_AIC8800DW, "aic8800dw", 0, 0},
|
||||
// {0x5449, 0x0145, PRODUCT_ID_AIC8800D80, "aic8800d80", 0, 0},
|
||||
};
|
||||
|
||||
static struct device_match_entry *aic_matched_ic;
|
||||
|
||||
static int aicbsp_dummy_probe(struct sdio_func *func, const struct sdio_device_id *id)
|
||||
{
|
||||
if (func && (func->num != 2))
|
||||
@ -142,7 +151,7 @@ void *aicbsp_get_drvdata(void *args)
|
||||
(void)args;
|
||||
if (aicbsp_sdiodev)
|
||||
return aicbsp_sdiodev->bus_if;
|
||||
return NULL;
|
||||
return dev_get_drvdata((const struct device *)args);
|
||||
}
|
||||
|
||||
static int aicbsp_sdio_probe(struct sdio_func *func,
|
||||
@ -152,12 +161,22 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
|
||||
struct aic_sdio_dev *sdiodev;
|
||||
struct aicwf_bus *bus_if;
|
||||
int err = -ENODEV;
|
||||
int i = 0;
|
||||
|
||||
sdio_dbg("%s:%d\n", __func__, func->num);
|
||||
if (func->num != 2) {
|
||||
return err;
|
||||
for (i = 0; i < sizeof(aicdev_match_table) / sizeof(aicdev_match_table[0]); i++) {
|
||||
if (func->vendor == aicdev_match_table[i].vid && func->device == aicdev_match_table[i].pid) {
|
||||
aic_matched_ic = &aicdev_match_table[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (aic_matched_ic == NULL)
|
||||
return err;
|
||||
|
||||
sdio_dbg("%s:%d, matched chip: %s\n", __func__, func->num, aic_matched_ic ? aic_matched_ic->name : "none");
|
||||
if (func->num != 2)
|
||||
return err;
|
||||
|
||||
func = func->card->sdio_func[1 - 1]; //replace 2 with 1
|
||||
host = func->card->host;
|
||||
sdio_dbg("%s after replace:%d\n", __func__, func->num);
|
||||
@ -175,9 +194,16 @@ static int aicbsp_sdio_probe(struct sdio_func *func,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sdiodev->func = func;
|
||||
aicbsp_info.chipinfo = aic_matched_ic;
|
||||
sdiodev->func[0] = func;
|
||||
sdiodev->bus_if = bus_if;
|
||||
bus_if->bus_priv.sdio = sdiodev;
|
||||
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC) {
|
||||
sdiodev->func[1] = func->card->sdio_func[1];
|
||||
dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
|
||||
}
|
||||
|
||||
dev_set_drvdata(&func->dev, bus_if);
|
||||
sdiodev->dev = &func->dev;
|
||||
err = aicwf_sdio_func_init(sdiodev);
|
||||
@ -201,6 +227,7 @@ fail:
|
||||
dev_set_drvdata(&func->dev, NULL);
|
||||
kfree(sdiodev);
|
||||
kfree(bus_if);
|
||||
aic_matched_ic = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -222,19 +249,20 @@ static void aicbsp_sdio_remove(struct sdio_func *func)
|
||||
goto done;
|
||||
}
|
||||
|
||||
func = sdiodev->func;
|
||||
func = sdiodev->func[0];
|
||||
host = func->card->host;
|
||||
host->caps &= ~MMC_CAP_NONREMOVABLE;
|
||||
|
||||
aicwf_sdio_release(sdiodev);
|
||||
aicwf_sdio_func_deinit(sdiodev);
|
||||
|
||||
dev_set_drvdata(&sdiodev->func->dev, NULL);
|
||||
dev_set_drvdata(&sdiodev->func[0]->dev, NULL);
|
||||
kfree(sdiodev);
|
||||
kfree(bus_if);
|
||||
|
||||
done:
|
||||
aicbsp_sdiodev = NULL;
|
||||
aic_matched_ic = NULL;
|
||||
sdio_dbg("%s done\n", __func__);
|
||||
}
|
||||
|
||||
@ -270,7 +298,8 @@ static int aicbsp_sdio_resume(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct sdio_device_id aicbsp_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN)},
|
||||
{SDIO_DEVICE(0x544a, 0x0146)}, // aic8800d in bootloader mode
|
||||
{SDIO_DEVICE(0xc8a1, 0xc18d)}, // aic8800dc in bootloader mode
|
||||
{ },
|
||||
};
|
||||
|
||||
@ -352,27 +381,34 @@ void aicbsp_sdio_exit(void)
|
||||
|
||||
void aicbsp_sdio_release(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int funcnum = 1, i = 0;
|
||||
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC)
|
||||
funcnum = 2;
|
||||
|
||||
sdiodev->bus_if->state = BUS_DOWN_ST;
|
||||
sdio_claim_host(sdiodev->func);
|
||||
sdio_release_irq(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func);
|
||||
for (i = 0; i < funcnum; i++) {
|
||||
sdio_claim_host(sdiodev->func[i]);
|
||||
sdio_release_irq(sdiodev->func[i]);
|
||||
sdio_release_host(sdiodev->func[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int aicwf_sdio_readb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 *val)
|
||||
int aicwf_sdio_readb(struct sdio_func *func, uint regaddr, u8 *val)
|
||||
{
|
||||
int ret;
|
||||
sdio_claim_host(sdiodev->func);
|
||||
*val = sdio_readb(sdiodev->func, regaddr, &ret);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_claim_host(func);
|
||||
*val = sdio_readb(func, regaddr, &ret);
|
||||
sdio_release_host(func);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val)
|
||||
int aicwf_sdio_writeb(struct sdio_func *func, uint regaddr, u8 val)
|
||||
{
|
||||
int ret;
|
||||
sdio_claim_host(sdiodev->func);
|
||||
sdio_writeb(sdiodev->func, val, regaddr, &ret);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_claim_host(func);
|
||||
sdio_writeb(func, val, regaddr, &ret);
|
||||
sdio_release_host(func);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -383,7 +419,7 @@ int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev)
|
||||
u32 count = 0;
|
||||
|
||||
while (true) {
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_FLOW_CTRL_REG, &fc_reg);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_FLOW_CTRL_REG, &fc_reg);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
@ -413,9 +449,20 @@ int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
sdio_claim_host(sdiodev->func);
|
||||
ret = sdio_writesb(sdiodev->func, 7, buf, count);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
ret = sdio_writesb(sdiodev->func[0], 7, buf, count);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicwf_sdio_send_msg(struct aic_sdio_dev *sdiodev, u8 *buf, uint count)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
ret = sdio_writesb(sdiodev->func[1], 7, buf, count);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -429,9 +476,30 @@ int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf,
|
||||
return -EINVAL;;
|
||||
}
|
||||
|
||||
sdio_claim_host(sdiodev->func);
|
||||
ret = sdio_readsb(sdiodev->func, skbbuf->data, 8, size);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
ret = sdio_readsb(sdiodev->func[0], skbbuf->data, 8, size);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
skbbuf->len = size;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicwf_sdio_recv_msg(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf,
|
||||
u32 size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if ((!skbbuf) || (!size)) {
|
||||
return -EINVAL;;
|
||||
}
|
||||
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
ret = sdio_readsb(sdiodev->func[1], skbbuf->data, 8, size);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -451,7 +519,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
|
||||
//if (sdiodev->rwnx_hw->vif_started) {
|
||||
down(&sdiodev->pwrctl_wakeup_sema);
|
||||
while (write_retry) {
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_WAKEUP_REG, 1);
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_WAKEUP_REG, 1);
|
||||
if (ret) {
|
||||
txrx_err("sdio wakeup fail\n");
|
||||
ret = -1;
|
||||
@ -459,7 +527,7 @@ int aicwf_sdio_wakeup(struct aic_sdio_dev *sdiodev)
|
||||
read_retry = 10;
|
||||
while (read_retry) {
|
||||
u8 val;
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_SLEEP_REG, &val);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_SLEEP_REG, &val);
|
||||
if ((ret == 0) && (val & 0x10)) {
|
||||
break;
|
||||
}
|
||||
@ -490,7 +558,7 @@ int aicwf_sdio_sleep_allow(struct aic_sdio_dev *sdiodev)
|
||||
struct aicwf_bus *bus_if = sdiodev->bus_if;
|
||||
|
||||
if (bus_if->state == BUS_DOWN_ST) {
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_SLEEP_REG, 0x10);
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_SLEEP_REG, 0x10);
|
||||
if (ret) {
|
||||
sdio_err("Write sleep fail!\n");
|
||||
}
|
||||
@ -501,7 +569,7 @@ int aicwf_sdio_sleep_allow(struct aic_sdio_dev *sdiodev)
|
||||
if (sdiodev->state == SDIO_ACTIVE_ST) {
|
||||
{
|
||||
sdio_dbg("s\n");
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_SLEEP_REG, 0x10);
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_SLEEP_REG, 0x10);
|
||||
if (ret)
|
||||
sdio_err("Write sleep fail!\n");
|
||||
}
|
||||
@ -573,7 +641,7 @@ static int aicwf_sdio_intr_get_len_bytemode(struct aic_sdio_dev *sdiodev, u8 *by
|
||||
if (sdiodev->bus_if->state == BUS_DOWN_ST) {
|
||||
*byte_len = 0;
|
||||
} else {
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_BYTEMODE_LEN_REG, byte_len);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_BYTEMODE_LEN_REG, byte_len);
|
||||
sdiodev->rx_priv->data_len = (*byte_len)*4;
|
||||
}
|
||||
|
||||
@ -636,6 +704,33 @@ struct sk_buff *aicwf_sdio_readframes(struct aic_sdio_dev *sdiodev)
|
||||
return skb;
|
||||
}
|
||||
|
||||
struct sk_buff *aicwf_sdio_readmessages(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 size = 0;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct aicwf_bus *bus_if = dev_get_drvdata(sdiodev->dev);
|
||||
|
||||
if (bus_if->state == BUS_DOWN_ST) {
|
||||
sdio_dbg("bus down\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = sdiodev->rx_priv->data_len;
|
||||
skb = __dev_alloc_skb(size, GFP_KERNEL);
|
||||
if (!skb) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = aicwf_sdio_recv_msg(sdiodev, skb, size);
|
||||
if (ret) {
|
||||
dev_kfree_skb(skb);
|
||||
skb = NULL;
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int aicwf_sdio_tx_msg(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int err = 0;
|
||||
@ -663,22 +758,31 @@ static int aicwf_sdio_tx_msg(struct aic_sdio_dev *sdiodev)
|
||||
} else
|
||||
len = payload_len;
|
||||
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
while ((buffer_cnt <= 0 || len > (buffer_cnt * BUFFER_SIZE)) && retry < 5) {
|
||||
retry++;
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800D) {
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
while ((buffer_cnt <= 0 || len > (buffer_cnt * BUFFER_SIZE)) && retry < 5) {
|
||||
retry++;
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
}
|
||||
}
|
||||
|
||||
down(&sdiodev->tx_priv->cmd_txsema);
|
||||
if (buffer_cnt > 0 && len < (buffer_cnt * BUFFER_SIZE)) {
|
||||
err = aicwf_sdio_send_pkt(sdiodev, payload, len);
|
||||
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800D) {
|
||||
if (buffer_cnt > 0 && len < (buffer_cnt * BUFFER_SIZE)) {
|
||||
err = aicwf_sdio_send_pkt(sdiodev, payload, len);
|
||||
if (err) {
|
||||
sdio_err("aicwf_sdio_send_pkt fail%d\n", err);
|
||||
}
|
||||
} else {
|
||||
up(&sdiodev->tx_priv->cmd_txsema);
|
||||
sdio_err("tx msg fc retry fail\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC) {
|
||||
err = aicwf_sdio_send_msg(sdiodev, payload, len);
|
||||
if (err) {
|
||||
sdio_err("aicwf_sdio_send_pkt fail%d\n", err);
|
||||
}
|
||||
} else {
|
||||
up(&sdiodev->tx_priv->cmd_txsema);
|
||||
sdio_err("tx msg fc retry fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdiodev->tx_priv->cmd_txstate = false;
|
||||
@ -736,7 +840,9 @@ static void aicwf_sdio_tx_process(struct aic_sdio_dev *sdiodev)
|
||||
return;
|
||||
}
|
||||
|
||||
sdiodev->tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
if (!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq))
|
||||
sdiodev->tx_priv->fw_avail_bufcnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
|
||||
while (!aicwf_is_framequeue_empty(&sdiodev->tx_priv->txq)) {
|
||||
aicwf_sdio_send(sdiodev->tx_priv);
|
||||
if (sdiodev->tx_priv->cmd_txstate)
|
||||
@ -797,7 +903,7 @@ static int aicwf_sdio_bus_txmsg(struct device *dev, u8 *msg, uint msglen)
|
||||
|
||||
if (sdiodev->tx_priv->cmd_txstate) {
|
||||
int timeout = msecs_to_jiffies(CMD_TX_TIMEOUT);
|
||||
ret = wait_event_interruptible_timeout(sdiodev->tx_priv->cmd_txdone_wait, \
|
||||
ret = wait_event_timeout(sdiodev->tx_priv->cmd_txdone_wait, \
|
||||
!(sdiodev->tx_priv->cmd_txstate), timeout);
|
||||
}
|
||||
|
||||
@ -959,20 +1065,37 @@ static int aicwf_sdio_bus_start(struct device *dev)
|
||||
struct aic_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
int ret = 0;
|
||||
|
||||
#if 1
|
||||
sdio_claim_host(sdiodev->func);
|
||||
sdio_claim_irq(sdiodev->func, aicwf_sdio_hal_irqhandler);
|
||||
#else
|
||||
//since we have func2 we don't register irq handler
|
||||
sdio_claim_irq(sdiodev->func, NULL);
|
||||
sdiodev->func->irq_handler = (sdio_irq_handler_t *)aicwf_sdio_hal_irqhandler;
|
||||
#endif
|
||||
//enable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x07);
|
||||
sdio_release_host(sdiodev->func);
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800D) {
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
sdio_claim_irq(sdiodev->func[0], aicwf_sdio_hal_irqhandler);
|
||||
//enable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_INTR_CONFIG_REG, 0x07);
|
||||
if (ret != 0)
|
||||
sdio_err("intr register failed:%d\n", ret);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
} else if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC) {
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
|
||||
if (ret != 0)
|
||||
sdio_err("intr register failed:%d\n", ret);
|
||||
//since we have func2 we don't register irq handler
|
||||
sdio_claim_irq(sdiodev->func[0], NULL);
|
||||
sdio_claim_irq(sdiodev->func[1], NULL);
|
||||
|
||||
sdiodev->func[0]->irq_handler = (sdio_irq_handler_t *)aicwf_sdio_hal_irqhandler;
|
||||
sdiodev->func[1]->irq_handler = (sdio_irq_handler_t *)aicwf_sdio_hal_irqhandler_func2;
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
|
||||
//enable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_INTR_CONFIG_REG, 0x07);
|
||||
|
||||
if (ret != 0)
|
||||
sdio_err("intr register failed:%d\n", ret);
|
||||
|
||||
//enable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[1], SDIOWIFI_INTR_CONFIG_REG, 0x07);
|
||||
|
||||
if (ret != 0)
|
||||
sdio_err("func2 intr register failed:%d\n", ret);
|
||||
}
|
||||
|
||||
bus_if->state = BUS_UP_ST;
|
||||
|
||||
@ -1068,10 +1191,10 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
|
||||
return;
|
||||
}
|
||||
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
while (ret || (intstatus & SDIO_OTHER_INTERRUPT)) {
|
||||
sdio_err("ret=%d, intstatus=%x\r\n", ret, intstatus);
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
}
|
||||
sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE;
|
||||
|
||||
@ -1093,6 +1216,52 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
|
||||
complete(&bus_if->busrx_trgg);
|
||||
}
|
||||
|
||||
void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func)
|
||||
{
|
||||
struct aicwf_bus *bus_if = aicbsp_sdiodev->bus_if;
|
||||
struct aic_sdio_dev *sdiodev = aicbsp_sdiodev;
|
||||
u8 intstatus = 0;
|
||||
u8 byte_len = 0;
|
||||
struct sk_buff *pkt = NULL;
|
||||
int ret;
|
||||
|
||||
if (!bus_if || bus_if->state == BUS_DOWN_ST) {
|
||||
if (!bus_if)
|
||||
sdio_err("bus if none\n");
|
||||
else
|
||||
sdio_err("bus state down\n");
|
||||
sdio_err("bus err\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = aicwf_sdio_readb(sdiodev->func[1], SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
|
||||
while (ret || (intstatus & SDIO_OTHER_INTERRUPT)) {
|
||||
sdio_err("ret=%d, intstatus=%x\r\n", ret, intstatus);
|
||||
ret = aicwf_sdio_readb(sdiodev->func[0], SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
}
|
||||
sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE;
|
||||
if (intstatus > 0) {
|
||||
if (intstatus < 64) {
|
||||
pkt = aicwf_sdio_readmessages(sdiodev);
|
||||
} else {
|
||||
sdio_info("byte mode len=%d\r\n", byte_len);
|
||||
|
||||
aicwf_sdio_intr_get_len_bytemode(sdiodev, &byte_len);//byte_len must<= 128
|
||||
pkt = aicwf_sdio_readmessages(sdiodev);
|
||||
}
|
||||
} else {
|
||||
#ifndef CONFIG_PLATFORM_ALLWINNER
|
||||
sdio_err("Interrupt but no data\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (pkt)
|
||||
aicwf_sdio_enq_rxpkt(sdiodev, pkt);
|
||||
|
||||
complete(&bus_if->busrx_trgg);
|
||||
}
|
||||
|
||||
void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration)
|
||||
{
|
||||
uint timeout;
|
||||
@ -1123,20 +1292,26 @@ void aicwf_sdio_release(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
struct aicwf_bus *bus_if;
|
||||
int ret = 0;
|
||||
int funcnum = 1, i = 0;
|
||||
|
||||
sdio_dbg("%s\n", __func__);
|
||||
|
||||
bus_if = sdiodev->bus_if;
|
||||
bus_if->state = BUS_DOWN_ST;
|
||||
|
||||
sdio_claim_host(sdiodev->func);
|
||||
//disable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_INTR_CONFIG_REG, 0x0);
|
||||
if (ret < 0) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC)
|
||||
funcnum = 2;
|
||||
|
||||
for (i = 0; i < funcnum; i++) {
|
||||
sdio_claim_host(sdiodev->func[i]);
|
||||
//disable sdio interrupt
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[i], SDIOWIFI_INTR_CONFIG_REG, 0x0);
|
||||
if (ret < 0) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_INTR_CONFIG_REG);
|
||||
}
|
||||
sdio_release_irq(sdiodev->func[i]);
|
||||
sdio_release_host(sdiodev->func[i]);
|
||||
}
|
||||
sdio_release_irq(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func);
|
||||
|
||||
if (sdiodev->dev)
|
||||
aicwf_bus_deinit(sdiodev->dev);
|
||||
@ -1160,25 +1335,25 @@ int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev)
|
||||
struct aicbsp_feature_t feature;
|
||||
|
||||
aicbsp_get_feature(&feature);
|
||||
host = sdiodev->func->card->host;
|
||||
host = sdiodev->func[0]->card->host;
|
||||
|
||||
sdio_claim_host(sdiodev->func);
|
||||
sdiodev->func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
|
||||
sdio_f0_writeb(sdiodev->func, feature.sdio_phase, 0x13, &ret);
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
sdiodev->func[0]->card->quirks |= MMC_QUIRK_LENIENT_FN0;
|
||||
sdio_f0_writeb(sdiodev->func[0], feature.sdio_phase, 0x13, &ret);
|
||||
if (ret < 0) {
|
||||
sdio_err("write func0 fail %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdio_set_block_size(sdiodev->func, SDIOWIFI_FUNC_BLOCKSIZE);
|
||||
ret = sdio_set_block_size(sdiodev->func[0], SDIOWIFI_FUNC_BLOCKSIZE);
|
||||
if (ret < 0) {
|
||||
sdio_err("set blocksize fail %d\n", ret);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
return ret;
|
||||
}
|
||||
ret = sdio_enable_func(sdiodev->func);
|
||||
ret = sdio_enable_func(sdiodev->func[0]);
|
||||
if (ret < 0) {
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
sdio_err("enable func fail %d.\n", ret);
|
||||
}
|
||||
|
||||
@ -1187,16 +1362,49 @@ int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev)
|
||||
host->ops->set_ios(host, &host->ios);
|
||||
sdio_dbg("Set SDIO Clock %d MHz\n", host->ios.clock/1000000);
|
||||
}
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_REGISTER_BLOCK, block_bit0);
|
||||
if (aicbsp_info.chipinfo->chipid == PRODUCT_ID_AIC8800DC) {
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
|
||||
//set sdio blocksize
|
||||
ret = sdio_set_block_size(sdiodev->func[1], SDIOWIFI_FUNC_BLOCKSIZE);
|
||||
if (ret < 0) {
|
||||
printk("set func2 blocksize fail %d\n", ret);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//set sdio enable func
|
||||
ret = sdio_enable_func(sdiodev->func[1]);
|
||||
if (ret < 0) {
|
||||
printk("enable func2 fail %d.\n", ret);
|
||||
}
|
||||
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[1], SDIOWIFI_REGISTER_BLOCK, block_bit0);
|
||||
if (ret < 0) {
|
||||
printk("reg:%d write failed!\n", SDIOWIFI_REGISTER_BLOCK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//1: no byte mode
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[1], SDIOWIFI_BYTEMODE_ENABLE_REG, byte_mode_disable);
|
||||
if (ret < 0) {
|
||||
printk("reg:%d write failed!\n", SDIOWIFI_BYTEMODE_ENABLE_REG);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_REGISTER_BLOCK, block_bit0);
|
||||
if (ret < 0) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_REGISTER_BLOCK);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//1: no byte mode
|
||||
ret = aicwf_sdio_writeb(sdiodev, SDIOWIFI_BYTEMODE_ENABLE_REG, byte_mode_disable);
|
||||
ret = aicwf_sdio_writeb(sdiodev->func[0], SDIOWIFI_BYTEMODE_ENABLE_REG, byte_mode_disable);
|
||||
if (ret < 0) {
|
||||
sdio_err("reg:%d write failed!\n", SDIOWIFI_BYTEMODE_ENABLE_REG);
|
||||
return ret;
|
||||
@ -1208,9 +1416,9 @@ int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev)
|
||||
|
||||
void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
sdio_claim_host(sdiodev->func);
|
||||
sdio_disable_func(sdiodev->func);
|
||||
sdio_release_host(sdiodev->func);
|
||||
sdio_claim_host(sdiodev->func[0]);
|
||||
sdio_disable_func(sdiodev->func[0]);
|
||||
sdio_release_host(sdiodev->func[0]);
|
||||
}
|
||||
|
||||
void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev)
|
||||
|
||||
@ -49,7 +49,7 @@ typedef enum {
|
||||
|
||||
struct aic_sdio_dev {
|
||||
struct rwnx_cmd_mgr cmd_mgr;
|
||||
struct sdio_func *func;
|
||||
struct sdio_func *func[2];
|
||||
struct device *dev;
|
||||
struct aicwf_bus *bus_if;
|
||||
|
||||
@ -67,8 +67,9 @@ struct aic_sdio_dev {
|
||||
};
|
||||
|
||||
void *aicbsp_get_drvdata(void *args);
|
||||
int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
|
||||
int aicwf_sdio_writeb(struct sdio_func *func, uint regaddr, u8 val);
|
||||
void aicwf_sdio_hal_irqhandler(struct sdio_func *func);
|
||||
void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func);
|
||||
void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration);
|
||||
int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target);
|
||||
int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
|
||||
int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = -ENOMEM;
|
||||
int errnum = 0;
|
||||
struct aicwf_bus *bus_if;
|
||||
|
||||
if (!dev) {
|
||||
@ -31,7 +32,6 @@ int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
bus_if = dev_get_drvdata(dev);
|
||||
bus_if->cmd_buf = kzalloc(CMD_BUF_MAX, GFP_KERNEL);
|
||||
if (!bus_if->cmd_buf) {
|
||||
ret = -ENOMEM;
|
||||
txrx_err("proto_attach failed\n");
|
||||
goto fail;
|
||||
}
|
||||
@ -45,18 +45,20 @@ int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
#endif
|
||||
|
||||
if (IS_ERR(bus_if->bustx_thread)) {
|
||||
errnum = PTR_ERR(bus_if->bustx_thread);
|
||||
bus_if->bustx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
txrx_err("aicwf_bustx_thread run fail, errnum is %d\n", errnum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (IS_ERR(bus_if->busrx_thread)) {
|
||||
errnum = PTR_ERR(bus_if->busrx_thread);
|
||||
bus_if->busrx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
txrx_err("aicwf_busrx_thread run fail, errnum is %d\n", errnum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
fail:
|
||||
aicwf_bus_deinit(dev);
|
||||
|
||||
@ -83,7 +85,7 @@ void aicwf_bus_deinit(struct device *dev)
|
||||
bus_if->cmd_buf = NULL;
|
||||
}
|
||||
|
||||
if (bus_if->bustx_thread) {
|
||||
if (!IS_ERR_OR_NULL(bus_if->bustx_thread)) {
|
||||
complete_all(&bus_if->bustx_trgg);
|
||||
kthread_stop(bus_if->bustx_thread);
|
||||
bus_if->bustx_thread = NULL;
|
||||
@ -284,7 +286,7 @@ static void aicwf_recvframe_queue_deinit(struct list_head *q)
|
||||
|
||||
void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv)
|
||||
{
|
||||
if (rx_priv->sdiodev->bus_if->busrx_thread) {
|
||||
if (!IS_ERR_OR_NULL(rx_priv->sdiodev->bus_if->busrx_thread)) {
|
||||
complete_all(&rx_priv->sdiodev->bus_if->busrx_trgg);
|
||||
kthread_stop(rx_priv->sdiodev->bus_if->busrx_thread);
|
||||
rx_priv->sdiodev->bus_if->busrx_thread = NULL;
|
||||
|
||||
@ -62,9 +62,11 @@
|
||||
/*
|
||||
* Defines
|
||||
*/
|
||||
|
||||
#define VERSION "1.3.3"
|
||||
#define PROC_DIR "bluetooth/sleep"
|
||||
#define DRV_RELEASE_DATE "20220429"
|
||||
#define DRV_PATCH_LEVEL "003"
|
||||
#define DRV_RELEASE_TAG "aic-btlpm-" DRV_RELEASE_DATE "-" DRV_PATCH_LEVEL
|
||||
#define VERSION "1.3.3"
|
||||
#define PROC_DIR "bluetooth/sleep"
|
||||
|
||||
#define DEFAULT_UART_INDEX 1
|
||||
#define BT_BLUEDROID_SUPPORT 1
|
||||
@ -107,8 +109,9 @@ DECLARE_DELAYED_WORK(sleep_workqueue, bluesleep_sleep_work);
|
||||
#define BT_PROTO 0x01
|
||||
#define BT_TXDATA 0x02
|
||||
#define BT_ASLEEP 0x04
|
||||
#define BT_RXTIMER 0x20
|
||||
#define BT_TXIDLE 0x08
|
||||
#define BT_PAUSE 0x09
|
||||
#define BT_RXTIMER 0x0a
|
||||
|
||||
#if BT_BLUEDROID_SUPPORT
|
||||
static bool has_lpm_enabled;
|
||||
@ -211,7 +214,8 @@ static void bluesleep_sleep_work(struct work_struct *work)
|
||||
BT_DBG("already asleep");
|
||||
return;
|
||||
}
|
||||
if (bsi->uport->ops->tx_empty(bsi->uport)) {
|
||||
if (bsi->uport->ops->tx_empty(bsi->uport) ||
|
||||
(test_bit(BT_PAUSE, &flags) && test_bit(BT_TXIDLE, &flags))) {
|
||||
BT_DBG("going to sleep...");
|
||||
set_bit(BT_ASLEEP, &flags);
|
||||
/*Deactivating UART */
|
||||
@ -242,9 +246,22 @@ static void bluesleep_sleep_work(struct work_struct *work)
|
||||
set_bit(BT_RXTIMER, &flags);
|
||||
hsuart_power(1);
|
||||
} else {
|
||||
static int tx_idle_cnt;
|
||||
if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert && test_bit(BT_TXIDLE, &flags))
|
||||
tx_idle_cnt++;
|
||||
else
|
||||
tx_idle_cnt = 0;
|
||||
|
||||
mod_timer(&rx_timer, jiffies + (RX_TIMER_INTERVAL * HZ));
|
||||
if (gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert
|
||||
&& !test_bit(BT_TXIDLE, &flags)) {
|
||||
set_bit(BT_RXTIMER, &flags);
|
||||
|
||||
if (test_bit(BT_PAUSE, &flags)) {
|
||||
BT_DBG("rx wake du BT_PAUSE:%lx", flags);
|
||||
///enable bt sleep immediately
|
||||
gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert);
|
||||
} else if ((gpio_get_value(bsi->ext_wake) != bsi->ext_wake_assert
|
||||
&& !test_bit(BT_TXIDLE, &flags)) || tx_idle_cnt > 5) {
|
||||
tx_idle_cnt = 0;
|
||||
BT_DBG("force retrigger bt wake:%lx", flags);
|
||||
gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert);
|
||||
msleep(20);
|
||||
@ -340,11 +357,20 @@ static ssize_t bluesleep_write_proc_lpm(struct file *file,
|
||||
return -EFAULT;
|
||||
|
||||
if (b == '0') {
|
||||
#if 1
|
||||
set_bit(BT_PAUSE, &flags);
|
||||
set_bit(BT_TXIDLE, &flags);
|
||||
clear_bit(BT_TXDATA, &flags);
|
||||
/* deassert BT_WAKE */
|
||||
gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert);
|
||||
#else
|
||||
/* HCI_DEV_UNREG */
|
||||
bluesleep_stop();
|
||||
has_lpm_enabled = false;
|
||||
bsi->uport = NULL;
|
||||
#endif
|
||||
} else {
|
||||
clear_bit(BT_PAUSE, &flags);
|
||||
/* HCI_DEV_REG */
|
||||
if (!has_lpm_enabled) {
|
||||
has_lpm_enabled = true;
|
||||
@ -478,6 +504,7 @@ static void bluesleep_tx_allow_sleep(void)
|
||||
spin_lock_irqsave(&rw_lock, irq_flags);
|
||||
gpio_set_value(bsi->ext_wake, !bsi->ext_wake_assert);
|
||||
set_bit(BT_TXIDLE, &flags);
|
||||
clear_bit(BT_TXDATA, &flags);
|
||||
bluesleep_tx_idle();
|
||||
spin_unlock_irqrestore(&rw_lock, irq_flags);
|
||||
}
|
||||
@ -569,7 +596,7 @@ fail:
|
||||
/**
|
||||
* Stops the Sleep-Mode Protocol on the Host.
|
||||
*/
|
||||
static void bluesleep_stop(void)
|
||||
static __attribute__((unused)) void bluesleep_stop(void)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
|
||||
@ -917,8 +944,6 @@ static int bluesleep_remove(struct platform_device *pdev)
|
||||
/* assert bt wake */
|
||||
gpio_set_value(bsi->ext_wake, bsi->ext_wake_assert);
|
||||
if (test_bit(BT_PROTO, &flags)) {
|
||||
if (disable_irq_wake(bsi->host_wake_irq))
|
||||
BT_ERR("Couldn't disable hostwake IRQ wakeup mode\n");
|
||||
free_irq(bsi->host_wake_irq, &bsi->pdev->dev);
|
||||
del_timer(&rx_timer);
|
||||
if (test_bit(BT_ASLEEP, &flags))
|
||||
@ -966,6 +991,7 @@ static int __init bluesleep_init(void)
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
BT_DBG("BlueSleep Mode Driver Ver %s", VERSION);
|
||||
BT_DBG("Driver Release Tag: %s", DRV_RELEASE_TAG);
|
||||
|
||||
retval = platform_driver_probe(&bluesleep_driver, bluesleep_probe);
|
||||
if (retval)
|
||||
|
||||
@ -48,6 +48,7 @@ CONFIG_RWNX_BFMER ?= n
|
||||
|
||||
CONFIG_SDIO_SUPPORT =y
|
||||
CONFIG_USB_SUPPORT =n
|
||||
CONFIG_PCIE_SUPPORT =n
|
||||
CONFIG_RX_REORDER ?=y
|
||||
CONFIG_ARP_OFFLOAD =y
|
||||
CONFIG_RADAR_OR_IR_DETECT =n
|
||||
@ -55,6 +56,7 @@ CONFIG_DOWNLOAD_FW =y
|
||||
CONFIG_RFTEST=y
|
||||
CONFIG_USB_BT =n
|
||||
CONFIG_GKI_OPT_FEATURES ?= y
|
||||
CONFIG_WPA3_FOR_OLD_KERNEL ?= n
|
||||
|
||||
|
||||
# Support of MU-MIMO transmission (need FW support)
|
||||
@ -79,6 +81,7 @@ CONFIG_RWNX_DBG ?= y
|
||||
|
||||
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := aic8800_fdrv.o
|
||||
aic8800_fdrv-y := \
|
||||
rwnx_wakelock.o \
|
||||
rwnx_gki.o \
|
||||
rwnx_msg_tx.o \
|
||||
rwnx_msg_rx.o \
|
||||
@ -94,7 +97,6 @@ aic8800_fdrv-y := \
|
||||
rwnx_mod_params.o \
|
||||
rwnx_mesh.o \
|
||||
rwnx_platform.o \
|
||||
rwnx_pci.o \
|
||||
rwnx_dini.o \
|
||||
rwnx_v7.o \
|
||||
ipc_host.o \
|
||||
@ -115,6 +117,8 @@ aic8800_fdrv-$(CONFIG_USB_SUPPORT) += usb_host.o
|
||||
aic8800_fdrv-$(CONFIG_USB_SUPPORT) += aicwf_txrxif.o
|
||||
aic8800_fdrv-$(CONFIG_USB_SUPPORT) += aicwf_usb.o
|
||||
|
||||
aic8800_fdrv-$(CONFIG_PCIE_SUPPORT) += rwnx_pci.o
|
||||
|
||||
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_DEBUGFS
|
||||
ccflags-$(CONFIG_DEBUG_FS) += -DCONFIG_RWNX_UM_HELPER_DFLT=\"$(CONFIG_RWNX_UM_HELPER_DFLT)\"
|
||||
ccflags-$(CONFIG_RWNX_P2P_DEBUGFS) += -DCONFIG_RWNX_P2P_DEBUGFS
|
||||
@ -139,11 +143,6 @@ ccflags-$(CONFIG_START_FROM_BOOTROM) += -DCONFIG_START_FROM_BOOTROM
|
||||
ccflags-$(CONFIG_PMIC_SETTING) += -DCONFIG_PMIC_SETTING
|
||||
ccflags-$(CONFIG_ROM_PATCH_EN) += -DCONFIG_ROM_PATCH_EN
|
||||
|
||||
CURRENT_CODE_VERSION := $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)
|
||||
MINI_VERSION_REQUEST := 4.14.0
|
||||
ifeq ($(shell expr $(CURRENT_CODE_VERSION) \< $(MINI_VERSION_REQUEST)),1)
|
||||
ccflags-y += -DCONFIG_HE_FOR_OLD_KERNEL
|
||||
endif
|
||||
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_COEX
|
||||
ccflags-$(CONFIG_PLATFORM_NANOPI_M4) += -DCONFIG_COEX
|
||||
|
||||
@ -162,6 +161,7 @@ ccflags-$(CONFIG_RWNX_DBG) += -DCONFIG_RWNX_DBG
|
||||
ccflags-$(CONFIG_RWNX_SW_PROFILING) += -DCONFIG_RWNX_SW_PROFILING
|
||||
ccflags-$(CONFIG_RWNX_MUMIMO_TX) += -DCONFIG_RWNX_MUMIMO_TX
|
||||
ccflags-$(CONFIG_RFTEST) += -DCONFIG_RFTEST
|
||||
ccflags-$(CONFIG_WPA3_FOR_OLD_KERNEL) += -DCONFIG_WPA3_FOR_OLD_KERNEL
|
||||
|
||||
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
||||
ccflags-y += -DAICWF_SDIO_SUPPORT
|
||||
@ -171,6 +171,10 @@ ifeq ($(CONFIG_USB_SUPPORT), y)
|
||||
ccflags-y += -DAICWF_USB_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PCIE_SUPPORT), y)
|
||||
ccflags-y += -DAICWF_PCIE_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RWNX_MUMIMO_TX), y)
|
||||
ccflags-y += -DCONFIG_USER_MAX=2
|
||||
else
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <net/netlink.h>
|
||||
#include "rwnx_version_gen.h"
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
static struct wifi_ring_buffer_status ring_buffer[] = {
|
||||
{
|
||||
.name = "aicwf_ring_buffer0",
|
||||
@ -843,12 +844,15 @@ const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
|
||||
|
||||
static const struct nl80211_vendor_cmd_info aicwf_vendor_events[] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
int aicwf_vendor_init(struct wiphy *wiphy)
|
||||
{
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
|
||||
wiphy->vendor_commands = aicwf_vendor_cmd;
|
||||
wiphy->n_vendor_commands = ARRAY_SIZE(aicwf_vendor_cmd);
|
||||
wiphy->vendor_events = aicwf_vendor_events;
|
||||
wiphy->n_vendor_events = ARRAY_SIZE(aicwf_vendor_events);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "mach/jzmmc.h"
|
||||
#endif /* CONFIG_INGENIC_T20 */
|
||||
#include "aic_bsp_export.h"
|
||||
#include "rwnx_wakelock.h"
|
||||
extern uint8_t scanning;
|
||||
|
||||
int aicwf_sdio_readb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 *val)
|
||||
@ -45,7 +46,7 @@ int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev)
|
||||
int aicwf_sdio_flow_ctrl_msg(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = -1;
|
||||
u8 fc_reg = 0;
|
||||
@ -69,9 +70,42 @@ int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev)
|
||||
if (count < 30)
|
||||
udelay(200);
|
||||
else if (count < 40)
|
||||
mdelay(1);
|
||||
msleep(2);
|
||||
else
|
||||
mdelay(10);
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int ret = -1;
|
||||
u8 fc_reg = 0;
|
||||
u32 count = 0;
|
||||
|
||||
while (true) {
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_FLOW_CTRL_REG, &fc_reg);
|
||||
if (ret) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fc_reg & SDIOWIFI_FLOWCTRL_MASK_REG) > DATA_FLOW_CTRL_THRESH) {
|
||||
ret = fc_reg & SDIOWIFI_FLOWCTRL_MASK_REG;
|
||||
return ret;
|
||||
} else {
|
||||
if (count >= FLOW_CTRL_RETRY_COUNT) {
|
||||
ret = -fc_reg;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
if (count < 30)
|
||||
udelay(200);
|
||||
else if (count < 40)
|
||||
msleep(2);
|
||||
else
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,8 +144,6 @@ int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wakeup_enable;
|
||||
static u32 hostwake_irq_num;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||
extern int sunxi_wlan_get_oob_irq(int *, int *);
|
||||
#else
|
||||
@ -119,23 +151,11 @@ extern int sunxi_wlan_get_oob_irq(void);
|
||||
extern int sunxi_wlan_get_oob_irq_flags(void);
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
static struct wakeup_source *ws;
|
||||
#else
|
||||
#include <linux/wakelock.h>
|
||||
static struct wake_lock irq_wakelock;
|
||||
#endif
|
||||
|
||||
static irqreturn_t rwnx_hostwake_irq_handler(int irq, void *para)
|
||||
{
|
||||
static int wake_cnt;
|
||||
wake_cnt++;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
__pm_wakeup_event(ws, HZ / 20);
|
||||
#else
|
||||
wake_lock_timeout(&irq_wakelock, HZ / 20);
|
||||
#endif
|
||||
printk("%s(%d): wake_irq_cnt = %d\n", __func__, __LINE__, wake_cnt);
|
||||
rwnx_wakeup_lock_timeout(g_rwnx_plat->sdiodev->rwnx_hw->ws_rx, jiffies_to_msecs(5));
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
@ -143,6 +163,8 @@ static int rwnx_register_hostwake_irq(struct device *dev)
|
||||
{
|
||||
int ret = -1;
|
||||
int irq_flags;
|
||||
int wakeup_enable;
|
||||
u32 hostwake_irq_num;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
|
||||
hostwake_irq_num = sunxi_wlan_get_oob_irq(&irq_flags, &wakeup_enable);
|
||||
#else
|
||||
@ -152,11 +174,6 @@ static int rwnx_register_hostwake_irq(struct device *dev)
|
||||
#endif
|
||||
|
||||
if (wakeup_enable) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
ws = wakeup_source_register(dev, "wifisleep");
|
||||
#else
|
||||
wake_lock_init(&irq_wakelock, WAKE_LOCK_SUSPEND, "wifisleep");
|
||||
#endif
|
||||
ret = device_init_wakeup(dev, true);
|
||||
if (ret < 0) {
|
||||
pr_err("%s(%d): device init wakeup failed!\n", __func__, __LINE__);
|
||||
@ -178,7 +195,9 @@ static int rwnx_register_hostwake_irq(struct device *dev)
|
||||
goto fail2;
|
||||
}
|
||||
}
|
||||
disable_irq(hostwake_irq_num);
|
||||
g_rwnx_plat->sdiodev->rwnx_hw->wakeup_enable = wakeup_enable;
|
||||
g_rwnx_plat->sdiodev->rwnx_hw->hostwake_irq_num = hostwake_irq_num;
|
||||
|
||||
printk("%s(%d)\n", __func__, __LINE__);
|
||||
return ret;
|
||||
|
||||
@ -186,44 +205,22 @@ fail2:
|
||||
dev_pm_clear_wake_irq(dev);
|
||||
fail1:
|
||||
device_init_wakeup(dev, false);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
wakeup_source_unregister(ws);
|
||||
#else
|
||||
wake_lock_destroy(&irq_wakelock);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rwnx_unregister_hostwake_irq(struct device *dev)
|
||||
{
|
||||
int wakeup_enable = g_rwnx_plat->sdiodev->rwnx_hw->wakeup_enable;
|
||||
u32 hostwake_irq_num = g_rwnx_plat->sdiodev->rwnx_hw->hostwake_irq_num;
|
||||
if (wakeup_enable) {
|
||||
free_irq(hostwake_irq_num, NULL);
|
||||
device_init_wakeup(dev, false);
|
||||
dev_pm_clear_wake_irq(dev);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
wakeup_source_unregister(ws);
|
||||
#else
|
||||
wake_lock_destroy(&irq_wakelock);
|
||||
#endif
|
||||
}
|
||||
free_irq(hostwake_irq_num, NULL);
|
||||
printk("%s(%d)\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rwnx_enable_hostwake_irq(void)
|
||||
{
|
||||
enable_irq(hostwake_irq_num);
|
||||
printk("%s(%d)\n", __func__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rwnx_disable_hostwake_irq(void)
|
||||
{
|
||||
printk("%s(%d)\n", __func__, __LINE__);
|
||||
disable_irq(hostwake_irq_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aicwf_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
@ -270,10 +267,11 @@ static int aicwf_sdio_probe(struct sdio_func *func,
|
||||
|
||||
host->caps |= MMC_CAP_NONREMOVABLE;
|
||||
aicwf_rwnx_sdio_platform_init(sdiodev);
|
||||
aicwf_hostif_ready();
|
||||
err = rwnx_register_hostwake_irq(sdiodev->dev);
|
||||
if (err != 0)
|
||||
return err;
|
||||
aicwf_hostif_fail();
|
||||
else
|
||||
aicwf_hostif_ready();
|
||||
return 0;
|
||||
fail:
|
||||
aicwf_sdio_func_deinit(sdiodev);
|
||||
@ -302,7 +300,6 @@ static void aicwf_sdio_remove(struct sdio_func *func)
|
||||
if (!sdiodev) {
|
||||
return;
|
||||
}
|
||||
rwnx_unregister_hostwake_irq(sdiodev->dev);
|
||||
sdiodev->bus_if->state = BUS_DOWN_ST;
|
||||
aicwf_sdio_release(sdiodev);
|
||||
aicwf_sdio_func_deinit(sdiodev);
|
||||
@ -342,7 +339,6 @@ static int aicwf_sdio_suspend(struct device *dev)
|
||||
up(&sdiodev->tx_priv->txctl_sema);
|
||||
break;
|
||||
}
|
||||
rwnx_enable_hostwake_irq();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -354,23 +350,18 @@ static int aicwf_sdio_resume(struct device *dev)
|
||||
struct rwnx_vif *rwnx_vif, *tmp;
|
||||
|
||||
sdio_dbg("%s\n", __func__);
|
||||
rwnx_disable_hostwake_irq();
|
||||
list_for_each_entry_safe(rwnx_vif, tmp, &sdiodev->rwnx_hw->vifs, list) {
|
||||
if (rwnx_vif->ndev)
|
||||
netif_device_attach(rwnx_vif->ndev);
|
||||
}
|
||||
aicwf_sdio_pwr_stctl(sdiodev, SDIO_ACTIVE_ST);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
__pm_relax(ws);
|
||||
#else
|
||||
wake_unlock(&irq_wakelock);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct sdio_device_id aicwf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN)},
|
||||
{SDIO_DEVICE(0x5449, 0x0145)}, // 8800d in nomal mode
|
||||
{SDIO_DEVICE(0xc8a1, 0xc08d)}, // 8800dc in nomal mode
|
||||
{ },
|
||||
};
|
||||
|
||||
@ -429,8 +420,10 @@ void aicwf_sdio_register(void)
|
||||
|
||||
void aicwf_sdio_exit(void)
|
||||
{
|
||||
if (g_rwnx_plat && g_rwnx_plat->enabled)
|
||||
if (g_rwnx_plat && g_rwnx_plat->enabled) {
|
||||
rwnx_unregister_hostwake_irq(g_rwnx_plat->sdiodev->dev);
|
||||
rwnx_platform_deinit(g_rwnx_plat->sdiodev->rwnx_hw);
|
||||
}
|
||||
|
||||
udelay(500);
|
||||
sdio_unregister_driver(&aicwf_sdio_driver);
|
||||
@ -662,10 +655,10 @@ static int aicwf_sdio_tx_msg(struct aic_sdio_dev *sdiodev)
|
||||
} else
|
||||
len = payload_len;
|
||||
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl_msg(sdiodev);
|
||||
while ((buffer_cnt <= 0 || (buffer_cnt > 0 && len > (buffer_cnt * BUFFER_SIZE))) && retry < 10) {
|
||||
retry++;
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl(sdiodev);
|
||||
buffer_cnt = aicwf_sdio_flow_ctrl_msg(sdiodev);
|
||||
printk("buffer_cnt = %d\n", buffer_cnt);
|
||||
}
|
||||
|
||||
@ -765,7 +758,11 @@ static int aicwf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
|
||||
prio = (pkt->priority & 0x7);
|
||||
spin_lock_bh(&sdiodev->tx_priv->txqlock);
|
||||
if (!aicwf_frame_enq(sdiodev->dev, &sdiodev->tx_priv->txq, pkt, prio)) {
|
||||
aicwf_dev_skb_free(pkt);
|
||||
struct rwnx_txhdr *txhdr = (struct rwnx_txhdr *)pkt->data;
|
||||
int headroom = txhdr->sw_hdr->headroom;
|
||||
kmem_cache_free(txhdr->sw_hdr->rwnx_vif->rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr);
|
||||
skb_pull(pkt, headroom);
|
||||
consume_skb(pkt);
|
||||
spin_unlock_bh(&sdiodev->tx_priv->txqlock);
|
||||
return -ENOSR;
|
||||
} else {
|
||||
@ -780,7 +777,8 @@ static int aicwf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
|
||||
|
||||
atomic_inc(&sdiodev->tx_priv->tx_pktcnt);
|
||||
spin_unlock_bh(&sdiodev->tx_priv->txqlock);
|
||||
complete(&bus_if->bustx_trgg);
|
||||
if (atomic_read(&sdiodev->tx_priv->tx_pktcnt) == 1)
|
||||
complete(&bus_if->bustx_trgg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1023,8 +1021,13 @@ int sdio_bustx_thread(void *data)
|
||||
if (sdiodev->bus_if->state == BUS_DOWN_ST)
|
||||
continue;
|
||||
|
||||
if ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) > 0) || (sdiodev->tx_priv->cmd_txstate == true))
|
||||
rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_tx);
|
||||
while ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) > 0) || (sdiodev->tx_priv->cmd_txstate == true)) {
|
||||
aicwf_sdio_tx_process(sdiodev);
|
||||
if (sdiodev->bus_if->state == BUS_DOWN_ST)
|
||||
break;
|
||||
}
|
||||
rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_tx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1035,6 +1038,7 @@ int sdio_busrx_thread(void *data)
|
||||
{
|
||||
struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data;
|
||||
struct aicwf_bus *bus_if = rx_priv->sdiodev->bus_if;
|
||||
struct aic_sdio_dev *sdiodev = rx_priv->sdiodev;
|
||||
|
||||
while (1) {
|
||||
if (kthread_should_stop()) {
|
||||
@ -1044,7 +1048,9 @@ int sdio_busrx_thread(void *data)
|
||||
if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) {
|
||||
if (bus_if->state == BUS_DOWN_ST)
|
||||
continue;
|
||||
rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_rx);
|
||||
aicwf_process_rxframes(rx_priv);
|
||||
rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_rx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1063,11 +1069,14 @@ static int aicwf_sdio_pwrctl_thread(void *data)
|
||||
if (!wait_for_completion_interruptible(&sdiodev->pwrctrl_trgg)) {
|
||||
if (sdiodev->bus_if->state == BUS_DOWN_ST)
|
||||
continue;
|
||||
|
||||
rwnx_wakeup_lock(sdiodev->rwnx_hw->ws_pwrctrl);
|
||||
if ((int)(atomic_read(&sdiodev->tx_priv->tx_pktcnt) <= 0) && (sdiodev->tx_priv->cmd_txstate == false) && \
|
||||
atomic_read(&sdiodev->rx_priv->rx_cnt) == 0)
|
||||
aicwf_sdio_pwr_stctl(sdiodev, SDIO_SLEEP_ST);
|
||||
else
|
||||
aicwf_sdio_pwrctl_timer(sdiodev, sdiodev->active_duration);
|
||||
rwnx_wakeup_unlock(sdiodev->rwnx_hw->ws_pwrctrl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1123,6 +1132,7 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
|
||||
u8 byte_len = 0;
|
||||
struct sk_buff *pkt = NULL;
|
||||
int ret;
|
||||
int retry = 10;
|
||||
|
||||
if (!bus_if || bus_if->state == BUS_DOWN_ST) {
|
||||
sdio_err("bus err\n");
|
||||
@ -1133,6 +1143,8 @@ void aicwf_sdio_hal_irqhandler(struct sdio_func *func)
|
||||
while (ret || (intstatus & SDIO_OTHER_INTERRUPT)) {
|
||||
sdio_err("ret=%d, intstatus=%x\r\n", ret, intstatus);
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_BLOCK_CNT_REG, &intstatus);
|
||||
if (retry-- <= 0)
|
||||
break;
|
||||
}
|
||||
sdiodev->rx_priv->data_len = intstatus * SDIOWIFI_FUNC_BLOCKSIZE;
|
||||
|
||||
@ -1281,7 +1293,7 @@ int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
mdelay(2);
|
||||
mdelay(5);
|
||||
ret = aicwf_sdio_readb(sdiodev, SDIOWIFI_SLEEP_REG, &val);
|
||||
if (ret < 0) {
|
||||
sdio_err("reg:%d read failed!\n", SDIOWIFI_SLEEP_REG);
|
||||
|
||||
@ -78,6 +78,7 @@ int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target);
|
||||
int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev);
|
||||
void aicwf_sdio_func_deinit(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdio_flow_ctrl(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdio_flow_ctrl_msg(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size);
|
||||
int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count);
|
||||
void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
@ -25,10 +25,12 @@
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
#include "sdio_host.h"
|
||||
#endif
|
||||
#include "aic_bsp_export.h"
|
||||
|
||||
int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int errnum = 0;
|
||||
struct aicwf_bus *bus_if;
|
||||
|
||||
if (!dev) {
|
||||
@ -56,14 +58,16 @@ int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
#endif
|
||||
|
||||
if (IS_ERR(bus_if->bustx_thread)) {
|
||||
errnum = PTR_ERR(bus_if->bustx_thread);
|
||||
bus_if->bustx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
txrx_err("aicwf_bustx_thread run fail, errnum is %d\n", errnum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (IS_ERR(bus_if->busrx_thread)) {
|
||||
errnum = PTR_ERR(bus_if->busrx_thread);
|
||||
bus_if->busrx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
txrx_err("aicwf_busrx_thread run fail, errnum is %d\n", errnum);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -109,7 +113,7 @@ void aicwf_bus_deinit(struct device *dev)
|
||||
bus_if->cmd_buf = NULL;
|
||||
}
|
||||
|
||||
if (bus_if->bustx_thread) {
|
||||
if (!IS_ERR_OR_NULL(bus_if->bustx_thread)) {
|
||||
complete_all(&bus_if->bustx_trgg);
|
||||
kthread_stop(bus_if->bustx_thread);
|
||||
bus_if->bustx_thread = NULL;
|
||||
@ -150,7 +154,11 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
|
||||
#endif
|
||||
|
||||
atomic_set(&tx_priv->aggr_count, 0);
|
||||
#ifdef AICBSP_RESV_MEM_SUPPORT
|
||||
tx_priv->aggr_buf = aicbsp_resv_mem_alloc_skb(MAX_AGGR_TXPKT_LEN, AIC_RESV_MEM_TXDATA);
|
||||
#else
|
||||
tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN);
|
||||
#endif
|
||||
if (!tx_priv->aggr_buf) {
|
||||
txrx_err("Alloc bus->txdata_buf failed!\n");
|
||||
kfree(tx_priv);
|
||||
@ -165,7 +173,11 @@ struct aicwf_tx_priv *aicwf_tx_init(void *arg)
|
||||
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv)
|
||||
{
|
||||
if (tx_priv && tx_priv->aggr_buf) {
|
||||
#ifdef AICBSP_RESV_MEM_SUPPORT
|
||||
aicbsp_resv_mem_kfree_skb(tx_priv->aggr_buf, AIC_RESV_MEM_TXDATA);
|
||||
#else
|
||||
dev_kfree_skb(tx_priv->aggr_buf);
|
||||
#endif
|
||||
kfree(tx_priv);
|
||||
}
|
||||
}
|
||||
@ -358,6 +370,7 @@ int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv)
|
||||
|
||||
skb_put(skb_inblock, aggr_len);
|
||||
memcpy(skb_inblock->data, data, aggr_len);
|
||||
aicwf_count_rx_tp(rx_priv, aggr_len);
|
||||
rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv);
|
||||
///TODO: here need to add rx data process
|
||||
|
||||
@ -462,23 +475,25 @@ void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv)
|
||||
struct reord_ctrl_info *reord_info, *tmp;
|
||||
|
||||
txrx_dbg("%s\n", __func__);
|
||||
|
||||
spin_lock_bh(&rx_priv->stas_reord_lock);
|
||||
list_for_each_entry_safe(reord_info, tmp,
|
||||
&rx_priv->stas_reord_list, list) {
|
||||
reord_deinit_sta(rx_priv, reord_info);
|
||||
}
|
||||
spin_unlock_bh(&rx_priv->stas_reord_lock);
|
||||
#endif
|
||||
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
txrx_dbg("sdio rx thread\n");
|
||||
if (rx_priv->sdiodev->bus_if->busrx_thread) {
|
||||
if (!IS_ERR_OR_NULL(rx_priv->sdiodev->bus_if->busrx_thread)) {
|
||||
complete_all(&rx_priv->sdiodev->bus_if->busrx_trgg);
|
||||
kthread_stop(rx_priv->sdiodev->bus_if->busrx_thread);
|
||||
rx_priv->sdiodev->bus_if->busrx_thread = NULL;
|
||||
}
|
||||
#endif
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
if (rx_priv->usbdev->bus_if->busrx_thread) {
|
||||
txrx_dbg("usb rx thread\n");
|
||||
if (!IS_ERR_OR_NULL(rx_priv->usbdev->bus_if->busrx_thread)) {
|
||||
complete_all(&rx_priv->usbdev->bus_if->busrx_trgg);
|
||||
kthread_stop(rx_priv->usbdev->bus_if->busrx_thread);
|
||||
rx_priv->usbdev->bus_if->busrx_thread = NULL;
|
||||
@ -608,48 +623,13 @@ struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq)
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct sk_buff *aicwf_skb_dequeue_tail(struct frame_queue *pq, int prio)
|
||||
{
|
||||
struct sk_buff_head *q = &pq->queuelist[prio];
|
||||
struct sk_buff *p = skb_dequeue_tail(q);
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
pq->qcnt--;
|
||||
return p;
|
||||
}
|
||||
|
||||
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio)
|
||||
{
|
||||
struct sk_buff *p = NULL;
|
||||
int prio_modified = -1;
|
||||
|
||||
if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) {
|
||||
aicwf_frame_queue_penq(q, prio, pkt);
|
||||
return true;
|
||||
}
|
||||
if (q->queuelist[prio].qlen >= q->qmax) {
|
||||
prio_modified = prio;
|
||||
} else if (q->qcnt >= q->qmax) {
|
||||
p = aicwf_frame_queue_peek_tail(q, &prio_modified);
|
||||
if (prio_modified > prio)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prio_modified >= 0) {
|
||||
if (prio_modified == prio)
|
||||
return false;
|
||||
|
||||
p = aicwf_skb_dequeue_tail(q, prio_modified);
|
||||
aicwf_dev_skb_free(p);
|
||||
|
||||
p = aicwf_frame_queue_penq(q, prio_modified, pkt);
|
||||
if (p == NULL)
|
||||
txrx_err("failed\n");
|
||||
}
|
||||
|
||||
return p != NULL;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "rwnx_defs.h"
|
||||
#include "usb_host.h"
|
||||
#include "rwnx_platform.h"
|
||||
#include "rwnx_wakelock.h"
|
||||
|
||||
void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state)
|
||||
{
|
||||
@ -153,6 +154,7 @@ static void aicwf_usb_rx_complete(struct urb *urb)
|
||||
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
|
||||
usb_err("rx_priv->rxq is over flow!!!\n");
|
||||
aicwf_dev_skb_free(skb);
|
||||
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
|
||||
return;
|
||||
}
|
||||
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
|
||||
@ -297,8 +299,10 @@ int usb_bustx_thread(void *data)
|
||||
if (!wait_for_completion_interruptible(&bus->bustx_trgg)) {
|
||||
if (usbdev->bus_if->state == BUS_DOWN_ST)
|
||||
continue;
|
||||
rwnx_wakeup_lock(usbdev->rwnx_hw->ws_tx);
|
||||
if (usbdev->tx_post_count > 0)
|
||||
aicwf_usb_tx_process(usbdev);
|
||||
rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_tx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,6 +313,7 @@ int usb_busrx_thread(void *data)
|
||||
{
|
||||
struct aicwf_rx_priv *rx_priv = (struct aicwf_rx_priv *)data;
|
||||
struct aicwf_bus *bus_if = rx_priv->usbdev->bus_if;
|
||||
struct aic_usb_dev *usbdev = rx_priv->usbdev;
|
||||
|
||||
while (1) {
|
||||
if (kthread_should_stop()) {
|
||||
@ -318,7 +323,9 @@ int usb_busrx_thread(void *data)
|
||||
if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) {
|
||||
if (bus_if->state == BUS_DOWN_ST)
|
||||
continue;
|
||||
rwnx_wakeup_lock(usbdev->rwnx_hw->ws_rx);
|
||||
aicwf_process_rxframes(rx_priv);
|
||||
rwnx_wakeup_unlock(usbdev->rwnx_hw->ws_rx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -556,7 +563,7 @@ static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb)
|
||||
complete(&bus_if->bustx_trgg);
|
||||
ret = 0;
|
||||
|
||||
flow_ctrl:
|
||||
flow_ctrl:
|
||||
spin_lock_irqsave(&usb_dev->tx_flow_lock, flags);
|
||||
if (usb_dev->tx_free_count < AICWF_USB_TX_LOW_WATER) {
|
||||
usb_dev->tbusy = true;
|
||||
@ -781,8 +788,6 @@ static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *in
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct aicwf_bus_ops aicwf_usb_bus_ops = {
|
||||
.start = aicwf_usb_bus_start,
|
||||
.stop = aicwf_usb_bus_stop,
|
||||
|
||||
@ -129,19 +129,10 @@
|
||||
// c.f LMAC/src/tx/tx_swdesc.h
|
||||
/// Descriptor filled by the Host
|
||||
struct hostdesc {
|
||||
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||
/// Pointers to packet payloads
|
||||
u32_l packet_addr[NX_TX_PAYLOAD_MAX];
|
||||
/// Sizes of the MPDU/MSDU payloads
|
||||
u16_l packet_len[NX_TX_PAYLOAD_MAX];
|
||||
/// Number of payloads forming the MPDU
|
||||
u8_l packet_cnt;
|
||||
#else
|
||||
/// Pointer to packet payload
|
||||
u32_l packet_addr;
|
||||
/// Size of the payload
|
||||
u16_l packet_len;
|
||||
#endif //(NX_AMSDU_TX)
|
||||
u16_l flags_ext;
|
||||
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
/// Address of the status descriptor in host memory (used for confirmation upload)
|
||||
@ -152,12 +143,6 @@ struct hostdesc {
|
||||
struct mac_addr eth_src_addr;
|
||||
/// Ethernet Type
|
||||
u16_l ethertype;
|
||||
/// Buffer containing the PN to be used for this packet
|
||||
u16_l pn[4];
|
||||
/// Sequence Number used for transmission of this MPDU
|
||||
u16_l sn;
|
||||
/// Timestamp of first transmission of this MPDU
|
||||
u16_l timestamp;
|
||||
#else /* ! CONFIG_RWNX_FULLMAC */
|
||||
#ifdef CONFIG_RWNX_AGG_TX
|
||||
///Sequence Number for AMPDU MPDUs - for quick check if it's allowed within window
|
||||
@ -166,6 +151,7 @@ struct hostdesc {
|
||||
/// Padding between the buffer control structure and the MPDU in host memory
|
||||
u8_l padding;
|
||||
#endif /* CONFIG_RWNX_FULLMAC */
|
||||
u8_l ac;
|
||||
/// Packet TID (0xFF if not a QoS frame)
|
||||
u8_l tid;
|
||||
/// Interface Id
|
||||
|
||||
@ -434,6 +434,12 @@ enum mac_connection_flags {
|
||||
REASSOCIATION = BIT(5),
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
|
||||
#include <linux/ieee80211.h>
|
||||
#else
|
||||
#define CONFIG_HE_FOR_OLD_KERNEL 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HE_FOR_OLD_KERNEL
|
||||
#define IEEE80211_HE_MAC_CAP2_ALL_ACK 0x02
|
||||
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G 0x02
|
||||
@ -465,9 +471,6 @@ enum mac_connection_flags {
|
||||
|
||||
#define IEEE80211_HE_PPE_THRES_MAX_LEN 25
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
|
||||
#include <linux/ieee80211.h>
|
||||
#else
|
||||
struct ieee80211_he_cap_elem {
|
||||
u8 mac_cap_info[6];
|
||||
u8 phy_cap_info[11];
|
||||
@ -495,5 +498,4 @@ struct ieee80211_sband_iftype_data {
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // LMAC_MAC_H_
|
||||
|
||||
@ -364,8 +364,8 @@ enum mm_msg_tag {
|
||||
MM_GET_STA_INFO_REQ,
|
||||
MM_GET_STA_INFO_CFM,
|
||||
|
||||
MM_SET_TXPWR_IDX_REQ,
|
||||
MM_SET_TXPWR_IDX_CFM,
|
||||
MM_SET_TXPWR_IDX_LVL_REQ,
|
||||
MM_SET_TXPWR_IDX_LVL_CFM,
|
||||
|
||||
MM_SET_TXPWR_OFST_REQ,
|
||||
MM_SET_TXPWR_OFST_CFM,
|
||||
@ -1209,6 +1209,20 @@ struct mm_set_txpwr_idx_req {
|
||||
txpwr_idx_conf_t txpwr_idx;
|
||||
};
|
||||
|
||||
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];
|
||||
} txpwr_lvl_conf_v2_t;
|
||||
|
||||
struct mm_set_txpwr_lvl_req {
|
||||
union {
|
||||
txpwr_idx_conf_t txpwr_lvl;
|
||||
txpwr_lvl_conf_v2_t txpwr_lvl_v2;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u8_l enable;
|
||||
s8_l chan_1_4;
|
||||
@ -1220,6 +1234,12 @@ typedef struct {
|
||||
s8_l chan_142_165;
|
||||
} txpwr_ofst_conf_t;
|
||||
|
||||
typedef struct {
|
||||
u8_l enable;
|
||||
u8_l xtal_cap;
|
||||
u8_l xtal_cap_fine;
|
||||
} xtal_cap_conf_t;
|
||||
|
||||
struct mm_set_txpwr_ofst_req {
|
||||
txpwr_ofst_conf_t txpwr_ofst;
|
||||
};
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
#include "rwnx_cmds.h"
|
||||
#include "rwnx_defs.h"
|
||||
#include "rwnx_strs.h"
|
||||
#define CREATE_TRACE_POINTS
|
||||
//#define CREATE_TRACE_POINTS
|
||||
#include "rwnx_events.h"
|
||||
#include "aicwf_txrxif.h"
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
@ -29,6 +29,37 @@
|
||||
*/
|
||||
extern int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
|
||||
|
||||
static int rwnx_exception_event(struct rwnx_cmd_mgr *cmd_mgr)
|
||||
{
|
||||
#if defined(AICWF_SDIO_SUPPORT)
|
||||
struct aic_sdio_dev *pdev = container_of(cmd_mgr, struct aic_sdio_dev, cmd_mgr);
|
||||
#elif defined(AICWF_USB_SUPPORT)
|
||||
struct aic_usb_dev *pdev = container_of(cmd_mgr, struct aic_usb_dev, cmd_mgr);
|
||||
#else
|
||||
struct aic_usb_dev *pdev = NULL;
|
||||
#endif
|
||||
|
||||
static bool need_send = true;
|
||||
|
||||
char *envp[] = {
|
||||
"SYSTEM=WIFI",
|
||||
"EVENT=EXCEPTION",
|
||||
"SUBEVENT=FW_CRASH",
|
||||
NULL};
|
||||
|
||||
if (!need_send)
|
||||
return 0;
|
||||
|
||||
if (pdev) {
|
||||
kobject_uevent_env(&pdev->dev->kobj, KOBJ_CHANGE, envp);
|
||||
need_send = true;
|
||||
printk(KERN_CRIT "%s send exception uevent to userspace", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void cmd_dump(const struct rwnx_cmd *cmd)
|
||||
{
|
||||
printk(KERN_CRIT "tkn[%d] flags:%04x result:%3d cmd:%4d-%-24s - reqcfm(%4d-%-s)\n",
|
||||
@ -63,8 +94,9 @@ int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd
|
||||
bool defer_push = false;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_msg_send(cmd->id);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&cmd_mgr->lock);
|
||||
|
||||
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||
@ -118,8 +150,9 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||
bool defer_push = false;
|
||||
|
||||
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_msg_send(cmd->id);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&cmd_mgr->lock);
|
||||
|
||||
if (cmd_mgr->state == RWNX_CMD_MGR_STATE_CRASHED) {
|
||||
@ -225,6 +258,7 @@ static int cmd_mgr_queue(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd)
|
||||
cmd_complete(cmd_mgr, cmd);
|
||||
}
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
rwnx_exception_event(cmd_mgr);
|
||||
} else {
|
||||
kfree(cmd);
|
||||
if (!list_empty(&cmd_mgr->cmds))
|
||||
@ -341,6 +375,7 @@ void cmd_mgr_task_process(struct work_struct *work)
|
||||
cmd_complete(cmd_mgr, next);
|
||||
}
|
||||
spin_unlock_bh(&cmd_mgr->lock);
|
||||
rwnx_exception_event(cmd_mgr);
|
||||
} else
|
||||
kfree(next);
|
||||
}
|
||||
@ -358,9 +393,9 @@ static int cmd_mgr_run_callback(struct rwnx_hw *rwnx_hw, struct rwnx_cmd *cmd,
|
||||
return 0;
|
||||
}
|
||||
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
spin_lock_bh(&rwnx_hw->cb_lock);
|
||||
//spin_lock_bh(&rwnx_hw->cb_lock);
|
||||
res = cb(rwnx_hw, cmd, msg);
|
||||
spin_unlock_bh(&rwnx_hw->cb_lock);
|
||||
//spin_unlock_bh(&rwnx_hw->cb_lock);
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -384,8 +419,9 @@ static int cmd_mgr_msgind(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd_e2amsg *
|
||||
bool found = false;
|
||||
|
||||
// RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_msg_recv(msg->id);
|
||||
|
||||
#endif
|
||||
//printk("cmd->id=%x\n", msg->id);
|
||||
spin_lock_bh(&cmd_mgr->lock);
|
||||
list_for_each_entry(cmd, &cmd_mgr->cmds, list) {
|
||||
|
||||
@ -1225,6 +1225,34 @@ static ssize_t rwnx_dbgfs_set_write(struct file *file,
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(set);
|
||||
#endif /* CONFIG_RWNX_RADAR */
|
||||
|
||||
static ssize_t rwnx_dbgfs_regdbg_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct rwnx_hw *priv = file->private_data;
|
||||
char buf[32];
|
||||
u32 addr, val, oper;
|
||||
size_t len = min_t(size_t, count, sizeof(buf) - 1);
|
||||
struct dbg_mem_read_cfm mem_read_cfm;
|
||||
int ret;
|
||||
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
|
||||
if (sscanf(buf, "%x %x %x", &oper, &addr, &val) > 0)
|
||||
printk("addr=%x, val=%x,oper=%d\n", addr, val, oper);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
DEBUGFS_WRITE_FILE_OPS(regdbg);
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
|
||||
#define LINE_MAX_SZ 150
|
||||
|
||||
@ -126,6 +126,13 @@ struct rwnx_csa {
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
struct apm_probe_sta {
|
||||
u8 sta_mac_addr[6];
|
||||
u8 vif_idx;
|
||||
u64 probe_id;
|
||||
struct work_struct apmprobestaWork;
|
||||
struct workqueue_struct *apmprobesta_wq;
|
||||
};
|
||||
/// Possible States of the TDLS link.
|
||||
enum tdls_status_tag {
|
||||
/// TDLS link is not active (no TDLS peer connected)
|
||||
@ -229,6 +236,7 @@ struct rwnx_vif {
|
||||
|
||||
u8_l key_has_add;
|
||||
u8_l is_p2p_vif;
|
||||
struct apm_probe_sta sta_probe;
|
||||
};
|
||||
|
||||
#define RWNX_VIF_TYPE(rwnx_vif) (rwnx_vif->wdev.iftype)
|
||||
@ -508,6 +516,8 @@ struct rwnx_hw {
|
||||
bool band_5g_support;
|
||||
u8_l vendor_info;
|
||||
bool fwlog_en;
|
||||
u16 chipid;
|
||||
u8 cpmode;
|
||||
|
||||
struct list_head defrag_list;
|
||||
spinlock_t defrag_lock;
|
||||
@ -516,6 +526,13 @@ struct rwnx_hw {
|
||||
struct workqueue_struct *apmStaloss_wq;
|
||||
u8 apm_vif_idx;
|
||||
u8 sta_mac_addr[6];
|
||||
|
||||
struct wakeup_source *ws_rx;
|
||||
struct wakeup_source *ws_tx;
|
||||
struct wakeup_source *ws_pwrctrl;
|
||||
|
||||
u8 wakeup_enable;
|
||||
u32 hostwake_irq_num;
|
||||
};
|
||||
|
||||
u8 *rwnx_build_bcn(struct rwnx_bcn *bcn, struct cfg80211_beacon_data *new);
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#include "aicwf_usb.h"
|
||||
#endif
|
||||
#include "aic_bsp_export.h"
|
||||
#include "rwnx_wakelock.h"
|
||||
|
||||
#define RW_DRV_DESCRIPTION "RivieraWaves 11nac driver for Linux cfg80211"
|
||||
#define RW_DRV_COPYRIGHT "Copyright(c) 2015-2017 RivieraWaves"
|
||||
@ -687,18 +688,48 @@ static void rwnx_del_csa(struct rwnx_vif *vif)
|
||||
kfree(csa);
|
||||
vif->ap.csa = NULL;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)
|
||||
static void rwnx_csa_finish(struct work_struct *ws)
|
||||
{
|
||||
struct rwnx_csa *csa = container_of(ws, struct rwnx_csa, work);
|
||||
struct rwnx_vif *vif = csa->vif;
|
||||
struct rwnx_hw *rwnx_hw = vif->rwnx_hw;
|
||||
int error = csa->status;
|
||||
u8 *buf, *pos;
|
||||
|
||||
if (!error)
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
buf = kmalloc(csa->bcn.len, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
printk ("%s buf fail\n", __func__);
|
||||
return;
|
||||
}
|
||||
pos = buf;
|
||||
|
||||
memcpy(pos, csa->bcn.head, csa->bcn.head_len);
|
||||
pos += csa->bcn.head_len;
|
||||
*pos++ = WLAN_EID_TIM;
|
||||
*pos++ = 4;
|
||||
*pos++ = 0;
|
||||
*pos++ = csa->bcn.dtim;
|
||||
*pos++ = 0;
|
||||
*pos++ = 0;
|
||||
if (csa->bcn.tail) {
|
||||
memcpy(pos, csa->bcn.tail, csa->bcn.tail_len);
|
||||
pos += csa->bcn.tail_len;
|
||||
}
|
||||
if (csa->bcn.ies) {
|
||||
memcpy(pos, csa->bcn.ies, csa->bcn.ies_len);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
error = rwnx_send_bcn(rwnx_hw, buf, vif->vif_index, csa->bcn.len);
|
||||
if (error)
|
||||
return;
|
||||
error = rwnx_send_bcn_change(rwnx_hw, vif->vif_index, 0,
|
||||
csa->bcn.len, csa->bcn.head_len,
|
||||
csa->bcn.tim_len, NULL);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
|
||||
@ -724,6 +755,7 @@ static void rwnx_csa_finish(struct work_struct *ws)
|
||||
}
|
||||
rwnx_del_csa(vif);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* rwnx_external_auth_enable - Enable external authentication on a vif
|
||||
@ -1601,7 +1633,7 @@ int handle_private_cmd(struct net_device *net, char *command, u32 cmd_len)
|
||||
} else {
|
||||
printk("wrong args\n");
|
||||
}
|
||||
} else if (strcasecmp(argv[0], "SETSUSPENDMODE") == 0) {
|
||||
} else if (strcasecmp(argv[0], "SETSUSPENDMODE") == 0 && g_rwnx_plat->sdiodev->rwnx_hw->cpmode != AICBSP_CPMODE_TEST) {
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
setsusp_mode = command_strtoul(argv[1], NULL, 10);
|
||||
rwnx_send_me_set_lp_level(g_rwnx_plat->sdiodev->rwnx_hw, setsusp_mode);
|
||||
@ -2345,7 +2377,6 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
|
||||
if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)
|
||||
p2p = true;
|
||||
|
||||
if (type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_P2P_GO) {
|
||||
if (vif->up) {
|
||||
/* Abort scan request on the vif */
|
||||
if (vif->rwnx_hw->scan_request &&
|
||||
@ -2388,7 +2419,6 @@ static int rwnx_cfg80211_change_iface(struct wiphy *wiphy,
|
||||
vif->vif_index = add_if_cfm.inst_nbr;
|
||||
vif->rwnx_hw->vif_table[add_if_cfm.inst_nbr] = vif;
|
||||
spin_unlock_bh(&vif->rwnx_hw->cb_lock);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -2465,6 +2495,9 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
if (rwnx_hw->cpmode == AICBSP_CPMODE_TEST)
|
||||
return -EBUSY;
|
||||
|
||||
if (scanning) {
|
||||
printk("is scanning, abort\n");
|
||||
error = rwnx_send_scanu_cancel_req(rwnx_hw, NULL);
|
||||
@ -2473,12 +2506,11 @@ static int rwnx_cfg80211_scan(struct wiphy *wiphy,
|
||||
msleep(150);
|
||||
}
|
||||
|
||||
rwnx_hw->scan_request = request;
|
||||
error = rwnx_send_scanu_req(rwnx_hw, rwnx_vif, request);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
rwnx_hw->scan_request = request;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2703,7 +2735,7 @@ static int rwnx_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
key_params.cipher = sme->crypto.cipher_group;
|
||||
rwnx_cfg80211_add_key(wiphy, dev, sme->key_idx, false, NULL, &key_params);
|
||||
}
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
|
||||
else if ((sme->auth_type == NL80211_AUTHTYPE_SAE) &&
|
||||
!(sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) {
|
||||
netdev_err(dev, "Doesn't support SAE without external authentication\n");
|
||||
@ -2759,7 +2791,7 @@ static int rwnx_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||
return rwnx_send_sm_disconnect_req(rwnx_hw, rwnx_vif, reason_code);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
|
||||
/**
|
||||
* @external_auth: indicates result of offloaded authentication processing from
|
||||
* user space
|
||||
@ -2965,6 +2997,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||
macaddr = cur->mac_addr;
|
||||
printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
|
||||
macaddr[3], macaddr[4], macaddr[5]);
|
||||
spin_lock_bh(&rx_priv->stas_reord_lock);
|
||||
list_for_each_entry_safe(reord_info, reord_tmp,
|
||||
&rx_priv->stas_reord_list, list) {
|
||||
printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \
|
||||
@ -2974,6 +3007,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rx_priv->stas_reord_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2992,7 +3026,7 @@ static int rwnx_cfg80211_del_station_compat(struct wiphy *wiphy,
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
rwnx_dbgfs_unregister_rc_stat(rwnx_hw, cur);
|
||||
#endif
|
||||
found++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3056,9 +3090,9 @@ void apm_staloss_work_process(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
||||
/*if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP || rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
|
||||
cfg80211_del_sta(rwnx_vif->ndev, cur->mac_addr, GFP_KERNEL);
|
||||
}
|
||||
}*/
|
||||
|
||||
#ifdef AICWF_RX_REORDER
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
@ -3072,6 +3106,7 @@ void apm_staloss_work_process(struct work_struct *work)
|
||||
macaddr = cur->mac_addr;
|
||||
printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
|
||||
macaddr[3], macaddr[4], macaddr[5]);
|
||||
spin_lock_bh(&rx_priv->stas_reord_lock);
|
||||
list_for_each_entry_safe(reord_info, reord_tmp,
|
||||
&rx_priv->stas_reord_list, list) {
|
||||
printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \
|
||||
@ -3081,6 +3116,7 @@ void apm_staloss_work_process(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rx_priv->stas_reord_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -3110,7 +3146,39 @@ void apm_staloss_work_process(struct work_struct *work)
|
||||
rwnx_update_mesh_power_mode(rwnx_vif);
|
||||
}
|
||||
|
||||
void apm_probe_sta_work_process(struct work_struct *work)
|
||||
{
|
||||
struct apm_probe_sta *probe_sta = container_of(work, struct apm_probe_sta, apmprobestaWork);
|
||||
struct rwnx_vif *rwnx_vif = container_of(probe_sta, struct rwnx_vif, sta_probe);
|
||||
bool found = false;
|
||||
struct rwnx_sta *cur, *tmp;
|
||||
|
||||
u8 *mac = rwnx_vif->sta_probe.sta_mac_addr;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
list_for_each_entry_safe(cur, tmp, &rwnx_vif->ap.sta_list, list) {
|
||||
if (!memcmp(cur->mac_addr, mac, ETH_ALEN)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printk("sta %pM found = %d\n", mac, found);
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
if (found)
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, 0, false, GFP_ATOMIC);
|
||||
else
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 0, 0, false, GFP_ATOMIC);
|
||||
#else
|
||||
if (found)
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 1, GFP_ATOMIC);
|
||||
else
|
||||
cfg80211_probe_status(rwnx_vif->ndev, mac, (u64)rwnx_vif->sta_probe.probe_id, 0, GFP_ATOMIC);
|
||||
|
||||
#endif
|
||||
rwnx_vif->sta_probe.probe_id++;
|
||||
}
|
||||
/**
|
||||
* @change_station: Modify a given station. Note that flags changes are not much
|
||||
* validated in cfg80211, in particular the auth/assoc/authorized flags
|
||||
@ -3281,6 +3349,12 @@ static int rwnx_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
INIT_WORK(&rwnx_vif->sta_probe.apmprobestaWork, apm_probe_sta_work_process);
|
||||
rwnx_vif->sta_probe.apmprobesta_wq = create_singlethread_workqueue("apmprobe_wq");
|
||||
if (!rwnx_vif->sta_probe.apmprobesta_wq) {
|
||||
txrx_err("insufficient memory to create apmprobe_wq.\n");
|
||||
return -ENOBUFS;
|
||||
}
|
||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)
|
||||
rwnx_hw->is_p2p_connected = 1;
|
||||
/* Forward the information to the LMAC */
|
||||
@ -3412,6 +3486,9 @@ static int rwnx_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
||||
rwnx_del_bcn(&rwnx_vif->ap.bcn);
|
||||
rwnx_del_csa(rwnx_vif);
|
||||
|
||||
flush_workqueue(rwnx_vif->sta_probe.apmprobesta_wq);
|
||||
destroy_workqueue(rwnx_vif->sta_probe.apmprobesta_wq);
|
||||
|
||||
netif_tx_stop_all_queues(dev);
|
||||
netif_carrier_off(dev);
|
||||
|
||||
@ -3489,6 +3566,29 @@ static int rwnx_cfg80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
int rwnx_cfg80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
|
||||
const u8 *peer, u64 *cookie)
|
||||
{
|
||||
//struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
struct rwnx_vif *vif = netdev_priv(dev);
|
||||
struct rwnx_sta *sta = NULL;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
if ((RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP) && (RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_P2P_GO) &&
|
||||
(RWNX_VIF_TYPE(vif) != NL80211_IFTYPE_AP_VLAN))
|
||||
return -EINVAL;
|
||||
list_for_each_entry(sta, &vif->ap.sta_list, list) {
|
||||
if (sta->valid && ether_addr_equal(sta->mac_addr, peer))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sta)
|
||||
return -ENOENT;
|
||||
|
||||
|
||||
memcpy(vif->sta_probe.sta_mac_addr, peer, 6);
|
||||
queue_work(vif->sta_probe.apmprobesta_wq, &vif->sta_probe.apmprobestaWork);
|
||||
|
||||
*cookie = vif->sta_probe.probe_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3639,8 +3739,9 @@ rwnx_cfg80211_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* For debug purpose (use ftrace kernel option) */
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_roc(rwnx_vif->vif_index, chan->center_freq, duration);
|
||||
|
||||
#endif
|
||||
/* Check that no other RoC procedure has been launched */
|
||||
if (rwnx_hw->roc_elem) {
|
||||
msleep(2);
|
||||
@ -3731,13 +3832,15 @@ static int rwnx_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
u64 cookie)
|
||||
{
|
||||
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev);//netdev_priv(wdev->netdev);
|
||||
|
||||
#endif
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* For debug purpose (use ftrace kernel option) */
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_cancel_roc(rwnx_vif->vif_index);
|
||||
|
||||
#endif
|
||||
/* Check if a RoC procedure is pending */
|
||||
if (!rwnx_hw->roc_elem) {
|
||||
return 0;
|
||||
@ -3885,11 +3988,11 @@ static int rwnx_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
/* Get STA on which management frame has to be sent */
|
||||
rwnx_sta = rwnx_retrieve_sta(rwnx_hw, rwnx_vif, mgmt->da,
|
||||
mgmt->frame_control, ap);
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mgmt_tx((channel) ? channel->center_freq : 0,
|
||||
rwnx_vif->vif_index, (rwnx_sta) ? rwnx_sta->sta_idx : 0xFF,
|
||||
mgmt);
|
||||
|
||||
#endif
|
||||
if (ap || rwnx_sta)
|
||||
goto send_frame;
|
||||
|
||||
@ -4098,7 +4201,11 @@ int rwnx_cfg80211_channel_switch (struct wiphy *wiphy,
|
||||
goto end;
|
||||
} else {
|
||||
INIT_WORK(&csa->work, rwnx_csa_finish);
|
||||
rwnx_cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count);
|
||||
rwnx_cfg80211_ch_switch_started_notify(dev, &csa->chandef, params->count
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
|
||||
, params->block_tx
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
end:
|
||||
@ -4471,7 +4578,8 @@ static int rwnx_fill_station_info(struct rwnx_sta *sta, struct rwnx_vif *vif,
|
||||
case FORMATMOD_HE_SU:
|
||||
case FORMATMOD_HE_ER:
|
||||
sinfo->rxrate.flags = RATE_INFO_FLAGS_VHT_MCS;
|
||||
sinfo->rxrate.mcs = rx_vect1->he.mcs;
|
||||
sinfo->rxrate.mcs = rx_vect1->he.mcs;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EINVAL;
|
||||
@ -4527,7 +4635,7 @@ static int rwnx_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev
|
||||
if (sta)
|
||||
return rwnx_fill_station_info(sta, vif, sinfo);
|
||||
|
||||
return -EINVAL;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
||||
@ -5031,7 +5139,7 @@ static struct cfg80211_ops rwnx_cfg80211_ops = {
|
||||
.tdls_mgmt = rwnx_cfg80211_tdls_mgmt,
|
||||
.tdls_oper = rwnx_cfg80211_tdls_oper,
|
||||
.change_bss = rwnx_cfg80211_change_bss,
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
|
||||
.external_auth = rwnx_cfg80211_external_auth,
|
||||
#endif
|
||||
};
|
||||
@ -5122,7 +5230,6 @@ static const struct wiphy_wowlan_support aic_wowlan_support = {
|
||||
*
|
||||
*/
|
||||
extern int aicwf_vendor_init(struct wiphy *wiphy);
|
||||
extern txpwr_idx_conf_t nvram_txpwr_idx;
|
||||
|
||||
int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
|
||||
{
|
||||
@ -5158,6 +5265,7 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
|
||||
rwnx_hw->wiphy = wiphy;
|
||||
rwnx_hw->plat = rwnx_plat;
|
||||
rwnx_hw->dev = rwnx_platform_get_dev(rwnx_plat);
|
||||
rwnx_hw->chipid = feature.chipinfo->chipid;
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
rwnx_hw->sdiodev = rwnx_plat->sdiodev;
|
||||
rwnx_plat->sdiodev->rwnx_hw = rwnx_hw;
|
||||
@ -5170,6 +5278,7 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
|
||||
rwnx_hw->mod_params = &rwnx_mod_params;
|
||||
rwnx_hw->tcp_pacing_shift = 7;
|
||||
|
||||
aicwf_wakeup_lock_init(rwnx_hw);
|
||||
rwnx_init_aic(rwnx_hw);
|
||||
/* set device pointer for wiphy */
|
||||
set_wiphy_dev(wiphy, rwnx_hw->dev);
|
||||
@ -5232,6 +5341,7 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
|
||||
wiphy->mgmt_stypes = rwnx_default_mgmt_stypes;
|
||||
|
||||
rwnx_hw->fwlog_en = feature.fwlog_en;
|
||||
rwnx_hw->cpmode = feature.cpmode;
|
||||
ret = rwnx_send_set_stack_start_req(rwnx_hw, 1, feature.hwinfo < 0, feature.hwinfo, feature.fwlog_en, &set_start_cfm);
|
||||
if (ret)
|
||||
goto err_lmac_reqs;
|
||||
@ -5285,7 +5395,7 @@ int rwnx_cfg80211_init(struct rwnx_plat *rwnx_plat, void **platform_data)
|
||||
#endif
|
||||
0;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
|
||||
wiphy->features |= NL80211_FEATURE_SAE;
|
||||
#endif
|
||||
|
||||
@ -5450,6 +5560,7 @@ err_platon:
|
||||
//err_config:
|
||||
kmem_cache_destroy(rwnx_hw->sw_txhdr_cache);
|
||||
err_cache:
|
||||
aicwf_wakeup_lock_deinit(rwnx_hw);
|
||||
wiphy_free(wiphy);
|
||||
err_out:
|
||||
return ret;
|
||||
@ -5495,6 +5606,7 @@ void rwnx_cfg80211_deinit(struct rwnx_hw *rwnx_hw)
|
||||
rwnx_radar_detection_deinit(&rwnx_hw->radar);
|
||||
rwnx_platform_off(rwnx_hw, NULL);
|
||||
kmem_cache_destroy(rwnx_hw->sw_txhdr_cache);
|
||||
aicwf_wakeup_lock_deinit(rwnx_hw);
|
||||
wiphy_free(rwnx_hw->wiphy);
|
||||
}
|
||||
|
||||
@ -5551,6 +5663,7 @@ static int __init rwnx_mod_init(void)
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
aicwf_usb_exit();
|
||||
#endif /*AICWF_USB_SUPPORT */
|
||||
aicbsp_set_subsys(AIC_WIFI, AIC_PWR_OFF);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ struct rwnx_mod_params rwnx_mod_params = {
|
||||
COMMON_PARAM(vht_on, true, true)
|
||||
COMMON_PARAM(he_on, true, true)
|
||||
COMMON_PARAM(mcs_map, IEEE80211_VHT_MCS_SUPPORT_0_9, IEEE80211_VHT_MCS_SUPPORT_0_9)
|
||||
COMMON_PARAM(he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_9, IEEE80211_HE_MCS_SUPPORT_0_9)
|
||||
COMMON_PARAM(he_mcs_map, IEEE80211_HE_MCS_SUPPORT_0_11, IEEE80211_HE_MCS_SUPPORT_0_11)
|
||||
COMMON_PARAM(he_ul_on, false, false)
|
||||
COMMON_PARAM(ldpc_on, true, true)
|
||||
COMMON_PARAM(stbc_on, true, true)
|
||||
@ -973,9 +973,15 @@ 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 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 |
|
||||
IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU;
|
||||
#else
|
||||
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 |
|
||||
IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA;
|
||||
#endif
|
||||
if (rwnx_hw->mod_params->bfmee) {
|
||||
he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;
|
||||
he_cap->he_cap_elem.phy_cap_info[4] |=
|
||||
@ -983,12 +989,21 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
||||
}
|
||||
he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||
he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
#else
|
||||
he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
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[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
|
||||
@ -1062,9 +1077,15 @@ 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 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 |
|
||||
IEEE80211_HE_PHY_CAP3_RX_PARTIAL_BW_SU_IN_20MHZ_MU;
|
||||
#else
|
||||
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 |
|
||||
IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA;
|
||||
#endif
|
||||
if (rwnx_hw->mod_params->bfmee) {
|
||||
he_cap->he_cap_elem.phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE;
|
||||
he_cap->he_cap_elem.phy_cap_info[4] |=
|
||||
@ -1072,12 +1093,21 @@ static void rwnx_set_he_capa(struct rwnx_hw *rwnx_hw, struct wiphy *wiphy)
|
||||
}
|
||||
he_cap->he_cap_elem.phy_cap_info[5] |= IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||
he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMING_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMING_PARTIAL_BW_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
#else
|
||||
he_cap->he_cap_elem.phy_cap_info[6] |= IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
|
||||
IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
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[8] |= IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)
|
||||
|
||||
@ -45,7 +45,7 @@ static int rwnx_freq_to_idx(struct rwnx_hw *rwnx_hw, int freq)
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(1);
|
||||
WARN_ON(1);
|
||||
|
||||
exit:
|
||||
// Channel has been found, return the index
|
||||
@ -218,8 +218,9 @@ static inline int rwnx_rx_remain_on_channel_exp_ind(struct rwnx_hw *rwnx_hw,
|
||||
|
||||
rwnx_vif = container_of(roc_elem->wdev, struct rwnx_vif, wdev);
|
||||
/* For debug purpose (use ftrace kernel option) */
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_roc_exp(rwnx_vif->vif_index);
|
||||
|
||||
#endif
|
||||
/* If mgmt_roc is true, remain on channel has been started by ourself */
|
||||
/* If RoC has been cancelled before we switched on channel, do not call cfg80211 */
|
||||
if (!roc_elem->mgmt_roc && roc_elem->on_chan) {
|
||||
@ -506,7 +507,7 @@ static inline int rwnx_rx_ps_change_ind(struct rwnx_hw *rwnx_hw,
|
||||
} else if (rwnx_hw->adding_sta) {
|
||||
sta->ps.active = ind->ps_state ? true : false;
|
||||
} else {
|
||||
if (rwnx_hw->vif_table[sta->vif_idx]->ndev)
|
||||
if (rwnx_hw->vif_table[sta->vif_idx] && rwnx_hw->vif_table[sta->vif_idx]->ndev)
|
||||
netdev_err(rwnx_hw->vif_table[sta->vif_idx]->ndev,
|
||||
"Ignore PS mode change on invalid sta\n");
|
||||
}
|
||||
@ -572,7 +573,6 @@ static inline int rwnx_rx_scanu_start_cfm(struct rwnx_hw *rwnx_hw,
|
||||
{
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
scanning = 0;
|
||||
if (rwnx_hw->scan_request) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
|
||||
struct cfg80211_scan_info info = {
|
||||
@ -586,6 +586,7 @@ static inline int rwnx_rx_scanu_start_cfm(struct rwnx_hw *rwnx_hw,
|
||||
}
|
||||
|
||||
rwnx_hw->scan_request = NULL;
|
||||
scanning = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -633,7 +634,7 @@ static inline int rwnx_rx_scanu_result_ind(struct rwnx_hw *rwnx_hw,
|
||||
CFG80211_BSS_FTYPE_UNKNOWN,
|
||||
#endif
|
||||
mgmt->bssid, tsf, capability, beacon_interval,
|
||||
ie, ielen, ind->rssi * 100, GFP_KERNEL);
|
||||
ie, ielen, ind->rssi * 100, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
if (bss != NULL)
|
||||
@ -842,7 +843,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
||||
{
|
||||
struct sm_disconnect_ind *ind = (struct sm_disconnect_ind *)msg->param;
|
||||
struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx];
|
||||
struct net_device *dev = rwnx_vif->ndev;
|
||||
struct net_device *dev;
|
||||
#ifdef AICWF_RX_REORDER
|
||||
struct reord_ctrl_info *reord_info, *tmp;
|
||||
u8 *macaddr;
|
||||
@ -852,6 +853,10 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
dhcped = 0;
|
||||
|
||||
if (!rwnx_vif)
|
||||
return 0;
|
||||
dev = rwnx_vif->ndev;
|
||||
|
||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
|
||||
rwnx_hw->is_p2p_connected = 0;
|
||||
/* if vif is not up, rwnx_close has already been called */
|
||||
@ -879,7 +884,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
||||
macaddr = rwnx_vif->ndev->dev_addr;
|
||||
printk("deinit:macaddr:%x,%x,%x,%x,%x,%x\r\n", macaddr[0], macaddr[1], macaddr[2], \
|
||||
macaddr[3], macaddr[4], macaddr[5]);
|
||||
|
||||
spin_lock_bh(&rx_priv->stas_reord_lock);
|
||||
list_for_each_entry_safe(reord_info, tmp, &rx_priv->stas_reord_list, list) {
|
||||
macaddr = rwnx_vif->ndev->dev_addr;
|
||||
printk("reord_mac:%x,%x,%x,%x,%x,%x\r\n", reord_info->mac_addr[0], reord_info->mac_addr[1], reord_info->mac_addr[2], \
|
||||
@ -889,6 +894,7 @@ static inline int rwnx_rx_sm_disconnect_ind(struct rwnx_hw *rwnx_hw,
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rx_priv->stas_reord_lock);
|
||||
} else if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_AP) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
|
||||
BUG();//should be not here: del_sta function
|
||||
}
|
||||
@ -914,7 +920,7 @@ static inline int rwnx_rx_sm_external_auth_required_ind(struct rwnx_hw *rwnx_hw,
|
||||
struct sm_external_auth_required_ind *ind =
|
||||
(struct sm_external_auth_required_ind *)msg->param;
|
||||
struct rwnx_vif *rwnx_vif = rwnx_hw->vif_table[ind->vif_idx];
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) || defined(CONFIG_WPA3_FOR_OLD_KERNEL)
|
||||
struct net_device *dev = rwnx_vif->ndev;
|
||||
struct cfg80211_external_auth_params params;
|
||||
|
||||
@ -1090,7 +1096,9 @@ static inline int rwnx_rx_mesh_path_update_ind(struct rwnx_hw *rwnx_hw,
|
||||
/* Check if element has been deleted */
|
||||
if (ind->delete) {
|
||||
if (found) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mesh_delete_path(mesh_path);
|
||||
#endif
|
||||
/* Remove element from list */
|
||||
list_del_init(&mesh_path->list);
|
||||
/* Free the element */
|
||||
@ -1100,7 +1108,9 @@ static inline int rwnx_rx_mesh_path_update_ind(struct rwnx_hw *rwnx_hw,
|
||||
if (found) {
|
||||
// Update the Next Hop STA
|
||||
mesh_path->p_nhop_sta = &rwnx_hw->sta_table[ind->nhop_sta_idx];
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mesh_update_path(mesh_path);
|
||||
#endif
|
||||
} else {
|
||||
// Allocate a Mesh Path structure
|
||||
mesh_path = (struct rwnx_mesh_path *)kmalloc(sizeof(struct rwnx_mesh_path), GFP_ATOMIC);
|
||||
@ -1114,8 +1124,9 @@ static inline int rwnx_rx_mesh_path_update_ind(struct rwnx_hw *rwnx_hw,
|
||||
|
||||
// Insert the path in the list of path
|
||||
list_add_tail(&mesh_path->list, &rwnx_vif->ap.mpath_list);
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mesh_create_path(mesh_path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#include "rwnx_compat.h"
|
||||
#include "rwnx_cmds.h"
|
||||
#include "aicwf_txrxif.h"
|
||||
#include "rwnx_wakelock.h"
|
||||
#include "aic_bsp_export.h"
|
||||
|
||||
const struct mac_addr mac_addr_bcst = {{0xFFFF, 0xFFFF, 0xFFFF}};
|
||||
|
||||
@ -227,6 +229,7 @@ static int rwnx_send_msg(struct rwnx_hw *rwnx_hw, const void *msg_params,
|
||||
|
||||
//RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
rwnx_wakeup_lock_timeout(rwnx_hw->ws_tx, jiffies_to_msecs(5));
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
if (rwnx_hw->usbdev->state == USB_DOWN_ST) {
|
||||
rwnx_msg_free(rwnx_hw, msg_params);
|
||||
@ -325,6 +328,7 @@ static int rwnx_send_msg1(struct rwnx_hw *rwnx_hw, const void *msg_params,
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
rwnx_wakeup_lock_timeout(rwnx_hw->ws_tx, jiffies_to_msecs(5));
|
||||
msg = container_of((void *)msg_params, struct lmac_msg, param);
|
||||
|
||||
//nonblock = is_non_blocking_msg(msg->id);
|
||||
@ -853,6 +857,9 @@ int rwnx_send_coex_req(struct rwnx_hw *rwnx_hw, u8_l disable_coexnull, u8_l enab
|
||||
struct mm_set_coex_req *coex_req;
|
||||
int error;
|
||||
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC && rwnx_hw->cpmode == AICBSP_CPMODE_TEST)
|
||||
return 0;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* Build the MM_SET_COEX_REQ message */
|
||||
@ -908,8 +915,12 @@ int rwnx_send_rf_config_req(struct rwnx_hw *rwnx_hw)
|
||||
int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
|
||||
{
|
||||
struct mm_set_rf_calib_req *rf_calib_req;
|
||||
xtal_cap_conf_t xtal_cap = {0,};
|
||||
int error;
|
||||
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC && rwnx_hw->cpmode == AICBSP_CPMODE_TEST)
|
||||
return 0;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* Build the MM_SET_P2P_NOA_REQ message */
|
||||
@ -928,6 +939,13 @@ int rwnx_send_rf_calib_req(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *
|
||||
rf_calib_req->xtal_cap = 0;
|
||||
rf_calib_req->xtal_cap_fine = 0;
|
||||
|
||||
get_userconfig_xtal_cap(&xtal_cap);
|
||||
|
||||
if (xtal_cap.enable) {
|
||||
rf_calib_req->xtal_cap = xtal_cap.xtal_cap;
|
||||
rf_calib_req->xtal_cap_fine = xtal_cap.xtal_cap_fine;
|
||||
}
|
||||
|
||||
/* Send the MM_SET_RF_CALIB_REQ message to UMAC FW */
|
||||
error = rwnx_send_msg(rwnx_hw, rf_calib_req, 1, MM_SET_RF_CALIB_CFM, cfm);
|
||||
|
||||
@ -1044,6 +1062,52 @@ int rwnx_send_get_fw_version_req(struct rwnx_hw *rwnx_hw, struct mm_get_fw_versi
|
||||
return error;
|
||||
}
|
||||
|
||||
int rwnx_send_txpwr_lvl_req(struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
struct mm_set_txpwr_lvl_req *txpwr_lvl_req;
|
||||
txpwr_lvl_conf_v2_t txpwr_lvl_v2_tmp;
|
||||
txpwr_lvl_conf_v2_t *txpwr_lvl_v2;
|
||||
int error = 0;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* Build the MM_SET_TXPWR_LVL_REQ message */
|
||||
txpwr_lvl_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID,
|
||||
sizeof(struct mm_set_txpwr_lvl_req));
|
||||
|
||||
if (!txpwr_lvl_req) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
txpwr_lvl_v2 = &txpwr_lvl_v2_tmp;
|
||||
|
||||
get_userconfig_txpwr_lvl_v2(txpwr_lvl_v2);
|
||||
|
||||
if (txpwr_lvl_v2->enable == 0) {
|
||||
rwnx_msg_free(rwnx_hw, txpwr_lvl_req);
|
||||
} else {
|
||||
struct aicbsp_feature_t feature;
|
||||
aicbsp_get_feature(&feature);
|
||||
if ((feature.cpmode != AICBSP_CPMODE_TEST) && (feature.chipinfo->subrev == 0)) {
|
||||
txpwr_lvl_req->txpwr_lvl.enable = txpwr_lvl_v2->enable;
|
||||
txpwr_lvl_req->txpwr_lvl.dsss = txpwr_lvl_v2->pwrlvl_11b_11ag_2g4[3]; // 11M
|
||||
txpwr_lvl_req->txpwr_lvl.ofdmlowrate_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[4]; // MCS4
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm64qam_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[7]; // MCS7
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm256qam_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[9]; // MCS9
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm1024qam_2g4 = txpwr_lvl_v2->pwrlvl_11ax_2g4[11]; // MCS11
|
||||
txpwr_lvl_req->txpwr_lvl.ofdmlowrate_5g = 13; // unused
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm64qam_5g = 13; // unused
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm256qam_5g = 13; // unused
|
||||
txpwr_lvl_req->txpwr_lvl.ofdm1024qam_5g = 13; // unused
|
||||
} else {
|
||||
txpwr_lvl_req->txpwr_lvl_v2 = *txpwr_lvl_v2;
|
||||
}
|
||||
|
||||
/* Send the MM_SET_TXPWR_LVL_REQ message to UMAC FW */
|
||||
error = rwnx_send_msg(rwnx_hw, txpwr_lvl_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
@ -1051,10 +1115,14 @@ int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw)
|
||||
txpwr_idx_conf_t *txpwr_idx;
|
||||
int error;
|
||||
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC) {
|
||||
return rwnx_send_txpwr_lvl_req(rwnx_hw);
|
||||
}
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* Build the MM_SET_TXPWR_IDX_REQ message */
|
||||
txpwr_idx_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_REQ, TASK_MM, DRV_TASK_ID,
|
||||
txpwr_idx_req = rwnx_msg_zalloc(MM_SET_TXPWR_IDX_LVL_REQ, TASK_MM, DRV_TASK_ID,
|
||||
sizeof(struct mm_set_txpwr_idx_req));
|
||||
|
||||
if (!txpwr_idx_req) {
|
||||
@ -1080,7 +1148,7 @@ int rwnx_send_txpwr_idx_req(struct rwnx_hw *rwnx_hw)
|
||||
return 0;
|
||||
} else {
|
||||
/* Send the MM_SET_TXPWR_IDX_REQ message to UMAC FW */
|
||||
error = rwnx_send_msg(rwnx_hw, txpwr_idx_req, 1, MM_SET_TXPWR_IDX_CFM, NULL);
|
||||
error = rwnx_send_msg(rwnx_hw, txpwr_idx_req, 1, MM_SET_TXPWR_IDX_LVL_CFM, NULL);
|
||||
|
||||
return error;
|
||||
}
|
||||
@ -1149,6 +1217,8 @@ int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw)
|
||||
#endif
|
||||
uint8_t *ht_mcs;
|
||||
int i;
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC && rwnx_hw->cpmode == AICBSP_CPMODE_TEST)
|
||||
return 0;
|
||||
|
||||
if (rwnx_hw->band_5g_support) {
|
||||
ht_cap = &wiphy->bands[NL80211_BAND_5GHZ]->ht_cap;
|
||||
@ -1197,8 +1267,6 @@ int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw)
|
||||
#if defined(CONFIG_HE_FOR_OLD_KERNEL)
|
||||
if (1) {
|
||||
he_cap = &rwnx_he_capa.he_cap;
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
req->he_supp = he_cap->has_he;
|
||||
for (i = 0; i < ARRAY_SIZE(he_cap->he_cap_elem.mac_cap_info); i++) {
|
||||
@ -1218,7 +1286,6 @@ int rwnx_send_me_config_req(struct rwnx_hw *rwnx_hw)
|
||||
}
|
||||
req->he_ul_on = rwnx_hw->mod_params->he_ul_on;
|
||||
}
|
||||
}
|
||||
#else
|
||||
req->he_supp = false;
|
||||
req->he_ul_on = false;
|
||||
@ -1247,6 +1314,9 @@ int rwnx_send_me_chan_config_req(struct rwnx_hw *rwnx_hw)
|
||||
struct wiphy *wiphy = rwnx_hw->wiphy;
|
||||
int i;
|
||||
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC && rwnx_hw->cpmode == AICBSP_CPMODE_TEST)
|
||||
return 0;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
|
||||
/* Build the ME_CHAN_CONFIG_REQ message */
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include "reg_access.h"
|
||||
#include "hal_desc.h"
|
||||
#include "rwnx_main.h"
|
||||
#include "rwnx_pci.h"
|
||||
#ifndef CONFIG_RWNX_FHOST
|
||||
#include "ipc_host.h"
|
||||
#endif /* !CONFIG_RWNX_FHOST */
|
||||
@ -30,6 +29,12 @@
|
||||
#include "aicwf_usb.h"
|
||||
#endif
|
||||
|
||||
#ifdef AICWF_PCIE_SUPPORT
|
||||
#include "rwnx_pci.h"
|
||||
#endif
|
||||
|
||||
#include "aic_bsp_export.h"
|
||||
|
||||
struct rwnx_plat *g_rwnx_plat;
|
||||
|
||||
#ifdef CONFIG_RWNX_TL4
|
||||
@ -224,7 +229,9 @@ static int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
|
||||
|
||||
typedef struct {
|
||||
txpwr_idx_conf_t txpwr_idx;
|
||||
txpwr_lvl_conf_v2_t txpwr_lvl_v2;
|
||||
txpwr_ofst_conf_t txpwr_ofst;
|
||||
xtal_cap_conf_t xtal_cap;
|
||||
} nvram_info_t;
|
||||
|
||||
nvram_info_t nvram_info = {
|
||||
@ -240,6 +247,18 @@ nvram_info_t nvram_info = {
|
||||
.ofdm256qam_5g = 9,
|
||||
.ofdm1024qam_5g = 9
|
||||
},
|
||||
.txpwr_lvl_v2 = {
|
||||
.enable = 1,
|
||||
.pwrlvl_11b_11ag_2g4 = {
|
||||
// 1M, 2M, 5M5, 11M, 6M, 9M, 12M, 18M, 24M, 36M, 48M, 54M
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 18, 18, 16, 16},
|
||||
.pwrlvl_11n_11ac_2g4 = {
|
||||
// MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9
|
||||
20, 20, 20, 20, 18, 18, 16, 16, 16, 16},
|
||||
.pwrlvl_11ax_2g4 = {
|
||||
// MCS0, MCS1, MCS2, MCS3, MCS4, MCS5, MCS6, MCS7, MCS8, MCS9, MCS10, MCS11
|
||||
20, 20, 20, 20, 18, 18, 16, 16, 16, 16, 15, 15},
|
||||
},
|
||||
.txpwr_ofst = {
|
||||
.enable = 1,
|
||||
.chan_1_4 = 0,
|
||||
@ -250,8 +269,18 @@ nvram_info_t nvram_info = {
|
||||
.chan_122_140 = 0,
|
||||
.chan_142_165 = 0,
|
||||
},
|
||||
.xtal_cap = {
|
||||
.enable = 0,
|
||||
.xtal_cap = 24,
|
||||
.xtal_cap_fine = 31,
|
||||
},
|
||||
};
|
||||
|
||||
void get_userconfig_txpwr_lvl_v2(txpwr_lvl_conf_v2_t *txpwr_lvl_v2)
|
||||
{
|
||||
memcpy(txpwr_lvl_v2, &(nvram_info.txpwr_lvl_v2), sizeof(txpwr_lvl_conf_v2_t));
|
||||
}
|
||||
|
||||
void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx)
|
||||
{
|
||||
memcpy(txpwr_idx, &(nvram_info.txpwr_idx), sizeof(txpwr_idx_conf_t));
|
||||
@ -262,6 +291,11 @@ void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst)
|
||||
memcpy(txpwr_ofst, &(nvram_info.txpwr_ofst), sizeof(txpwr_ofst_conf_t));
|
||||
}
|
||||
|
||||
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap)
|
||||
{
|
||||
memcpy(xtal_cap, &(nvram_info.xtal_cap), sizeof(xtal_cap_conf_t));
|
||||
}
|
||||
|
||||
#define MATCH_NODE(type, node, cfg_key) {cfg_key, offsetof(type, node)}
|
||||
|
||||
struct parse_match_t {
|
||||
@ -272,6 +306,7 @@ struct parse_match_t {
|
||||
static const char *parse_key_prefix[] = {
|
||||
[0x01] = "module0_",
|
||||
[0x21] = "module1_",
|
||||
[0xFF] = "",
|
||||
};
|
||||
|
||||
static const struct parse_match_t parse_match_tab[] = {
|
||||
@ -286,6 +321,43 @@ static const struct parse_match_t parse_match_tab[] = {
|
||||
MATCH_NODE(nvram_info_t, txpwr_idx.ofdm256qam_5g, "ofdm256qam_5g"),
|
||||
MATCH_NODE(nvram_info_t, txpwr_idx.ofdm1024qam_5g, "ofdm1024qam_5g"),
|
||||
|
||||
{"lvl_11b_11ag_1m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 0},
|
||||
{"lvl_11b_11ag_2m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 1},
|
||||
{"lvl_11b_11ag_5m5_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 2},
|
||||
{"lvl_11b_11ag_11m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 3},
|
||||
{"lvl_11b_11ag_6m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 4},
|
||||
{"lvl_11b_11ag_9m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 5},
|
||||
{"lvl_11b_11ag_12m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 6},
|
||||
{"lvl_11b_11ag_18m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 7},
|
||||
{"lvl_11b_11ag_24m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 8},
|
||||
{"lvl_11b_11ag_36m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 9},
|
||||
{"lvl_11b_11ag_48m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 10},
|
||||
{"lvl_11b_11ag_54m_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11b_11ag_2g4) + 11},
|
||||
|
||||
{"lvl_11n_11ac_mcs0_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 0},
|
||||
{"lvl_11n_11ac_mcs1_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 1},
|
||||
{"lvl_11n_11ac_mcs2_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 2},
|
||||
{"lvl_11n_11ac_mcs3_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 3},
|
||||
{"lvl_11n_11ac_mcs4_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 4},
|
||||
{"lvl_11n_11ac_mcs5_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 5},
|
||||
{"lvl_11n_11ac_mcs6_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 6},
|
||||
{"lvl_11n_11ac_mcs7_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 7},
|
||||
{"lvl_11n_11ac_mcs8_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 8},
|
||||
{"lvl_11n_11ac_mcs9_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11n_11ac_2g4) + 9},
|
||||
|
||||
{"lvl_11ax_mcs0_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 0},
|
||||
{"lvl_11ax_mcs1_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 1},
|
||||
{"lvl_11ax_mcs2_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 2},
|
||||
{"lvl_11ax_mcs3_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 3},
|
||||
{"lvl_11ax_mcs4_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 4},
|
||||
{"lvl_11ax_mcs5_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 5},
|
||||
{"lvl_11ax_mcs6_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 6},
|
||||
{"lvl_11ax_mcs7_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 7},
|
||||
{"lvl_11ax_mcs8_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 8},
|
||||
{"lvl_11ax_mcs9_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 9},
|
||||
{"lvl_11ax_mcs10_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 10},
|
||||
{"lvl_11ax_mcs11_2g4", offsetof(nvram_info_t, txpwr_lvl_v2.pwrlvl_11ax_2g4) + 11},
|
||||
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.enable, "ofst_enable"),
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.chan_1_4, "ofst_chan_1_4"),
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.chan_5_9, "ofst_chan_5_9"),
|
||||
@ -294,6 +366,10 @@ static const struct parse_match_t parse_match_tab[] = {
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.chan_100_120, "ofst_chan_100_120"),
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.chan_122_140, "ofst_chan_122_140"),
|
||||
MATCH_NODE(nvram_info_t, txpwr_ofst.chan_142_165, "ofst_chan_142_165"),
|
||||
|
||||
MATCH_NODE(nvram_info_t, xtal_cap.enable, "xtal_enable"),
|
||||
MATCH_NODE(nvram_info_t, xtal_cap.xtal_cap, "xtal_cap"),
|
||||
MATCH_NODE(nvram_info_t, xtal_cap.xtal_cap_fine, "xtal_cap_fine"),
|
||||
};
|
||||
|
||||
static int parse_key_val(const char *str, const char *key, char *val)
|
||||
@ -366,6 +442,7 @@ void rwnx_plat_userconfig_parsing(struct rwnx_hw *rwnx_hw, char *buffer, int siz
|
||||
char *data;
|
||||
int i = 0, err, len = 0;
|
||||
long val;
|
||||
u8 efuse_idx = 0;
|
||||
|
||||
if (size <= 0) {
|
||||
pr_err("Config buffer size %d error\n", size);
|
||||
@ -377,6 +454,15 @@ void rwnx_plat_userconfig_parsing(struct rwnx_hw *rwnx_hw, char *buffer, int siz
|
||||
return;
|
||||
}
|
||||
|
||||
efuse_idx = rwnx_hw->vendor_info;
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC || rwnx_hw->chipid == PRODUCT_ID_AIC8800DW) {
|
||||
printk("AIC8800DC chipset\n");
|
||||
efuse_idx = 0xFF;
|
||||
} else if (rwnx_hw->vendor_info == 0x00) {
|
||||
printk("Empty efuse, using module0 config\n");
|
||||
efuse_idx = 0x01;
|
||||
}
|
||||
|
||||
data = vmalloc(size + 1);
|
||||
if (!data) {
|
||||
pr_err("vmalloc fail\n");
|
||||
@ -402,10 +488,10 @@ void rwnx_plat_userconfig_parsing(struct rwnx_hw *rwnx_hw, char *buffer, int siz
|
||||
|
||||
// store value to data struct
|
||||
for (i = 0; i < sizeof(parse_match_tab) / sizeof(parse_match_tab[0]); i++) {
|
||||
sprintf(&keyname[0], "%s%s", parse_key_prefix[rwnx_hw->vendor_info], parse_match_tab[i].keyname);
|
||||
sprintf(&keyname[0], "%s%s", parse_key_prefix[efuse_idx], parse_match_tab[i].keyname);
|
||||
if (parse_key_val(line, keyname, conf) == 0) {
|
||||
err = kstrtol(conf, 0, &val);
|
||||
*(unsigned long *)((unsigned long)&nvram_info + parse_match_tab[i].offset) = val;
|
||||
*(unsigned char *)((unsigned long)&nvram_info + parse_match_tab[i].offset) = val;
|
||||
printk("%s, %s = %ld\n", __func__, parse_match_tab[i].keyname, val);
|
||||
break;
|
||||
}
|
||||
@ -414,7 +500,8 @@ void rwnx_plat_userconfig_parsing(struct rwnx_hw *rwnx_hw, char *buffer, int siz
|
||||
vfree(data);
|
||||
}
|
||||
|
||||
#define FW_USERCONFIG_NAME "aic_userconfig.txt"
|
||||
#define FW_USERCONFIG_NAME_8800D "aic_userconfig.txt"
|
||||
#define FW_USERCONFIG_NAME_8800DC "aic8800dc/aic_userconfig.txt"
|
||||
|
||||
int rwnx_plat_userconfig_upload_android(struct rwnx_hw *rwnx_hw, char *filename)
|
||||
{
|
||||
@ -457,7 +544,11 @@ static int rwnx_plat_fmac_load(struct rwnx_hw *rwnx_hw)
|
||||
int ret = 0;
|
||||
|
||||
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
||||
ret = rwnx_plat_userconfig_upload_android(rwnx_hw, FW_USERCONFIG_NAME);
|
||||
if (rwnx_hw->chipid == PRODUCT_ID_AIC8800D)
|
||||
ret = rwnx_plat_userconfig_upload_android(rwnx_hw, FW_USERCONFIG_NAME_8800D);
|
||||
else if (rwnx_hw->chipid == PRODUCT_ID_AIC8800DC)
|
||||
ret = rwnx_plat_userconfig_upload_android(rwnx_hw, FW_USERCONFIG_NAME_8800DC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !CONFIG_ROM_PATCH_EN */
|
||||
@ -788,6 +879,7 @@ void rwnx_platform_deinit(struct rwnx_hw *rwnx_hw)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef AICWF_PCIE_SUPPORT
|
||||
/**
|
||||
* rwnx_platform_register_drv() - Register all possible platform drivers
|
||||
*/
|
||||
@ -804,6 +896,23 @@ void rwnx_platform_unregister_drv(void)
|
||||
{
|
||||
return rwnx_pci_unregister_drv();
|
||||
}
|
||||
#else
|
||||
/**
|
||||
* rwnx_platform_register_drv() - Register all possible platform drivers
|
||||
*/
|
||||
int rwnx_platform_register_drv(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* rwnx_platform_unregister_drv() - Unegister all platform drivers
|
||||
*/
|
||||
void rwnx_platform_unregister_drv(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat)
|
||||
{
|
||||
@ -813,7 +922,9 @@ struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat)
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
return rwnx_plat->usbdev->dev;
|
||||
#endif
|
||||
#ifdef AICWF_PCIE_SUPPORT
|
||||
return &(rwnx_plat->pci_dev->dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -111,8 +111,10 @@ void rwnx_platform_off(struct rwnx_hw *rwnx_hw, void **config);
|
||||
int rwnx_platform_register_drv(void);
|
||||
void rwnx_platform_unregister_drv(void);
|
||||
|
||||
void get_userconfig_txpwr_lvl_v2(txpwr_lvl_conf_v2_t *txpwr_lvl_v2);
|
||||
void get_userconfig_txpwr_idx(txpwr_idx_conf_t *txpwr_idx);
|
||||
void get_userconfig_txpwr_ofst(txpwr_ofst_conf_t *txpwr_ofst);
|
||||
void get_userconfig_xtal_cap(xtal_cap_conf_t *xtal_cap);
|
||||
|
||||
extern struct device *rwnx_platform_get_dev(struct rwnx_plat *rwnx_plat);
|
||||
|
||||
|
||||
@ -1125,7 +1125,9 @@ static bool dfs_pattern_detector_add_pulse(struct dfs_pattern_detector *dpd,
|
||||
ps = pde->ops->add_pulse(pde, len, dpd->last_pulse_ts, pri);
|
||||
|
||||
if (ps != NULL) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_radar_detected(chain, dpd->region, pde->freq, i, ps->pri);
|
||||
#endif
|
||||
// reset everything instead of just the channel detector
|
||||
dfs_pattern_detector_reset(dpd);
|
||||
return true;
|
||||
@ -1339,7 +1341,9 @@ static void rwnx_radar_process_pulse(struct work_struct *ws)
|
||||
|
||||
for (i = 0; i < pulses_count[chain] ; i++) {
|
||||
struct radar_pulse *p = (struct radar_pulse *)&pulses[chain][i];
|
||||
#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)) {
|
||||
@ -1444,9 +1448,9 @@ bool rwnx_radar_set_domain(struct rwnx_radar *radar,
|
||||
{
|
||||
if (radar->dpd[0] == NULL)
|
||||
return false;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_radar_set_region(region);
|
||||
|
||||
#endif
|
||||
return (dfs_pattern_detector_set_domain(radar->dpd[RWNX_RADAR_RIU],
|
||||
region, RWNX_RADAR_RIU) &&
|
||||
dfs_pattern_detector_set_domain(radar->dpd[RWNX_RADAR_FCU],
|
||||
@ -1456,7 +1460,9 @@ bool rwnx_radar_set_domain(struct rwnx_radar *radar,
|
||||
void rwnx_radar_detection_enable(struct rwnx_radar *radar, u8 enable, u8 chain)
|
||||
{
|
||||
if (chain < RWNX_RADAR_LAST) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_radar_enable_detection(radar->dpd[chain]->region, enable, chain);
|
||||
#endif
|
||||
spin_lock_bh(&radar->lock);
|
||||
radar->dpd[chain]->enabled = enable;
|
||||
spin_unlock_bh(&radar->lock);
|
||||
|
||||
@ -626,10 +626,10 @@ static void rwnx_rx_mgmt_any(struct rwnx_hw *rwnx_hw, struct sk_buff *skb,
|
||||
{
|
||||
struct rwnx_vif *rwnx_vif;
|
||||
int vif_idx = hw_rxhdr->flags_vif_idx;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mgmt_rx(hw_rxhdr->phy_info.phy_prim20_freq, vif_idx,
|
||||
hw_rxhdr->flags_sta_idx, (struct ieee80211_mgmt *)skb->data);
|
||||
|
||||
#endif
|
||||
if (vif_idx == RWNX_INVALID_VIF) {
|
||||
list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
|
||||
if (!rwnx_vif->up)
|
||||
@ -1264,13 +1264,6 @@ void reord_deinit_sta(struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reo
|
||||
for (i = 0; i < 8; i++) {
|
||||
struct recv_msdu *req, *next;
|
||||
preorder_ctrl = &reord_info->preorder_ctrl[i];
|
||||
if (preorder_ctrl->enable) {
|
||||
preorder_ctrl->enable = false;
|
||||
if (timer_pending(&preorder_ctrl->reord_timer)) {
|
||||
ret = del_timer_sync(&preorder_ctrl->reord_timer);
|
||||
}
|
||||
cancel_work_sync(&preorder_ctrl->reord_timer_work);
|
||||
}
|
||||
spin_lock_irqsave(&preorder_ctrl->reord_list_lock, flags);
|
||||
list_for_each_entry_safe(req, next, &preorder_ctrl->reord_list, reord_pending_list) {
|
||||
list_del_init(&req->reord_pending_list);
|
||||
@ -1280,11 +1273,13 @@ void reord_deinit_sta(struct aicwf_rx_priv *rx_priv, struct reord_ctrl_info *reo
|
||||
reord_rxframe_free(&rx_priv->freeq_lock, &rx_priv->rxframes_freequeue, &req->rxframe_list);
|
||||
}
|
||||
spin_unlock_irqrestore(&preorder_ctrl->reord_list_lock, flags);
|
||||
if (timer_pending(&preorder_ctrl->reord_timer)) {
|
||||
ret = del_timer_sync(&preorder_ctrl->reord_timer);
|
||||
}
|
||||
cancel_work_sync(&preorder_ctrl->reord_timer_work);
|
||||
}
|
||||
|
||||
spin_lock_bh(&rx_priv->stas_reord_lock);
|
||||
list_del(&reord_info->list);
|
||||
spin_unlock_bh(&rx_priv->stas_reord_lock);
|
||||
kfree(reord_info);
|
||||
}
|
||||
|
||||
@ -1475,7 +1470,7 @@ int reord_process_unit(struct aicwf_rx_priv *rx_priv, struct sk_buff *skb, u16 s
|
||||
pframe->forward = forward;
|
||||
preorder_ctrl = pframe->preorder_ctrl;
|
||||
|
||||
if ((ntohs(eh->h_proto) == ETH_P_PAE) || (((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) && is_mcast))
|
||||
if ((ntohs(eh->h_proto) == ETH_P_PAE) || is_mcast)
|
||||
return reord_single_frame_ind(rx_priv, pframe);
|
||||
|
||||
if ((rwnx_vif->wdev.iftype == NL80211_IFTYPE_STATION) || (rwnx_vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
|
||||
|
||||
@ -119,8 +119,8 @@ static const char *const rwnx_mmid2str[MSG_I(MM_MAX)] = {
|
||||
[MSG_I(MM_GET_MAC_ADDR_CFM)] = "MM_GET_MAC_ADDR_CFM",
|
||||
[MSG_I(MM_GET_STA_INFO_REQ)] = "MM_GET_STA_INFO_REQ",
|
||||
[MSG_I(MM_GET_STA_INFO_CFM)] = "MM_GET_STA_INFO_CFM",
|
||||
[MSG_I(MM_SET_TXPWR_IDX_REQ)] = "MM_SET_TXPWR_IDX_REQ",
|
||||
[MSG_I(MM_SET_TXPWR_IDX_CFM)] = "MM_SET_TXPWR_IDX_CFM",
|
||||
[MSG_I(MM_SET_TXPWR_IDX_LVL_REQ)] = "MM_SET_TXPWR_IDX_LVL_REQ",
|
||||
[MSG_I(MM_SET_TXPWR_IDX_LVL_CFM)] = "MM_SET_TXPWR_IDX_LVL_CFM",
|
||||
[MSG_I(MM_SET_TXPWR_OFST_REQ)] = "MM_SET_TXPWR_OFST_REQ",
|
||||
[MSG_I(MM_SET_TXPWR_OFST_CFM)] = "MM_SET_TXPWR_OFST_CFM",
|
||||
[MSG_I(MM_SET_STACK_START_REQ)] = "MM_SET_STACK_START_REQ",
|
||||
@ -224,6 +224,8 @@ static const char *const rwnx_apmid2str[MSG_I(APM_MAX)] = {
|
||||
[MSG_I(APM_START_CAC_CFM)] = "APM_START_CAC_CFM",
|
||||
[MSG_I(APM_STOP_CAC_REQ)] = "APM_STOP_CAC_REQ",
|
||||
[MSG_I(APM_STOP_CAC_CFM)] = "APM_STOP_CAC_CFM",
|
||||
[MSG_I(APM_SET_BEACON_IE_REQ)] = "APM_SET_BEACON_IE_REQ",
|
||||
[MSG_I(APM_SET_BEACON_IE_CFM)] = "APM_SET_BEACON_IE_CFM",
|
||||
};
|
||||
|
||||
static const char *const rwnx_meshid2str[MSG_I(MESH_MAX)] = {
|
||||
|
||||
@ -41,7 +41,9 @@ void rwnx_set_traffic_status(struct rwnx_hw *rwnx_hw,
|
||||
} else {
|
||||
bool uapsd = (ps_id != LEGACY_PS_ID);
|
||||
rwnx_send_me_traffic_ind(rwnx_hw, sta->sta_idx, uapsd, available);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_traffic_update(sta->sta_idx, available, uapsd);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,8 +78,9 @@ void rwnx_ps_bh_enable(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||
struct rwnx_txq *txq;
|
||||
|
||||
if (enable) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_enable(sta);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
sta->ps.active = true;
|
||||
sta->ps.sp_cnt[LEGACY_PS_ID] = 0;
|
||||
@ -100,14 +103,15 @@ 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])
|
||||
/*if (sta->ps.pkt_ready[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);
|
||||
rwnx_set_traffic_status(rwnx_hw, sta, true, UAPSD_ID);*/
|
||||
} else {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_disable(sta->sta_idx);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
sta->ps.active = false;
|
||||
|
||||
@ -125,11 +129,11 @@ 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])
|
||||
/*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);
|
||||
rwnx_set_traffic_status(rwnx_hw, sta, false, UAPSD_ID);*/
|
||||
|
||||
tasklet_schedule(&rwnx_hw->task);
|
||||
}
|
||||
@ -168,9 +172,9 @@ void rwnx_ps_bh_traffic_req(struct rwnx_hw *rwnx_hw, struct rwnx_sta *sta,
|
||||
printk("sta %pM is not in Power Save mode", sta->mac_addr);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_traffic_req(sta, pkt_req, ps_id);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
|
||||
/* Fw may ask to stop a service period with PS_SP_INTERRUPTED. This only
|
||||
@ -446,9 +450,9 @@ static inline void rwnx_set_more_data_flag(struct rwnx_hw *rwnx_hw,
|
||||
if (unlikely(sta->ps.active)) {
|
||||
sta->ps.pkt_ready[txq->ps_id]--;
|
||||
sta->ps.sp_cnt[txq->ps_id]--;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_push(sta);
|
||||
|
||||
#endif
|
||||
if (((txq->ps_id == UAPSD_ID) || (vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) || (sta->tdls.active))
|
||||
&& !sta->ps.sp_cnt[txq->ps_id]) {
|
||||
sw_txhdr->desc.host.flags |= TXU_CNTRL_EOSP;
|
||||
@ -578,7 +582,8 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags)
|
||||
between queue and push (because of PS) */
|
||||
sw_txhdr->hw_queue = hw_queue;
|
||||
|
||||
sw_txhdr->desc.host.packet_addr = hw_queue; //use packet_addr field for hw_txq
|
||||
//sw_txhdr->desc.host.packet_addr = hw_queue; //use packet_addr field for hw_txq
|
||||
sw_txhdr->desc.host.ac = hw_queue; //use ac field for hw_txq
|
||||
#ifdef CONFIG_RWNX_MUMIMO_TX
|
||||
/* MU group is only selected during hwq processing */
|
||||
sw_txhdr->desc.host.mumimo_info = txq->mumimo_info;
|
||||
@ -589,8 +594,9 @@ void rwnx_tx_push(struct rwnx_hw *rwnx_hw, struct rwnx_txhdr *txhdr, int flags)
|
||||
/* only for AP mode */
|
||||
rwnx_set_more_data_flag(rwnx_hw, sw_txhdr);
|
||||
}
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_push_desc(skb, sw_txhdr, flags);
|
||||
#endif
|
||||
#if 0
|
||||
txq->credits--;
|
||||
#endif
|
||||
@ -674,12 +680,6 @@ static void rwnx_tx_retry(struct rwnx_hw *rwnx_hw, struct sk_buff *skb,
|
||||
|
||||
if (!sw_retry) {
|
||||
/* update sw desc */
|
||||
sw_txhdr->desc.host.sn = cfm->sn;
|
||||
sw_txhdr->desc.host.pn[0] = cfm->pn[0];
|
||||
sw_txhdr->desc.host.pn[1] = cfm->pn[1];
|
||||
sw_txhdr->desc.host.pn[2] = cfm->pn[2];
|
||||
sw_txhdr->desc.host.pn[3] = cfm->pn[3];
|
||||
sw_txhdr->desc.host.timestamp = cfm->timestamp;
|
||||
sw_txhdr->desc.host.flags |= TXU_CNTRL_RETRY;
|
||||
|
||||
#ifdef CONFIG_RWNX_AMSDUS_TX
|
||||
@ -1094,7 +1094,7 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
(memcmp(desc->host.eth_dest_addr.array, rwnx_vif->sta.tdls_sta->mac_addr, ETH_ALEN) == 0)) {
|
||||
desc->host.flags |= TXU_CNTRL_TDLS;
|
||||
rwnx_vif->sta.tdls_sta->tdls.last_tid = desc->host.tid;
|
||||
rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn;
|
||||
//rwnx_vif->sta.tdls_sta->tdls.last_sn = desc->host.sn;
|
||||
}
|
||||
|
||||
if (rwnx_vif->wdev.iftype == NL80211_IFTYPE_MESH_POINT) {
|
||||
@ -1121,12 +1121,6 @@ netdev_tx_t rwnx_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
/* Fill-in TX descriptor */
|
||||
frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr)
|
||||
+ hdr_pads;// + sizeof(*eth);
|
||||
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||
desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft;
|
||||
desc->host.packet_cnt = 1;
|
||||
#else
|
||||
desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft;
|
||||
#endif
|
||||
desc->host.status_desc_addr = sw_txhdr->dma_addr;
|
||||
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
@ -1311,12 +1305,6 @@ int rwnx_start_mgmt_xmit(struct rwnx_vif *vif, struct rwnx_sta *sta,
|
||||
}
|
||||
|
||||
frame_oft = sizeof(struct rwnx_txhdr) - offsetof(struct rwnx_txhdr, hw_hdr);
|
||||
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
|
||||
desc->host.packet_addr[0] = sw_txhdr->dma_addr + frame_oft;
|
||||
desc->host.packet_cnt = 1;
|
||||
#else
|
||||
desc->host.packet_addr = sw_txhdr->dma_addr + frame_oft;
|
||||
#endif
|
||||
desc->host.status_desc_addr = sw_txhdr->dma_addr;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -1359,6 +1347,19 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(AICWF_USB_SUPPORT)
|
||||
if (rwnx_hw->usbdev->state == USB_DOWN_ST)
|
||||
#elif defined(AICWF_SDIO_SUPPORT)
|
||||
if (rwnx_hw->sdiodev->bus_if->state == BUS_DOWN_ST)
|
||||
#endif
|
||||
{
|
||||
headroom = sw_txhdr->headroom;
|
||||
kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr);
|
||||
skb_pull(skb, headroom);
|
||||
consume_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
txq = sw_txhdr->txq;
|
||||
/* don't use txq->hwq as it may have changed between push and confirm */
|
||||
hwq = &rwnx_hw->hwq[sw_txhdr->hw_queue];
|
||||
@ -1369,11 +1370,11 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
printk("done=%d retry_required=%d sw_retry_required=%d acknowledged=%d\n",
|
||||
rwnx_txst.tx_done, rwnx_txst.retry_required,
|
||||
rwnx_txst.sw_retry_required, rwnx_txst.acknowledged);
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_mgmt_cfm(sw_txhdr->rwnx_vif->vif_index,
|
||||
(sw_txhdr->rwnx_sta) ? sw_txhdr->rwnx_sta->sta_idx : 0xFF,
|
||||
rwnx_txst.acknowledged);
|
||||
|
||||
#endif
|
||||
/* Confirm transmission to CFG80211 */
|
||||
cfg80211_mgmt_tx_status(&sw_txhdr->rwnx_vif->wdev,
|
||||
(unsigned long)skb,
|
||||
@ -1393,9 +1394,9 @@ int rwnx_txdatacfm(void *pthis, void *host_id)
|
||||
rwnx_tx_retry(rwnx_hw, skb, txhdr, sw_retry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_skb_confirm(skb, txq, hwq, &txhdr->hw_hdr.cfm);
|
||||
|
||||
#endif
|
||||
/* STA may have disconnect (and txq stopped) when buffers were stored
|
||||
in fw. In this case do nothing when they're returned */
|
||||
if (txq->idx != TXQ_INACTIVE) {
|
||||
@ -1469,7 +1470,9 @@ void rwnx_txq_credit_update(struct rwnx_hw *rwnx_hw, int sta_idx, u8 tid,
|
||||
|
||||
if (txq->idx != TXQ_INACTIVE) {
|
||||
//txq->credits += update;
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_credit_update(txq, update);
|
||||
#endif
|
||||
if (txq->credits <= 0)
|
||||
rwnx_txq_stop(txq, RWNX_TXQ_STOP_FULL);
|
||||
else
|
||||
|
||||
@ -137,15 +137,15 @@ void rwnx_txq_flush(struct rwnx_hw *rwnx_hw, struct rwnx_txq *txq)
|
||||
if (sw_txhdr->desc.host.packet_cnt > 1) {
|
||||
struct rwnx_amsdu_txhdr *amsdu_txhdr;
|
||||
list_for_each_entry(amsdu_txhdr, &sw_txhdr->amsdu.hdrs, list) {
|
||||
dma_unmap_single(rwnx_hw->dev, amsdu_txhdr->dma_addr,
|
||||
amsdu_txhdr->map_len, DMA_TO_DEVICE);
|
||||
//dma_unmap_single(rwnx_hw->dev, amsdu_txhdr->dma_addr,
|
||||
// amsdu_txhdr->map_len, DMA_TO_DEVICE);
|
||||
dev_kfree_skb_any(amsdu_txhdr->skb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
kmem_cache_free(rwnx_hw->sw_txhdr_cache, sw_txhdr);
|
||||
dma_unmap_single(rwnx_hw->dev, sw_txhdr->dma_addr, sw_txhdr->map_len,
|
||||
DMA_TO_DEVICE);
|
||||
//dma_unmap_single(rwnx_hw->dev, sw_txhdr->dma_addr, sw_txhdr->map_len,
|
||||
// DMA_TO_DEVICE);
|
||||
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
dev_kfree_skb_any(skb);
|
||||
@ -384,7 +384,9 @@ void rwnx_txq_tdls_vif_deinit(struct rwnx_vif *rwnx_vif)
|
||||
void rwnx_txq_add_to_hw_list(struct rwnx_txq *txq)
|
||||
{
|
||||
if (!(txq->status & RWNX_TXQ_IN_HWQ_LIST)) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_add_to_hw(txq);
|
||||
#endif
|
||||
txq->status |= RWNX_TXQ_IN_HWQ_LIST;
|
||||
list_add_tail(&txq->sched_list, &txq->hwq->list);
|
||||
txq->hwq->need_processing = true;
|
||||
@ -402,7 +404,9 @@ void rwnx_txq_add_to_hw_list(struct rwnx_txq *txq)
|
||||
void rwnx_txq_del_from_hw_list(struct rwnx_txq *txq)
|
||||
{
|
||||
if (txq->status & RWNX_TXQ_IN_HWQ_LIST) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_del_from_hw(txq);
|
||||
#endif
|
||||
txq->status &= ~RWNX_TXQ_IN_HWQ_LIST;
|
||||
list_del(&txq->sched_list);
|
||||
}
|
||||
@ -440,7 +444,9 @@ void rwnx_txq_start(struct rwnx_txq *txq, u16 reason)
|
||||
{
|
||||
BUG_ON(txq == NULL);
|
||||
if (txq->idx != TXQ_INACTIVE && (txq->status & reason)) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_start(txq, reason);
|
||||
#endif
|
||||
txq->status &= ~reason;
|
||||
if (!rwnx_txq_is_stopped(txq) && rwnx_txq_skb_ready(txq))
|
||||
rwnx_txq_add_to_hw_list(txq);
|
||||
@ -460,7 +466,9 @@ void rwnx_txq_stop(struct rwnx_txq *txq, u16 reason)
|
||||
{
|
||||
BUG_ON(txq == NULL);
|
||||
if (txq->idx != TXQ_INACTIVE) {
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_stop(txq, reason);
|
||||
#endif
|
||||
txq->status |= reason;
|
||||
rwnx_txq_del_from_hw_list(txq);
|
||||
}
|
||||
@ -492,8 +500,9 @@ void rwnx_txq_sta_start(struct rwnx_sta *rwnx_sta, u16 reason
|
||||
{
|
||||
struct rwnx_txq *txq;
|
||||
int tid;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_sta_start(rwnx_sta->sta_idx);
|
||||
#endif
|
||||
|
||||
foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) {
|
||||
rwnx_txq_start(txq, reason);
|
||||
@ -528,8 +537,9 @@ void rwnx_txq_sta_stop(struct rwnx_sta *rwnx_sta, u16 reason
|
||||
|
||||
if (!rwnx_sta)
|
||||
return;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_sta_stop(rwnx_sta->sta_idx);
|
||||
#endif
|
||||
foreach_sta_txq(rwnx_sta, txq, tid, rwnx_hw) {
|
||||
rwnx_txq_stop(txq, reason);
|
||||
}
|
||||
@ -539,7 +549,9 @@ void rwnx_txq_sta_stop(struct rwnx_sta *rwnx_sta, u16 reason
|
||||
void rwnx_txq_tdls_sta_start(struct rwnx_vif *rwnx_vif, u16 reason,
|
||||
struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_vif_start(rwnx_vif->vif_index);
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
|
||||
if (rwnx_vif->sta.tdls_sta)
|
||||
@ -553,7 +565,9 @@ void rwnx_txq_tdls_sta_start(struct rwnx_vif *rwnx_vif, u16 reason,
|
||||
void rwnx_txq_tdls_sta_stop(struct rwnx_vif *rwnx_vif, u16 reason,
|
||||
struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_vif_stop(rwnx_vif->vif_index);
|
||||
#endif
|
||||
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
|
||||
@ -613,9 +627,9 @@ void rwnx_txq_vif_start(struct rwnx_vif *rwnx_vif, u16 reason,
|
||||
struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
struct rwnx_txq *txq;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_vif_start(rwnx_vif->vif_index);
|
||||
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
@ -657,8 +671,9 @@ void rwnx_txq_vif_stop(struct rwnx_vif *rwnx_vif, u16 reason,
|
||||
struct rwnx_hw *rwnx_hw)
|
||||
{
|
||||
struct rwnx_txq *txq;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_vif_stop(rwnx_vif->vif_index);
|
||||
#endif
|
||||
spin_lock_bh(&rwnx_hw->tx_lock);
|
||||
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
@ -758,8 +773,9 @@ int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq,
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
if (unlikely(txq->sta && txq->sta->ps.active)) {
|
||||
txq->sta->ps.pkt_ready[txq->ps_id]++;
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_ps_queue(txq->sta);
|
||||
|
||||
#endif
|
||||
if (txq->sta->ps.pkt_ready[txq->ps_id] == 1) {
|
||||
rwnx_set_traffic_status(rwnx_hw, txq->sta, true, txq->ps_id);
|
||||
}
|
||||
@ -778,9 +794,9 @@ int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq,
|
||||
txq->last_retry_skb = skb;
|
||||
txq->nb_retry++;
|
||||
}
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_queue_skb(skb, txq, retry);
|
||||
|
||||
#endif
|
||||
/* Flowctrl corresponding netdev queue if needed */
|
||||
#ifdef CONFIG_RWNX_FULLMAC
|
||||
/* If too many buffer are queued for this TXQ stop netdev queue */
|
||||
@ -788,7 +804,9 @@ int rwnx_txq_queue_skb(struct sk_buff *skb, struct rwnx_txq *txq,
|
||||
(skb_queue_len(&txq->sk_list) > RWNX_NDEV_FLOW_CTRL_STOP)) {
|
||||
txq->status |= RWNX_TXQ_NDEV_FLOW_CTRL;
|
||||
netif_stop_subqueue(txq->ndev, txq->ndev_idx);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_flowctrl_stop(txq);
|
||||
#endif
|
||||
}
|
||||
#else /* ! CONFIG_RWNX_FULLMAC */
|
||||
|
||||
@ -1150,9 +1168,9 @@ void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq)
|
||||
struct rwnx_txq *txq, *next;
|
||||
int user, credit_map = 0;
|
||||
bool mu_enable;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_process_hw_queue(hwq);
|
||||
|
||||
#endif
|
||||
hwq->need_processing = false;
|
||||
|
||||
mu_enable = rwnx_txq_take_mu_lock(rwnx_hw);
|
||||
@ -1164,10 +1182,15 @@ void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq)
|
||||
struct sk_buff_head sk_list_push;
|
||||
struct sk_buff *skb;
|
||||
bool txq_empty;
|
||||
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_process_txq(txq);
|
||||
#endif
|
||||
/* sanity check for debug */
|
||||
BUG_ON(!(txq->status & RWNX_TXQ_IN_HWQ_LIST));
|
||||
if (txq->idx == TXQ_INACTIVE) {
|
||||
printk("%s txq->idx == TXQ_INACTIVE \r\n", __func__);
|
||||
continue;
|
||||
}
|
||||
BUG_ON(txq->idx == TXQ_INACTIVE);
|
||||
BUG_ON(txq->credits <= 0);
|
||||
BUG_ON(!rwnx_txq_skb_ready(txq));
|
||||
@ -1213,10 +1236,12 @@ void rwnx_hwq_process(struct rwnx_hw *rwnx_hw, struct rwnx_hwq *hwq)
|
||||
|
||||
/* restart netdev queue if number of queued buffer is below threshold */
|
||||
if (unlikely(txq->status & RWNX_TXQ_NDEV_FLOW_CTRL) &&
|
||||
skb_queue_len(&txq->sk_list) < RWNX_NDEV_FLOW_CTRL_RESTART) {
|
||||
(skb_queue_len(&txq->sk_list) < RWNX_NDEV_FLOW_CTRL_RESTART)) {
|
||||
txq->status &= ~RWNX_TXQ_NDEV_FLOW_CTRL;
|
||||
netif_wake_subqueue(txq->ndev, txq->ndev_idx);
|
||||
#ifdef CREATE_TRACE_POINTS
|
||||
trace_txq_flowctrl_restart(txq);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_RWNX_FULLMAC */
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
static inline void rwnx_print_version(void)
|
||||
{
|
||||
printk(RWNX_VERS_BANNER"\n");
|
||||
printk("Driver Release Tag: %s\n", DRV_RELEASE_TAG);
|
||||
}
|
||||
|
||||
#endif /* _RWNX_VERSION_H_ */
|
||||
|
||||
@ -1,3 +1,15 @@
|
||||
#define RWNX_VERS_REV "241c091M (master)"
|
||||
#define RWNX_VERS_MOD "20211129-6.4.3.0"
|
||||
#define RWNX_VERS_REV "241c091M (master)"
|
||||
#define DRV_RELEASE_DATE "20221108"
|
||||
#define DRV_PATCH_LEVEL "004"
|
||||
#define RWNX_VERS_MOD DRV_RELEASE_DATE "-" DRV_PATCH_LEVEL "-6.4.3.0"
|
||||
#define RWNX_VERS_BANNER "rwnx " RWNX_VERS_MOD " - - " RWNX_VERS_REV
|
||||
|
||||
#if defined(AICWF_SDIO_SUPPORT)
|
||||
#define DRV_TYPE_NAME "sdio"
|
||||
#elif defined(AICWF_USB_SUPPORT)
|
||||
#define DRV_TYPE_NAME "usb"
|
||||
#else
|
||||
#define DRV_TYPE_NAME "unknow"
|
||||
#endif
|
||||
|
||||
#define DRV_RELEASE_TAG "aic-rwnx-" DRV_TYPE_NAME "-" DRV_RELEASE_DATE "-" DRV_PATCH_LEVEL
|
||||
|
||||
68
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c
Normal file
68
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.c
Normal file
@ -0,0 +1,68 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_wakeirq.h>
|
||||
#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
|
||||
return wakeup_source_register(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
__pm_stay_awake(ws);
|
||||
}
|
||||
|
||||
void rwnx_wakeup_unlock(struct wakeup_source *ws)
|
||||
{
|
||||
__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_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_pwrctrl);
|
||||
}
|
||||
|
||||
21
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.h
Normal file
21
drivers/net/wireless/aic8800/aic8800_fdrv/rwnx_wakelock.h
Normal file
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user