update:add luckfox-pico Ultra support
This commit is contained in:
committed by
luckfox-eng33
parent
1e160dee55
commit
d3153ac97e
+10
@@ -0,0 +1,10 @@
|
||||
*.o
|
||||
*.ko
|
||||
*.order
|
||||
*.symvers
|
||||
*.o.d
|
||||
*.o.cmd
|
||||
*.ko.cmd
|
||||
*.mod
|
||||
*.mod.c
|
||||
*.mod.cmd
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
EXTRA_CFLAGS += -Wno-unused-function
|
||||
|
||||
CONFIG_SDIO_SUPPORT := y
|
||||
CONFIG_SDIO_PWRCTRL := y
|
||||
# CONFIG_AIC_FW_PATH = "/vendor/etc/firmware"
|
||||
# CONFIG_AIC_FW_PATH = "/lib/firmware/aic8800dc_fw"
|
||||
CONFIG_AIC_FW_PATH = "/oem/usr/ko/aic8800dc_fw"
|
||||
export CONFIG_AIC_FW_PATH
|
||||
ccflags-y += -DCONFIG_AIC_FW_PATH=\"$(CONFIG_AIC_FW_PATH)\"
|
||||
|
||||
MODULE_NAME := aic8800_bsp
|
||||
ifeq ($(CONFIG_SDIO_SUPPORT), y)
|
||||
ccflags-y += -DAICWF_SDIO_SUPPORT
|
||||
ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL
|
||||
endif
|
||||
|
||||
CONFIG_GPIO_WAKEUP = n
|
||||
CONFIG_M2D_OTA_AUTO_SUPPORT = n
|
||||
CONFIG_M2D_OTA_LZMA_SUPPORT = n
|
||||
CONFIG_LINK_DET_5G = y
|
||||
CONFIG_MCU_MESSAGE = n
|
||||
CONFIG_FIRMWARE_ARRAY = n
|
||||
# Need to set fw path in BOARD_KERNEL_CMDLINE
|
||||
CONFIG_USE_FW_REQUEST = n
|
||||
CONFIG_FDRV_NO_REG_SDIO = n
|
||||
CONFIG_VRF_DCDC_MODE = y
|
||||
CONFIG_OOB = n
|
||||
CONFIG_PREALLOC_TXQ = y
|
||||
CONFIG_ONE_TXQ = n
|
||||
CONFIG_DPD = y
|
||||
CONFIG_FORCE_DPD_CALIB = y
|
||||
CONFIG_RESV_MEM_SUPPORT = y
|
||||
CONFIG_AMSDU_RX ?=n
|
||||
|
||||
ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP
|
||||
ccflags-$(CONFIG_M2D_OTA_AUTO_SUPPORT) += -DCONFIG_M2D_OTA_AUTO_SUPPORT
|
||||
ccflags-$(CONFIG_M2D_OTA_LZMA_SUPPORT) += -DCONFIG_M2D_OTA_LZMA_SUPPORT
|
||||
ccflags-$(CONFIG_LINK_DET_5G) += -DCONFIG_LINK_DET_5G
|
||||
ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE
|
||||
ccflags-$(CONFIG_FIRMWARE_ARRAY) += -DCONFIG_FIRMWARE_ARRAY
|
||||
ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST
|
||||
ccflags-$(CONFIG_FDRV_NO_REG_SDIO) += -DCONFIG_FDRV_NO_REG_SDIO
|
||||
ccflags-$(CONFIG_VRF_DCDC_MODE) += -DCONFIG_VRF_DCDC_MODE
|
||||
ccflags-$(CONFIG_OOB) += -DCONFIG_OOB
|
||||
ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
|
||||
ccflags-$(CONFIG_ONE_TXQ) += -DCONFIG_ONE_TXQ
|
||||
ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
|
||||
ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
|
||||
ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
|
||||
ccflags-$(CONFIG_AMSDU_RX) += -DCONFIG_AMSDU_RX
|
||||
|
||||
obj-m := $(MODULE_NAME).o
|
||||
$(MODULE_NAME)-y := \
|
||||
aic8800dc_compat.o \
|
||||
aic8800d80_compat.o \
|
||||
aic_bsp_main.o \
|
||||
aic_bsp_driver.o \
|
||||
aicsdio.o \
|
||||
aicsdio_txrxif.o \
|
||||
md5.o
|
||||
|
||||
$(MODULE_NAME)-$(CONFIG_PREALLOC_TXQ) += aicwf_txq_prealloc.o
|
||||
|
||||
ifeq ($(CONFIG_FIRMWARE_ARRAY),y)
|
||||
$(MODULE_NAME)-y += aicwf_firmware_array.o
|
||||
endif
|
||||
|
||||
# Platform support list
|
||||
CONFIG_PLATFORM_ROCKCHIP ?= n
|
||||
CONFIG_PLATFORM_ROCKCHIP2 ?= n
|
||||
CONFIG_PLATFORM_ALLWINNER ?=n
|
||||
CONFIG_PLATFORM_INGENIC_T20 ?= n
|
||||
CONFIG_PLATFORM_AMLOGIC ?= n
|
||||
CONFIG_PLATFORM_UBUNTU ?= y
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
|
||||
ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3399/rk3399-android-10/kernel
|
||||
#ARCH ?= arm64
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3399/rk3399-android-10/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3288/Android10/kernel/kernel/
|
||||
#ARCH ?= arm
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3288/Android10/tool/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/kernel
|
||||
#ARCH ?= arm
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android7/RK3229_ANDROID7.1_v1.01_20170914/rk3229_Android7.1_v1.01_xml0914/prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/kernel
|
||||
#ARCH ?= arm
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android9/rk3229_android9.0_box/prebuilts/gcc/linux-x86/arm/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3566/oudu/kernel
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3566/shengteng/kernel
|
||||
#ARCH ?= arm64
|
||||
#CROSS_COMPILE ?= ~/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
#KDIR ?= /home/yaya/E/Rockchip/3328/Android9/SDK/kernel/
|
||||
#ARCH ?= arm64
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3328/Android9/SDK/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
|
||||
ARCH ?= arm64
|
||||
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
|
||||
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
|
||||
ARCH ?= arm64
|
||||
KDIR ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/kernel
|
||||
CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/firefly/Android11.0/Firefly-RK356X_Android11.0_git_20210824/RK356X_Android11.0/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
|
||||
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
|
||||
#KDIR ?= /home/yaya/E/Allwinner/A133/a133-sdk/android/longan/out/kernel/build/
|
||||
#ARCH ?= arm64
|
||||
#CROSS_COMPILE ?= /home/yaya/E/Allwinner/A133/a133-sdk/android/longan/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
|
||||
KDIR ?= /home/yaya/E/Allwinner/r818/Android10/lichee/kernel/linux-4.9/
|
||||
ARCH ?= arm64
|
||||
CROSS_COMPILE ?= /home/yaya/E/Allwinner/r818/Android10/android/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_INGENIC_T20), y)
|
||||
KDIR ?= /home/yaya/E/T40/kernel
|
||||
ARCH ?= mips
|
||||
CROSS_COMPILE ?= /home/yaya/E/T40/mips-linux-gnu-ingenic-gcc7.2.0-glibc2.29-fp64/bin/mips-linux-gnu-
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
|
||||
ccflags-$(CONFIG_PLATFORM_AMLOGIC) += -DCONFIG_PLATFORM_AMLOGIC
|
||||
KDIR ?= /home/aiden/D1/SDK/Amlogic/905x3_a9/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
|
||||
ARCH ?= arm
|
||||
CROSS_COMPILE ?= /home/aiden/D1/SDK/Amlogic/905x3_a9/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
|
||||
ccflags-$(CONFIG_PLATFORM_UBUNTU) += -DCONFIG_PLATFORM_UBUNTU
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD ?= $(shell pwd)
|
||||
KVER ?= $(shell uname -r)
|
||||
MODDESTDIR ?= /lib/modules/$(KVER)/kernel/drivers/net/wireless/
|
||||
ARCH ?= x86_64
|
||||
CROSS_COMPILE ?=
|
||||
endif
|
||||
|
||||
|
||||
all: modules
|
||||
modules:
|
||||
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
|
||||
|
||||
install:
|
||||
mkdir -p $(MODDESTDIR)
|
||||
install -p -m 644 $(MODULE_NAME).ko $(MODDESTDIR)
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
uninstall:
|
||||
rm -rfv $(MODDESTDIR)/$(MODULE_NAME).ko
|
||||
/sbin/depmod -a ${KVER}
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.ko *.o.* *.mod.* modules.* Module.* .a* .o* .*.o.* *.mod .tmp* .cache.mk built-in.a
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
#include "aic8800d80_compat.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
extern struct aicbsp_info_t aicbsp_info;
|
||||
extern int adap_test;
|
||||
|
||||
typedef u32 (*array2_tbl_t)[2];
|
||||
|
||||
#define AIC_PATCH_MAGIG_NUM 0x48435450 // "PTCH"
|
||||
#define AIC_PATCH_MAGIG_NUM_2 0x50544348 // "HCTP"
|
||||
#define AIC_PATCH_BLOCK_MAX 4
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic_num;
|
||||
uint32_t pair_start;
|
||||
uint32_t magic_num_2;
|
||||
uint32_t pair_count;
|
||||
uint32_t block_dst[AIC_PATCH_BLOCK_MAX];
|
||||
uint32_t block_src[AIC_PATCH_BLOCK_MAX];
|
||||
uint32_t block_size[AIC_PATCH_BLOCK_MAX]; // word count
|
||||
} aic_patch_t;
|
||||
|
||||
#define AIC_PATCH_OFST(mem) ((size_t) &((aic_patch_t *)0)->mem)
|
||||
#define AIC_PATCH_ADDR(mem) ((u32)(aic_patch_str_base + AIC_PATCH_OFST(mem)))
|
||||
|
||||
u32 aicbsp_syscfg_tbl_8800d80[][2] = {
|
||||
};
|
||||
|
||||
int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
int syscfg_num = sizeof(aicbsp_syscfg_tbl_8800d80) / sizeof(u32) / 2;
|
||||
int ret, cnt;
|
||||
for (cnt = 0; cnt < syscfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, aicbsp_syscfg_tbl_8800d80[cnt][0], aicbsp_syscfg_tbl_8800d80[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", aicbsp_syscfg_tbl_8800d80[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 adaptivity_patch_tbl_8800d80[][2] = {
|
||||
{0x000C, 0x0000320A}, //linkloss_thd
|
||||
{0x009C, 0x00000000}, //ac_param_conf
|
||||
{0x0168, 0x00010000}, //tx_adaptivity_en
|
||||
};
|
||||
|
||||
u32 patch_tbl_8800d80[][2] = {
|
||||
#ifdef USE_5G
|
||||
{0x00b4, 0xf3010001},
|
||||
#else
|
||||
{0x00b4, 0xf3010000},
|
||||
#endif
|
||||
#if defined(CONFIG_AMSDU_RX)
|
||||
{0x170, 0x0100000a}
|
||||
#endif
|
||||
#if AIC_IRQ_WAKE_FLAG
|
||||
{0x00000170, 0x0000010a}, //irqf
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OOB
|
||||
// for 8800d40/d80 map data1 isr to gpiob1
|
||||
u32 gpio_cfg_tbl_8800d40d80[][2] = {
|
||||
{0x40504084, 0x00000006},
|
||||
{0x40500040, 0x00000000},
|
||||
{0x40100030, 0x00000001},
|
||||
{0x40241020, 0x00000001},
|
||||
{0x40240030, 0x00000004},
|
||||
{0x40240020, 0x03020700},
|
||||
};
|
||||
#endif
|
||||
|
||||
int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
#ifdef CONFIG_OOB
|
||||
int ret, cnt;
|
||||
int gpiocfg_num = sizeof(gpio_cfg_tbl_8800d40d80) / sizeof(u32) / 2;
|
||||
for (cnt = 0; cnt < gpiocfg_num; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, gpio_cfg_tbl_8800d40d80[cnt][0], gpio_cfg_tbl_8800d40d80[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail: %d\n", gpio_cfg_tbl_8800d40d80[cnt][0], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev)
|
||||
{
|
||||
const u32 rd_patch_addr = RAM_FMAC_FW_ADDR + 0x0198;
|
||||
u32 aic_patch_addr;
|
||||
u32 config_base, aic_patch_str_base;
|
||||
uint32_t start_addr = 0x0016F800;
|
||||
u32 patch_addr = start_addr;
|
||||
u32 patch_cnt = sizeof(patch_tbl_8800d80)/sizeof(u32)/2;
|
||||
struct dbg_mem_read_cfm rd_patch_addr_cfm;
|
||||
int ret = 0;
|
||||
int cnt = 0;
|
||||
//adap test
|
||||
int adap_patch_cnt = 0;
|
||||
|
||||
if (adap_test) {
|
||||
printk("%s for adaptivity test \r\n", __func__);
|
||||
adap_patch_cnt = sizeof(adaptivity_patch_tbl_8800d80)/sizeof(u32)/2;
|
||||
}
|
||||
|
||||
aic_patch_addr = rd_patch_addr + 8;
|
||||
|
||||
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_read_req(sdiodev, aic_patch_addr, &rd_patch_addr_cfm);
|
||||
if (ret) {
|
||||
printk("patch str rd fail\n");
|
||||
return ret;
|
||||
}
|
||||
aic_patch_str_base = rd_patch_addr_cfm.memdata;
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(magic_num), AIC_PATCH_MAGIG_NUM);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", AIC_PATCH_ADDR(magic_num));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(magic_num_2), AIC_PATCH_MAGIG_NUM_2);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", AIC_PATCH_ADDR(magic_num_2));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(pair_start), patch_addr);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", AIC_PATCH_ADDR(pair_start));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(pair_count), patch_cnt + adap_patch_cnt);
|
||||
if (ret) {
|
||||
printk("0x%x write fail\n", AIC_PATCH_ADDR(pair_count));
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (cnt = 0; cnt < patch_cnt; cnt++) {
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, patch_tbl_8800d80[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_8800d80[cnt][1]);
|
||||
if (ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt+4);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (adap_test){
|
||||
int tmp_cnt = patch_cnt + adap_patch_cnt;
|
||||
for (cnt = patch_cnt; cnt < tmp_cnt; cnt++) {
|
||||
int tbl_idx = cnt - patch_cnt;
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, start_addr+8*cnt, adaptivity_patch_tbl_8800d80[tbl_idx][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, adaptivity_patch_tbl_8800d80[tbl_idx][1]);
|
||||
if(ret) {
|
||||
printk("%x write fail\n", start_addr+8*cnt+4);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[0]), 0);
|
||||
if (ret) {
|
||||
printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[0]), ret);
|
||||
return ret;
|
||||
}
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[1]), 0);
|
||||
if (ret) {
|
||||
printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[1]), ret);
|
||||
return ret;
|
||||
}
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[2]), 0);
|
||||
if (ret) {
|
||||
printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[2]), ret);
|
||||
return ret;
|
||||
}
|
||||
ret = rwnx_send_dbg_mem_write_req(sdiodev, AIC_PATCH_ADDR(block_size[3]), 0);
|
||||
if (ret) {
|
||||
printk("block_size[0x%x] write fail: %d\n", AIC_PATCH_ADDR(block_size[3]), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _AIC8800D80_COMPAT_H_
|
||||
#define _AIC8800D80_COMPAT_H_
|
||||
|
||||
#include "aicsdio.h"
|
||||
/*typedef u32 (*array2_tbl_t)[2];
|
||||
|
||||
typedef uint8_t u8_l;
|
||||
typedef int8_t s8_l;
|
||||
typedef bool bool_l;
|
||||
typedef uint16_t u16_l;
|
||||
typedef int16_t s16_l;
|
||||
typedef uint32_t u32_l;
|
||||
typedef int32_t s32_l;
|
||||
typedef uint64_t u64_l;*/
|
||||
|
||||
int aicbsp_system_config_8800d80(struct aic_sdio_dev *sdiodev);
|
||||
int aicwifi_sys_config_8800d80(struct aic_sdio_dev *sdiodev);
|
||||
int aicwifi_patch_config_8800d80(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+2210
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
#ifndef _AIC8800DC_COMPAT_H_
|
||||
#define _AIC8800DC_COMPAT_H_
|
||||
|
||||
#include "aicsdio.h"
|
||||
typedef u32 (*array2_tbl_t)[2];
|
||||
typedef u32 (*array3_tbl_t)[3];
|
||||
|
||||
typedef uint8_t u8_l;
|
||||
typedef int8_t s8_l;
|
||||
typedef bool bool_l;
|
||||
typedef uint16_t u16_l;
|
||||
typedef int16_t s16_l;
|
||||
typedef uint32_t u32_l;
|
||||
typedef int32_t s32_l;
|
||||
typedef uint64_t u64_l;
|
||||
|
||||
extern u8 chip_sub_id;
|
||||
extern u8 chip_mcu_id;
|
||||
#define FW_PATH_MAX_LEN 200
|
||||
|
||||
void aicwf_patch_config_8800dc(struct aic_sdio_dev *rwnx_hw);
|
||||
void system_config_8800dc(struct aic_sdio_dev *rwnx_hw);
|
||||
int aicwf_misc_ram_init_8800dc(struct aic_sdio_dev *sdiodev);
|
||||
|
||||
#ifdef CONFIG_DPD
|
||||
int aicwf_dpd_calib_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
|
||||
int aicwf_dpd_result_apply_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
|
||||
#ifndef CONFIG_FORCE_DPD_CALIB
|
||||
int aicwf_dpd_result_load_8800dc(struct aic_sdio_dev *sdiodev, rf_misc_ram_lite_t *dpd_res);
|
||||
int aicwf_dpd_result_write_8800dc(void *buf, int buf_len);
|
||||
#endif/* !CONFIG_FORCE_DPD_CALIB */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+2051
File diff suppressed because it is too large
Load Diff
+566
@@ -0,0 +1,566 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* rwnx_cmds.h
|
||||
*
|
||||
* Copyright (C) RivieraWaves 2014-2019
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _AIC_BSP_DRIVER_H
|
||||
#define _AIC_BSP_DRIVER_H
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/module.h>
|
||||
#include "aic_bsp_export.h"
|
||||
|
||||
#define RWNX_80211_CMD_TIMEOUT_MS 3000//500//300
|
||||
|
||||
#define RWNX_CMD_FLAG_NONBLOCK BIT(0)
|
||||
#define RWNX_CMD_FLAG_REQ_CFM BIT(1)
|
||||
#define RWNX_CMD_FLAG_WAIT_PUSH BIT(2)
|
||||
#define RWNX_CMD_FLAG_WAIT_ACK BIT(3)
|
||||
#define RWNX_CMD_FLAG_WAIT_CFM BIT(4)
|
||||
#define RWNX_CMD_FLAG_DONE BIT(5)
|
||||
/* ATM IPC design makes it possible to get the CFM before the ACK,
|
||||
* otherwise this could have simply been a state enum */
|
||||
#define RWNX_CMD_WAIT_COMPLETE(flags) \
|
||||
(!(flags & (RWNX_CMD_FLAG_WAIT_ACK | RWNX_CMD_FLAG_WAIT_CFM)))
|
||||
|
||||
#define RWNX_CMD_MAX_QUEUED 8
|
||||
|
||||
#define IPC_E2A_MSG_PARAM_SIZE 256
|
||||
|
||||
#define RWNX_FN_ENTRY_STR ">>> %s()\n", __func__
|
||||
|
||||
/* message levels */
|
||||
#define LOGERROR 0x0001
|
||||
#define LOGINFO 0x0002
|
||||
#define LOGTRACE 0x0004
|
||||
#define LOGDEBUG 0x0008
|
||||
#define LOGDATA 0x0010
|
||||
|
||||
extern int aicwf_dbg_level_bsp;
|
||||
|
||||
#define AICWF_LOG "AICWFDBG("
|
||||
|
||||
#define AICWFDBG(level, args, arg...) \
|
||||
do { \
|
||||
if (aicwf_dbg_level_bsp & level) { \
|
||||
printk(AICWF_LOG#level")\t" args, ##arg); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RWNX_DBG(fmt, ...) \
|
||||
do { \
|
||||
if (aicwf_dbg_level_bsp & LOGTRACE) { \
|
||||
printk(AICWF_LOG"LOGTRACE)\t"fmt , ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/// Message structure for MSGs from Emb to App
|
||||
struct ipc_e2a_msg {
|
||||
u16 id; ///< Message id.
|
||||
u16 dummy_dest_id;
|
||||
u16 dummy_src_id;
|
||||
u16 param_len; ///< Parameter embedded struct length.
|
||||
u32 pattern; ///< Used to stamp a valid MSG buffer
|
||||
u32 param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned.
|
||||
};
|
||||
|
||||
typedef u16 lmac_msg_id_t;
|
||||
typedef u16 lmac_task_id_t;
|
||||
|
||||
struct lmac_msg {
|
||||
lmac_msg_id_t id; ///< Message id.
|
||||
lmac_task_id_t dest_id; ///< Destination kernel identifier.
|
||||
lmac_task_id_t src_id; ///< Source kernel identifier.
|
||||
u16 param_len; ///< Parameter embedded struct length.
|
||||
u32 param[]; ///< Parameter embedded struct. Must be word-aligned.
|
||||
};
|
||||
|
||||
#define rwnx_cmd_e2amsg ipc_e2a_msg
|
||||
#define rwnx_cmd_a2emsg lmac_msg
|
||||
#define RWNX_CMD_A2EMSG_LEN(m) (sizeof(struct lmac_msg) + m->param_len)
|
||||
#define RWNX_CMD_E2AMSG_LEN_MAX (IPC_E2A_MSG_PARAM_SIZE * 4)
|
||||
|
||||
static inline void put_u16(u8 *buf, u16 data)
|
||||
{
|
||||
buf[0] = (u8)(data&0x00ff);
|
||||
buf[1] = (u8)((data >> 8)&0x00ff);
|
||||
}
|
||||
|
||||
enum rwnx_cmd_mgr_state {
|
||||
RWNX_CMD_MGR_STATE_DEINIT,
|
||||
RWNX_CMD_MGR_STATE_INITED,
|
||||
RWNX_CMD_MGR_STATE_CRASHED,
|
||||
};
|
||||
|
||||
struct rwnx_cmd {
|
||||
struct list_head list;
|
||||
lmac_msg_id_t id;
|
||||
lmac_msg_id_t reqid;
|
||||
struct rwnx_cmd_a2emsg *a2e_msg;
|
||||
char *e2a_msg;
|
||||
u32 tkn;
|
||||
u16 flags;
|
||||
struct completion complete;
|
||||
u32 result;
|
||||
};
|
||||
|
||||
struct aic_sdio_dev;
|
||||
struct rwnx_cmd;
|
||||
typedef int (*msg_cb_fct)(struct rwnx_cmd *cmd, struct rwnx_cmd_e2amsg *msg);
|
||||
|
||||
struct rwnx_cmd_mgr {
|
||||
enum rwnx_cmd_mgr_state state;
|
||||
spinlock_t lock;
|
||||
u32 next_tkn;
|
||||
u32 queue_sz;
|
||||
u32 max_queue_sz;
|
||||
spinlock_t cb_lock;
|
||||
void *sdiodev;
|
||||
|
||||
struct list_head cmds;
|
||||
|
||||
int (*queue)(struct rwnx_cmd_mgr *, struct rwnx_cmd *);
|
||||
int (*llind)(struct rwnx_cmd_mgr *, struct rwnx_cmd *);
|
||||
int (*msgind)(struct rwnx_cmd_mgr *, struct rwnx_cmd_e2amsg *, msg_cb_fct);
|
||||
void (*print)(struct rwnx_cmd_mgr *);
|
||||
void (*drain)(struct rwnx_cmd_mgr *);
|
||||
|
||||
struct work_struct cmdWork;
|
||||
struct workqueue_struct *cmd_wq;
|
||||
};
|
||||
|
||||
void rwnx_cmd_mgr_init(struct rwnx_cmd_mgr *cmd_mgr);
|
||||
void rwnx_cmd_mgr_deinit(struct rwnx_cmd_mgr *cmd_mgr);
|
||||
int cmd_mgr_queue_force_defer(struct rwnx_cmd_mgr *cmd_mgr, struct rwnx_cmd *cmd);
|
||||
void rwnx_set_cmd_tx(void *dev, struct lmac_msg *msg, uint len);
|
||||
|
||||
enum {
|
||||
TASK_NONE = (u8) -1,
|
||||
|
||||
// MAC Management task.
|
||||
TASK_MM = 0,
|
||||
// DEBUG task
|
||||
TASK_DBG,
|
||||
/// SCAN task
|
||||
TASK_SCAN,
|
||||
/// TDLS task
|
||||
TASK_TDLS,
|
||||
/// SCANU task
|
||||
TASK_SCANU,
|
||||
/// ME task
|
||||
TASK_ME,
|
||||
/// SM task
|
||||
TASK_SM,
|
||||
/// APM task
|
||||
TASK_APM,
|
||||
/// BAM task
|
||||
TASK_BAM,
|
||||
/// MESH task
|
||||
TASK_MESH,
|
||||
/// RXU task
|
||||
TASK_RXU,
|
||||
// This is used to define the last task that is running on the EMB processor
|
||||
TASK_LAST_EMB = TASK_RXU,
|
||||
|
||||
// nX API task
|
||||
TASK_API,
|
||||
TASK_MAX,
|
||||
};
|
||||
|
||||
#define LMAC_FIRST_MSG(task) ((lmac_msg_id_t)((task) << 10))
|
||||
#define DRV_TASK_ID 100
|
||||
#define MSG_I(msg) ((msg) & ((1<<10)-1))
|
||||
#define MSG_T(msg) ((lmac_task_id_t)((msg) >> 10))
|
||||
|
||||
enum dbg_msg_tag {
|
||||
/// Memory read request
|
||||
DBG_MEM_READ_REQ = LMAC_FIRST_MSG(TASK_DBG),
|
||||
/// Memory read confirm
|
||||
DBG_MEM_READ_CFM,
|
||||
/// Memory write request
|
||||
DBG_MEM_WRITE_REQ,
|
||||
/// Memory write confirm
|
||||
DBG_MEM_WRITE_CFM,
|
||||
/// Module filter request
|
||||
DBG_SET_MOD_FILTER_REQ,
|
||||
/// Module filter confirm
|
||||
DBG_SET_MOD_FILTER_CFM,
|
||||
/// Severity filter request
|
||||
DBG_SET_SEV_FILTER_REQ,
|
||||
/// Severity filter confirm
|
||||
DBG_SET_SEV_FILTER_CFM,
|
||||
/// LMAC/MAC HW fatal error indication
|
||||
DBG_ERROR_IND,
|
||||
/// Request to get system statistics
|
||||
DBG_GET_SYS_STAT_REQ,
|
||||
/// COnfirmation of system statistics
|
||||
DBG_GET_SYS_STAT_CFM,
|
||||
/// Memory block write request
|
||||
DBG_MEM_BLOCK_WRITE_REQ,
|
||||
/// Memory block write confirm
|
||||
DBG_MEM_BLOCK_WRITE_CFM,
|
||||
/// Start app request
|
||||
DBG_START_APP_REQ,
|
||||
/// Start app confirm
|
||||
DBG_START_APP_CFM,
|
||||
/// Start npc request
|
||||
DBG_START_NPC_REQ,
|
||||
/// Start npc confirm
|
||||
DBG_START_NPC_CFM,
|
||||
/// Memory mask write request
|
||||
DBG_MEM_MASK_WRITE_REQ,
|
||||
/// Memory mask write confirm
|
||||
DBG_MEM_MASK_WRITE_CFM,
|
||||
|
||||
DBG_RFTEST_CMD_REQ,
|
||||
DBG_RFTEST_CMD_CFM,
|
||||
DBG_BINDING_REQ,
|
||||
DBG_BINDING_CFM,
|
||||
DBG_BINDING_IND,
|
||||
|
||||
DBG_CUSTOM_MSG_REQ,
|
||||
DBG_CUSTOM_MSG_CFM,
|
||||
DBG_CUSTOM_MSG_IND,
|
||||
|
||||
DBG_GPIO_WRITE_REQ,
|
||||
DBG_GPIO_WRITE_CFM,
|
||||
|
||||
|
||||
/// Max number of Debug messages
|
||||
DBG_MAX,
|
||||
};
|
||||
|
||||
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
|
||||
#define FW_M2D_OTA_NAME "m2d_ota.bin"
|
||||
#else
|
||||
#define FW_M2D_OTA_NAME "m2d_ota_lzma.bin"
|
||||
#endif
|
||||
|
||||
enum {
|
||||
HOST_START_APP_AUTO = 1,
|
||||
HOST_START_APP_CUSTOM,
|
||||
HOST_START_APP_FNCALL = 4,
|
||||
HOST_START_APP_DUMMY = 5,
|
||||
};
|
||||
|
||||
|
||||
struct dbg_mem_block_write_req {
|
||||
u32 memaddr;
|
||||
u32 memsize;
|
||||
u32 memdata[1024 / sizeof(u32)];
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_BLOCK_WRITE_CFM message.
|
||||
struct dbg_mem_block_write_cfm {
|
||||
u32 wstatus;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_WRITE_REQ message.
|
||||
struct dbg_mem_write_req {
|
||||
u32 memaddr;
|
||||
u32 memdata;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_WRITE_CFM message.
|
||||
struct dbg_mem_write_cfm {
|
||||
u32 memaddr;
|
||||
u32 memdata;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_READ_REQ message.
|
||||
struct dbg_mem_read_req {
|
||||
u32 memaddr;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_READ_CFM message.
|
||||
struct dbg_mem_read_cfm {
|
||||
u32 memaddr;
|
||||
u32 memdata;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_REQ message.
|
||||
struct dbg_mem_mask_write_req {
|
||||
u32 memaddr;
|
||||
u32 memmask;
|
||||
u32 memdata;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_MEM_MASK_WRITE_CFM message.
|
||||
struct dbg_mem_mask_write_cfm {
|
||||
u32 memaddr;
|
||||
u32 memdata;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_START_APP_REQ message.
|
||||
struct dbg_start_app_req {
|
||||
u32 bootaddr;
|
||||
u32 boottype;
|
||||
};
|
||||
|
||||
/// Structure containing the parameters of the @ref DBG_START_APP_CFM message.
|
||||
struct dbg_start_app_cfm {
|
||||
u32 bootstatus;
|
||||
};
|
||||
|
||||
int aicwf_plat_patch_load_8800dc(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_plat_rftest_load_8800dc(struct aic_sdio_dev *sdiodev);
|
||||
#ifdef CONFIG_DPD
|
||||
int aicwf_misc_ram_valid_check_8800dc(struct aic_sdio_dev *sdiodev, int *valid_out);
|
||||
int aicwf_plat_calib_load_8800dc(struct aic_sdio_dev *sdiodev);
|
||||
#endif
|
||||
|
||||
int rwnx_load_firmware(u32 **fw_buf, const char *name, struct device *device);
|
||||
int aicwf_patch_table_load(struct aic_sdio_dev *rwnx_hw, char *filename);
|
||||
|
||||
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,
|
||||
u32 mem_size, u32 *mem_data);
|
||||
int rwnx_send_dbg_mem_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr, u32 mem_data);
|
||||
int rwnx_send_dbg_mem_mask_write_req(struct aic_sdio_dev *sdiodev, u32 mem_addr,
|
||||
u32 mem_mask, u32 mem_data);
|
||||
int rwnx_send_dbg_start_app_req(struct aic_sdio_dev *sdiodev, u32 boot_addr, u32 boot_type, struct dbg_start_app_cfm *start_app_cfm);
|
||||
|
||||
int rwnx_plat_bin_fw_upload_android(struct aic_sdio_dev *sdiodev, u32 fw_addr, const char *filename);
|
||||
|
||||
void rwnx_rx_handle_msg(struct aic_sdio_dev *sdiodev, struct ipc_e2a_msg *msg);
|
||||
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);
|
||||
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
|
||||
int is_file_exist(char* name);
|
||||
#endif
|
||||
int aicbsp_resv_mem_init(void);
|
||||
int aicbsp_resv_mem_deinit(void);
|
||||
|
||||
#define AICBSP_FW_PATH CONFIG_AIC_FW_PATH
|
||||
#define AICBSP_FW_PATH_MAX 200
|
||||
|
||||
#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
|
||||
#define RAM_8800DC_U01_ADID_ADDR 0x00101788
|
||||
#define RAM_8800DC_U02_ADID_ADDR 0x001017d8
|
||||
#define RAM_8800DC_FW_PATCH_ADDR 0x00184000
|
||||
#define FW_RESET_START_ADDR 0x40500128
|
||||
#define FW_RESET_START_VAL 0x40
|
||||
#define FW_ADID_FLAG_ADDR 0x40500150
|
||||
#define FW_ADID_FLAG_VAL 0x01
|
||||
#define FW_RAM_ADID_BASE_ADDR_8800D80 0x002017E0
|
||||
#define FW_RAM_PATCH_BASE_ADDR_8800D80 0x0020B2B0
|
||||
#define FW_RAM_ADID_BASE_ADDR_8800D80_U02 0x00201940
|
||||
#define FW_RAM_PATCH_BASE_ADDR_8800D80_U02 0x0020b43c
|
||||
|
||||
#define AICBT_PT_TAG "AICBT_PT_TAG"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Addresses within RWNX_ADDR_CPU
|
||||
*****************************************************************************/
|
||||
#define RAM_LMAC_FW_ADDR 0x00150000
|
||||
|
||||
#define ROM_FMAC_FW_ADDR 0x00010000
|
||||
#define ROM_FMAC_PATCH_ADDR 0x00180000
|
||||
|
||||
#define RWNX_MAC_CALIB_BASE_NAME_8800DC "fmacfw_calib_8800dc"
|
||||
#define RWNX_MAC_CALIB_NAME_8800DC_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_u02.bin"
|
||||
#define RWNX_MAC_CALIB_NAME_8800DC_H_U02 RWNX_MAC_CALIB_BASE_NAME_8800DC"_h_u02.bin"
|
||||
|
||||
#ifdef CONFIG_DPD
|
||||
#define ROM_FMAC_CALIB_ADDR 0x00130000
|
||||
#ifndef CONFIG_FORCE_DPD_CALIB
|
||||
#define FW_DPDRESULT_NAME_8800DC "aic_dpdresult_lite_8800dc.bin"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define RWNX_MAC_FW_RF_BASE_NAME_8800DC "lmacfw_rf_8800dc.bin"
|
||||
|
||||
#ifdef CONFIG_FOR_IPCOM
|
||||
#define RWNX_MAC_PATCH_BASE_NAME_8800DC "fmacfw_patch_8800dc_ipc"
|
||||
#define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin"
|
||||
#else
|
||||
#define RWNX_MAC_PATCH_BASE_NAME_8800DC "fmacfw_patch_8800dc"
|
||||
#define RWNX_MAC_PATCH_NAME2_8800DC RWNX_MAC_PATCH_BASE_NAME_8800DC".bin"
|
||||
#define RWNX_MAC_PATCH_NAME2_8800DC_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_u02.bin"
|
||||
#define RWNX_MAC_PATCH_NAME2_8800DC_H_U02 RWNX_MAC_PATCH_BASE_NAME_8800DC"_h_u02.bin"
|
||||
#endif
|
||||
|
||||
#define RWNX_MAC_PATCH_TABLE_NAME_8800DC "fmacfw_patch_tbl_8800dc"
|
||||
#define RWNX_MAC_PATCH_TABLE_8800DC RWNX_MAC_PATCH_TABLE_NAME_8800DC ".bin"
|
||||
#define RWNX_MAC_PATCH_TABLE_8800DC_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_u02.bin"
|
||||
#define RWNX_MAC_PATCH_TABLE_8800DC_H_U02 RWNX_MAC_PATCH_TABLE_NAME_8800DC "_h_u02.bin"
|
||||
|
||||
#define RWNX_MAC_RF_PATCH_BASE_NAME_8800DC "fmacfw_rf_patch_8800dc"
|
||||
#define RWNX_MAC_RF_PATCH_NAME_8800DC RWNX_MAC_RF_PATCH_BASE_NAME_8800DC".bin"
|
||||
#define FW_USERCONFIG_NAME_8800DC "aic_userconfig_8800dc.txt"
|
||||
|
||||
enum {
|
||||
FW_NORMAL_MODE = 0,
|
||||
FW_RFTEST_MODE = 1,
|
||||
FW_BLE_SCAN_WAKEUP_MODE = 2,
|
||||
FW_M2D_OTA_MODE = 3,
|
||||
FW_DPDCALIB_MODE = 4,
|
||||
FW_BLE_SCAN_AD_FILTER_MODE = 5,
|
||||
};
|
||||
|
||||
enum aicbt_patch_table_type {
|
||||
AICBT_PT_INF = 0x00,
|
||||
AICBT_PT_TRAP = 0x1,
|
||||
AICBT_PT_B4,
|
||||
AICBT_PT_BTMODE,
|
||||
AICBT_PT_PWRON,
|
||||
AICBT_PT_AF,
|
||||
AICBT_PT_VER,
|
||||
};
|
||||
|
||||
enum aicbt_btport_type {
|
||||
AICBT_BTPORT_NULL,
|
||||
AICBT_BTPORT_MB,
|
||||
AICBT_BTPORT_UART,
|
||||
};
|
||||
|
||||
/* btmode
|
||||
* used for force bt mode,if not AICBSP_MODE_NULL
|
||||
* efuse valid and vendor_info will be invalid, even has beed set valid
|
||||
*/
|
||||
enum aicbt_btmode_type {
|
||||
AICBT_BTMODE_BT_ONLY_SW = 0x0, // bt only mode with switch
|
||||
AICBT_BTMODE_BT_WIFI_COMBO, // wifi/bt combo mode
|
||||
AICBT_BTMODE_BT_ONLY, // bt only mode without switch
|
||||
AICBT_BTMODE_BT_ONLY_TEST, // bt only test mode
|
||||
AICBT_BTMODE_BT_WIFI_COMBO_TEST, // wifi/bt combo test mode
|
||||
AICBT_BTMODE_BT_ONLY_COANT, // bt only mode with no external switch
|
||||
AICBT_MODE_NULL = 0xFF, // invalid value
|
||||
};
|
||||
|
||||
/* uart_baud
|
||||
* used for config uart baud when btport set to uart,
|
||||
* otherwise meaningless
|
||||
*/
|
||||
enum aicbt_uart_baud_type {
|
||||
AICBT_UART_BAUD_115200 = 115200,
|
||||
AICBT_UART_BAUD_921600 = 921600,
|
||||
AICBT_UART_BAUD_1_5M = 1500000,
|
||||
AICBT_UART_BAUD_3_25M = 3250000,
|
||||
};
|
||||
|
||||
enum aicbt_uart_flowctrl_type {
|
||||
AICBT_UART_FLOWCTRL_DISABLE = 0x0, // uart without flow ctrl
|
||||
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_U01 = 1,
|
||||
CHIP_REV_U02 = 3,
|
||||
CHIP_REV_U03 = 7,
|
||||
CHIP_REV_U04 = 7,
|
||||
};
|
||||
|
||||
#define AIC_M2D_OTA_INFO_ADDR 0x88000020
|
||||
#define AIC_M2D_OTA_DATA_ADDR 0x88000040
|
||||
#if !defined(CONFIG_M2D_OTA_LZMA_SUPPORT)
|
||||
#define AIC_M2D_OTA_FLASH_ADDR 0x08004000
|
||||
#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0188)
|
||||
#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x018C)
|
||||
#else
|
||||
#define AIC_M2D_OTA_FLASH_ADDR 0x08005000
|
||||
#define AIC_M2D_OTA_CODE_START_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x1188)
|
||||
#define AIC_M2D_OTA_VER_ADDR (AIC_M2D_OTA_FLASH_ADDR + 0x0010)
|
||||
#endif
|
||||
///aic bt tx pwr lvl :lsb->msb: first byte, min pwr lvl; second byte, max pwr lvl;
|
||||
///pwr lvl:20(min), 30 , 40 , 50 , 60(max)
|
||||
#define AICBT_TXPWR_LVL 0x00006020
|
||||
#define AICBT_TXPWR_LVL_8800dc 0x00006f2f
|
||||
#define AICBT_TXPWR_LVL_8800d80 0x00006f2f
|
||||
|
||||
#define AICBSP_HWINFO_DEFAULT (-1)
|
||||
#define AICBSP_CPMODE_DEFAULT AICBSP_CPMODE_WORK
|
||||
#define AICBSP_FWLOG_EN_DEFAULT 0
|
||||
|
||||
#define AICBT_BTMODE_DEFAULT_8800d80 AICBT_BTMODE_BT_ONLY_COANT
|
||||
#define AICBT_BTMODE_DEFAULT AICBT_BTMODE_BT_ONLY_SW
|
||||
#define AICBT_BTPORT_DEFAULT AICBT_BTPORT_UART
|
||||
#define AICBT_UART_BAUD_DEFAULT AICBT_UART_BAUD_115200
|
||||
#define AICBT_UART_FC_DEFAULT AICBT_UART_FLOWCTRL_ENABLE
|
||||
#define AICBT_LPM_ENABLE_DEFAULT 0
|
||||
#define AICBT_TXPWR_LVL_DEFAULT AICBT_TXPWR_LVL
|
||||
#define AICBT_TXPWR_LVL_DEFAULT_8800dc AICBT_TXPWR_LVL_8800dc
|
||||
#define AICBT_TXPWR_LVL_DEFAULT_8800d80 AICBT_TXPWR_LVL_8800d80
|
||||
|
||||
|
||||
#define AIC_IRQ_WAKE_FLAG 0 // 0: rising edge, 1: falling edge
|
||||
#define FEATURE_SDIO_CLOCK 10000000 // 0: default, other: target clock rate
|
||||
#define FEATURE_SDIO_CLOCK_V3 50000000 // 0: default, other: target clock rate
|
||||
#define FEATURE_SDIO_PHASE 2 // 0: default, 2: 180°
|
||||
|
||||
struct aicbt_patch_table {
|
||||
char *name;
|
||||
uint32_t type;
|
||||
uint32_t *data;
|
||||
uint32_t len;
|
||||
struct aicbt_patch_table *next;
|
||||
};
|
||||
|
||||
struct aicbt_info_t {
|
||||
uint32_t btmode;
|
||||
uint32_t btport;
|
||||
uint32_t uart_baud;
|
||||
uint32_t uart_flowctrl;
|
||||
uint32_t lpm_enable;
|
||||
uint32_t txpwr_lvl;
|
||||
};
|
||||
|
||||
struct aicbt_patch_info_t {
|
||||
uint32_t info_len;
|
||||
uint32_t adid_addrinf;
|
||||
uint32_t addr_adid;
|
||||
uint32_t patch_addrinf;
|
||||
uint32_t addr_patch;
|
||||
uint32_t reset_addr;
|
||||
uint32_t reset_val;
|
||||
uint32_t adid_flag_addr;
|
||||
uint32_t adid_flag;
|
||||
};
|
||||
|
||||
struct aicbsp_firmware {
|
||||
const char *desc;
|
||||
const char *bt_adid;
|
||||
const char *bt_patch;
|
||||
const char *bt_table;
|
||||
const char *wl_fw;
|
||||
};
|
||||
|
||||
struct aicbsp_info_t {
|
||||
int hwinfo;
|
||||
int hwinfo_r;
|
||||
uint32_t cpmode;
|
||||
uint32_t chip_rev;
|
||||
bool fwlog_en;
|
||||
uint8_t irqf;
|
||||
};
|
||||
|
||||
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[];
|
||||
extern const struct aicbsp_firmware fw_8800dc_u01[];
|
||||
extern const struct aicbsp_firmware fw_8800dc_u02[];
|
||||
extern const struct aicbsp_firmware fw_8800dc_h_u02[];
|
||||
extern const struct aicbsp_firmware fw_8800d80_u01[];
|
||||
extern const struct aicbsp_firmware fw_8800d80_u02[];
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef __AIC_BSP_EXPORT_H
|
||||
#define __AIC_BSP_EXPORT_H
|
||||
|
||||
enum aicbsp_subsys {
|
||||
AIC_BLUETOOTH,
|
||||
AIC_WIFI,
|
||||
};
|
||||
|
||||
enum aicbsp_pwr_state {
|
||||
AIC_PWR_OFF,
|
||||
AIC_PWR_ON,
|
||||
};
|
||||
|
||||
enum skb_buff_id {
|
||||
AIC_RESV_MEM_TXDATA,
|
||||
};
|
||||
|
||||
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;
|
||||
uint8_t irqf;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DPD
|
||||
typedef struct {
|
||||
uint32_t bit_mask[3];
|
||||
uint32_t reserved;
|
||||
uint32_t dpd_high[96];
|
||||
uint32_t dpd_11b[96];
|
||||
uint32_t dpd_low[96];
|
||||
uint32_t idac_11b[48];
|
||||
uint32_t idac_high[48];
|
||||
uint32_t idac_low[48];
|
||||
uint32_t loft_res[18];
|
||||
uint32_t rx_iqim_res[16];
|
||||
} rf_misc_ram_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t bit_mask[4];
|
||||
uint32_t dpd_high[96];
|
||||
uint32_t loft_res[18];
|
||||
} rf_misc_ram_lite_t;
|
||||
|
||||
#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
||||
#define DPD_RESULT_SIZE_8800DC sizeof(rf_misc_ram_lite_t)
|
||||
|
||||
extern rf_misc_ram_lite_t dpd_res;
|
||||
#endif
|
||||
|
||||
int aicbsp_set_subsys(int, int);
|
||||
int aicbsp_get_feature(struct aicbsp_feature_t *feature, char *fw_path);
|
||||
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
|
||||
+379
@@ -0,0 +1,379 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "aic_bsp_driver.h"
|
||||
#include "rwnx_version_gen.h"
|
||||
#include "aicwf_txq_prealloc.h"
|
||||
|
||||
|
||||
#define DRV_DESCRIPTION "AIC BSP"
|
||||
#define DRV_COPYRIGHT "Copyright(c) 2015-2020 AICSemi"
|
||||
#define DRV_AUTHOR "AICSemi"
|
||||
#define DRV_VERS_MOD "1.0"
|
||||
|
||||
int aicwf_dbg_level_bsp = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE;
|
||||
|
||||
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",
|
||||
#ifdef CONFIG_MCU_MESSAGE
|
||||
.wl_fw = "fmacfw_8800m_custmsg.bin"
|
||||
#else
|
||||
.wl_fw = "fmacfw.bin"
|
||||
#endif
|
||||
},
|
||||
|
||||
[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 fw_8800dc_u01[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(sdio u01)",
|
||||
.bt_adid = "fw_adid_8800dc.bin",
|
||||
.bt_patch = "fw_patch_8800dc.bin",
|
||||
.bt_table = "fw_patch_table_8800dc.bin",
|
||||
.wl_fw = "fmacfw_8800dc.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(sdio u01)",
|
||||
.bt_adid = "fw_adid_8800dc.bin",
|
||||
.bt_patch = "fw_patch_8800dc.bin",
|
||||
.bt_table = "fw_patch_table_8800dc.bin",
|
||||
.wl_fw = "fmacfw_rf_8800dc.bin"
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
const struct aicbsp_firmware fw_8800dc_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(8800dc sdio u02)",
|
||||
.bt_adid = "fw_adid_8800dc_u02.bin",
|
||||
.bt_patch = "fw_patch_8800dc_u02.bin",
|
||||
.bt_table = "fw_patch_table_8800dc_u02.bin",
|
||||
.wl_fw = "fmacfw_patch_8800dc_u02.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(8800dc sdio u02)",
|
||||
.bt_adid = "fw_adid_8800dc_u02.bin",
|
||||
.bt_patch = "fw_patch_8800dc_u02.bin",
|
||||
.bt_table = "fw_patch_table_8800dc_u02.bin",
|
||||
.wl_fw = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin
|
||||
},
|
||||
};
|
||||
|
||||
const struct aicbsp_firmware fw_8800dc_h_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(8800dc_h sdio u02)",
|
||||
.bt_adid = "fw_adid_8800dc_u02h.bin",
|
||||
.bt_patch = "fw_patch_8800dc_u02h.bin",
|
||||
.bt_table = "fw_patch_table_8800dc_u02h.bin",
|
||||
.wl_fw = "fmacfw_patch_8800dc_h_u02.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(8800dc_h sdio u02)",
|
||||
.bt_adid = "fw_adid_8800dc_u02h.bin",
|
||||
.bt_patch = "fw_patch_8800dc_u02h.bin",
|
||||
.bt_table = "fw_patch_table_8800dc_u02h.bin",
|
||||
.wl_fw = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
const struct aicbsp_firmware fw_8800d80_u01[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(8800d80 sdio u01)",
|
||||
.bt_adid = "fw_adid_8800d80.bin",
|
||||
.bt_patch = "fw_patch_8800d80.bin",
|
||||
.bt_table = "fw_patch_table_8800d80.bin",
|
||||
.wl_fw = "fmacfw_8800d80.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(8800d80 sdio u01)",
|
||||
.bt_adid = "fw_adid_8800d80.bin",
|
||||
.bt_patch = "fw_patch_8800d80.bin",
|
||||
.bt_table = "fw_patch_table_8800d80.bin",
|
||||
.wl_fw = "lmacfw_rf_8800d80.bin"
|
||||
},
|
||||
};
|
||||
|
||||
const struct aicbsp_firmware fw_8800d80_u02[] = {
|
||||
[AICBSP_CPMODE_WORK] = {
|
||||
.desc = "normal work mode(8800d80 sdio u02)",
|
||||
.bt_adid = "fw_adid_8800d80_u02.bin",
|
||||
.bt_patch = "fw_patch_8800d80_u02.bin",
|
||||
.bt_table = "fw_patch_table_8800d80_u02.bin",
|
||||
.wl_fw = "fmacfw_8800d80_u02.bin"
|
||||
},
|
||||
|
||||
[AICBSP_CPMODE_TEST] = {
|
||||
.desc = "rf test mode(8800d80 sdio u02)",
|
||||
.bt_adid = "fw_adid_8800d80_u02.bin",
|
||||
.bt_patch = "fw_patch_8800d80_u02.bin",
|
||||
.bt_table = "fw_patch_table_8800d80_u02.bin",
|
||||
.wl_fw = "lmacfw_rf_8800d80_u02.bin"
|
||||
},
|
||||
};
|
||||
|
||||
struct aicbsp_info_t aicbsp_info = {
|
||||
.hwinfo_r = AICBSP_HWINFO_DEFAULT,
|
||||
.hwinfo = AICBSP_HWINFO_DEFAULT,
|
||||
.cpmode = AICBSP_CPMODE_DEFAULT,
|
||||
.fwlog_en = AICBSP_FWLOG_EN_DEFAULT,
|
||||
.irqf = AIC_IRQ_WAKE_FLAG,
|
||||
};
|
||||
|
||||
struct mutex aicbsp_power_lock;
|
||||
|
||||
static struct platform_driver aicbsp_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "aic_bsp",
|
||||
},
|
||||
//.probe = aicbsp_probe,
|
||||
//.remove = aicbsp_remove,
|
||||
};
|
||||
|
||||
static ssize_t cpmode_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
uint8_t i = 0;
|
||||
|
||||
count += sprintf(&buf[count], "Support mode value:\n");
|
||||
|
||||
for (i = 0; i < AICBSP_CPMODE_MAX; i++) {
|
||||
if (aicbsp_firmware_list[i].desc)
|
||||
count += sprintf(&buf[count], " %2d: %s\n", i, aicbsp_firmware_list[i].desc);
|
||||
}
|
||||
|
||||
count += sprintf(&buf[count], "Current: %d, firmware info:\n", aicbsp_info.cpmode);
|
||||
count += sprintf(&buf[count], " BT ADID : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid);
|
||||
count += sprintf(&buf[count], " BT PATCH: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch);
|
||||
count += sprintf(&buf[count], " BT TABLE: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
|
||||
count += sprintf(&buf[count], " WIFI FW : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw);
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t cpmode_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
unsigned long val;
|
||||
int err = kstrtoul(buf, 0, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (val >= AICBSP_CPMODE_MAX) {
|
||||
pr_err("mode value must less than %d\n", AICBSP_CPMODE_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
aicbsp_info.cpmode = val;
|
||||
printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t hwinfo_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
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");
|
||||
else
|
||||
count += sprintf(&buf[count], "0x%02X\n", aicbsp_info.chip_rev);
|
||||
|
||||
count += sprintf(&buf[count], "hwinfo read: ");
|
||||
if (aicbsp_info.hwinfo_r < 0)
|
||||
count += sprintf(&buf[count], "%d(not avalible), ", aicbsp_info.hwinfo_r);
|
||||
else
|
||||
count += sprintf(&buf[count], "0x%02X, ", aicbsp_info.hwinfo_r);
|
||||
|
||||
if (aicbsp_info.hwinfo < 0)
|
||||
count += sprintf(&buf[count], "set: %d(not avalible)\n", aicbsp_info.hwinfo);
|
||||
else
|
||||
count += sprintf(&buf[count], "set: 0x%02X\n", aicbsp_info.hwinfo);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t hwinfo_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
long val;
|
||||
int err = kstrtol(buf, 0, &val);
|
||||
|
||||
if (err) {
|
||||
pr_err("invalid input\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((val == -1) || (val >= 0 && val <= 0xFF)) {
|
||||
aicbsp_info.hwinfo = val;
|
||||
} else {
|
||||
pr_err("invalid values\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t fwdebug_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t count = 0;
|
||||
|
||||
count += sprintf(&buf[count], "fw log status: %s\n",
|
||||
aicbsp_info.fwlog_en ? "on" : "off");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t fwdebug_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
long val;
|
||||
int err = kstrtol(buf, 0, &val);
|
||||
|
||||
if (err) {
|
||||
pr_err("invalid input\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
if (val > 1 || val < 0) {
|
||||
pr_err("must be 0 or 1\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
aicbsp_info.fwlog_en = val;
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(cpmode, S_IRUGO | S_IWUSR,
|
||||
cpmode_show, cpmode_store);
|
||||
|
||||
static DEVICE_ATTR(hwinfo, S_IRUGO | S_IWUSR,
|
||||
hwinfo_show, hwinfo_store);
|
||||
|
||||
static DEVICE_ATTR(fwdebug, S_IRUGO | S_IWUSR,
|
||||
fwdebug_show, fwdebug_store);
|
||||
|
||||
static struct attribute *aicbsp_attributes[] = {
|
||||
&dev_attr_cpmode.attr,
|
||||
&dev_attr_hwinfo.attr,
|
||||
&dev_attr_fwdebug.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group aicbsp_attribute_group = {
|
||||
.name = "aicbsp_info",
|
||||
.attrs = aicbsp_attributes,
|
||||
};
|
||||
|
||||
int testmode = AICBSP_CPMODE_DEFAULT;
|
||||
int adap_test = 0;
|
||||
module_param(testmode, int, 0660);
|
||||
module_param(adap_test, int, 0660);
|
||||
|
||||
|
||||
static int __init aicbsp_init(void)
|
||||
{
|
||||
int ret;
|
||||
printk("%s\n", __func__);
|
||||
printk("RELEASE_DATE:%s\r\n", RELEASE_DATE);
|
||||
|
||||
aicbsp_info.cpmode = testmode;
|
||||
|
||||
aicbsp_resv_mem_init();
|
||||
ret = platform_driver_register(&aicbsp_driver);
|
||||
if (ret) {
|
||||
pr_err("register platform driver failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
aicbsp_pdev = platform_device_alloc("aic-bsp", -1);
|
||||
ret = platform_device_add(aicbsp_pdev);
|
||||
if (ret) {
|
||||
pr_err("register platform device failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
|
||||
if (ret) {
|
||||
pr_err("register sysfs create group failed!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
mutex_init(&aicbsp_power_lock);
|
||||
#ifdef CONFIG_PLATFORM_ROCKCHIP
|
||||
aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void aicbsp_sdio_exit(void);
|
||||
extern struct aic_sdio_dev *aicbsp_sdiodev;
|
||||
|
||||
static void __exit aicbsp_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_PLATFORM_ROCKCHIP
|
||||
if(aicbsp_sdiodev){
|
||||
aicbsp_sdio_exit();
|
||||
}
|
||||
#endif
|
||||
sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
|
||||
platform_device_del(aicbsp_pdev);
|
||||
platform_driver_unregister(&aicbsp_driver);
|
||||
mutex_destroy(&aicbsp_power_lock);
|
||||
aicbsp_resv_mem_deinit();
|
||||
#ifdef CONFIG_PREALLOC_TXQ
|
||||
aicwf_prealloc_txq_free();
|
||||
#endif
|
||||
printk("%s\n", __func__);
|
||||
}
|
||||
|
||||
module_init(aicbsp_init);
|
||||
module_exit(aicbsp_exit);
|
||||
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERS_MOD);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
|
||||
MODULE_LICENSE("GPL");
|
||||
+1993
File diff suppressed because it is too large
Load Diff
+147
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* aicwf_sdio.h
|
||||
*
|
||||
* SDIO function declarations
|
||||
*
|
||||
* Copyright (C) AICSemi 2018-2020
|
||||
*/
|
||||
|
||||
#ifndef _AICWF_SDMMC_H_
|
||||
#define _AICWF_SDMMC_H_
|
||||
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
#define AICBSP_SDIO_NAME "aicbsp_sdio"
|
||||
#define SDIOWIFI_FUNC_BLOCKSIZE 512
|
||||
|
||||
#define SDIO_VENDOR_ID_AIC 0x8800
|
||||
#define SDIO_DEVICE_ID_AIC 0x0001
|
||||
#define SDIOWIFI_BYTEMODE_LEN_REG 0x02
|
||||
#define SDIOWIFI_INTR_CONFIG_REG 0x04
|
||||
#define SDIOWIFI_SLEEP_REG 0x05
|
||||
#define SDIOWIFI_WAKEUP_REG 0x09
|
||||
#define SDIOWIFI_FLOW_CTRL_REG 0x0A
|
||||
#define SDIOWIFI_REGISTER_BLOCK 0x0B
|
||||
#define SDIOWIFI_BYTEMODE_ENABLE_REG 0x11
|
||||
#define SDIOWIFI_BLOCK_CNT_REG 0x12
|
||||
#define SDIOWIFI_FLOWCTRL_MASK_REG 0x7F
|
||||
#define SDIOWIFI_WR_FIFO_ADDR 0x07
|
||||
#define SDIOWIFI_RD_FIFO_ADDR 0x08
|
||||
|
||||
#define SDIOWIFI_INTR_ENABLE_REG_V3 0x00
|
||||
#define SDIOWIFI_INTR_PENDING_REG_V3 0x01
|
||||
#define SDIOWIFI_INTR_TO_DEVICE_REG_V3 0x02
|
||||
#define SDIOWIFI_FLOW_CTRL_Q1_REG_V3 0x03
|
||||
#define SDIOWIFI_MISC_INT_STATUS_REG_V3 0x04
|
||||
#define SDIOWIFI_BYTEMODE_LEN_REG_V3 0x05
|
||||
#define SDIOWIFI_BYTEMODE_LEN_MSB_REG_V3 0x06
|
||||
#define SDIOWIFI_BYTEMODE_ENABLE_REG_V3 0x07
|
||||
#define SDIOWIFI_MISC_CTRL_REG_V3 0x08
|
||||
#define SDIOWIFI_FLOW_CTRL_Q2_REG_V3 0x09
|
||||
#define SDIOWIFI_CLK_TEST_RESULT_REG_V3 0x0A
|
||||
#define SDIOWIFI_RD_FIFO_ADDR_V3 0x0F
|
||||
#define SDIOWIFI_WR_FIFO_ADDR_V3 0x10
|
||||
|
||||
#define SDIOCLK_FREE_RUNNING_BIT (1 << 6)
|
||||
|
||||
#define SDIOWIFI_PWR_CTRL_INTERVAL 30
|
||||
#define FLOW_CTRL_RETRY_COUNT 50
|
||||
#define BUFFER_SIZE 1536
|
||||
#define TAIL_LEN 4
|
||||
#define TXQLEN (2048*4)
|
||||
|
||||
#define SDIO_SLEEP_ST 0
|
||||
#define SDIO_ACTIVE_ST 1
|
||||
|
||||
typedef enum {
|
||||
SDIO_TYPE_DATA = 0X00,
|
||||
SDIO_TYPE_CFG = 0X10,
|
||||
SDIO_TYPE_CFG_CMD_RSP = 0X11,
|
||||
SDIO_TYPE_CFG_DATA_CFM = 0X12
|
||||
} sdio_type;
|
||||
|
||||
enum AICWF_IC{
|
||||
PRODUCT_ID_AIC8801 = 0,
|
||||
PRODUCT_ID_AIC8800DC,
|
||||
PRODUCT_ID_AIC8800DW,
|
||||
PRODUCT_ID_AIC8800D80
|
||||
};
|
||||
|
||||
struct aic_sdio_reg {
|
||||
u8 bytemode_len_reg;
|
||||
u8 intr_config_reg;
|
||||
u8 sleep_reg;
|
||||
u8 wakeup_reg;
|
||||
u8 flow_ctrl_reg;
|
||||
u8 flowctrl_mask_reg;
|
||||
u8 register_block;
|
||||
u8 bytemode_enable_reg;
|
||||
u8 block_cnt_reg;
|
||||
u8 misc_int_status_reg;
|
||||
u8 rd_fifo_addr;
|
||||
u8 wr_fifo_addr;
|
||||
};
|
||||
|
||||
struct aic_sdio_dev {
|
||||
struct rwnx_cmd_mgr cmd_mgr;
|
||||
struct sdio_func *func;
|
||||
struct sdio_func *func_msg;
|
||||
struct device *dev;
|
||||
struct aicwf_bus *bus_if;
|
||||
|
||||
struct aicwf_rx_priv *rx_priv;
|
||||
struct aicwf_tx_priv *tx_priv;
|
||||
u32 state;
|
||||
|
||||
#if defined(CONFIG_SDIO_PWRCTRL)
|
||||
//for sdio pwr ctrl
|
||||
struct timer_list timer;
|
||||
uint active_duration;
|
||||
struct completion pwrctrl_trgg;
|
||||
struct task_struct *pwrctl_tsk;
|
||||
spinlock_t pwrctl_lock;
|
||||
struct semaphore pwrctl_wakeup_sema;
|
||||
#endif
|
||||
u16 chipid;
|
||||
struct aic_sdio_reg sdio_reg;
|
||||
void (*sdio_hal_irqhandler) (struct sdio_func *func);
|
||||
};
|
||||
|
||||
void *aicbsp_get_drvdata(void *args);
|
||||
int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
|
||||
void aicwf_sdio_hal_irqhandler(struct sdio_func *func);
|
||||
void aicwf_sdio_hal_irqhandler_func2(struct sdio_func *func);
|
||||
#if defined(CONFIG_SDIO_PWRCTRL)
|
||||
void aicwf_sdio_pwrctl_timer(struct aic_sdio_dev *sdiodev, uint duration);
|
||||
int aicwf_sdio_pwr_stctl(struct aic_sdio_dev *sdiodev, uint target);
|
||||
#endif
|
||||
void aicwf_sdio_reg_init(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdio_func_init(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdiov3_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_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size, u8 msg);
|
||||
int aicwf_sdio_send_pkt(struct aic_sdio_dev *sdiodev, u8 *buf, uint count);
|
||||
void *aicwf_sdio_bus_init(struct aic_sdio_dev *sdiodev);
|
||||
void aicwf_sdio_release(struct aic_sdio_dev *sdiodev);
|
||||
void aicbsp_sdio_exit(void);
|
||||
int aicbsp_sdio_init(void);
|
||||
void aicbsp_sdio_release(struct aic_sdio_dev *sdiodev);
|
||||
int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt);
|
||||
int aicwf_sdio_bustx_thread(void *data);
|
||||
int aicwf_sdio_busrx_thread(void *data);
|
||||
int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt);
|
||||
int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv);
|
||||
void aicwf_sdio_aggr_send(struct aicwf_tx_priv *tx_priv);
|
||||
void aicwf_sdio_aggrbuf_reset(struct aicwf_tx_priv *tx_priv);
|
||||
extern void aicwf_hostif_ready(void);
|
||||
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv);
|
||||
uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size);
|
||||
#endif /* AICWF_SDIO_SUPPORT */
|
||||
|
||||
#endif /*_AICWF_SDMMC_H_*/
|
||||
+463
@@ -0,0 +1,463 @@
|
||||
/**
|
||||
* aicwf_bus.c
|
||||
*
|
||||
* bus function declarations
|
||||
*
|
||||
* Copyright (C) AICSemi 2018-2020
|
||||
*/
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include "aicsdio_txrxif.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
int aicwf_bus_init(uint bus_hdrlen, struct device *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct aicwf_bus *bus_if;
|
||||
|
||||
if (!dev) {
|
||||
txrx_err("device not found\n");
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
memset(bus_if->cmd_buf, '\0', CMD_BUF_MAX);
|
||||
|
||||
init_completion(&bus_if->bustx_trgg);
|
||||
init_completion(&bus_if->busrx_trgg);
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
bus_if->bustx_thread = kthread_run(aicwf_sdio_bustx_thread, (void *)bus_if, "aicwf_bustx_thread");
|
||||
bus_if->busrx_thread = kthread_run(aicwf_sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread");
|
||||
#endif
|
||||
|
||||
if (IS_ERR(bus_if->bustx_thread)) {
|
||||
bus_if->bustx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (IS_ERR(bus_if->busrx_thread)) {
|
||||
bus_if->busrx_thread = NULL;
|
||||
txrx_err("aicwf_bustx_thread run fail\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return ret;
|
||||
fail:
|
||||
aicwf_bus_deinit(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void aicwf_bus_deinit(struct device *dev)
|
||||
{
|
||||
struct aicwf_bus *bus_if;
|
||||
struct aic_sdio_dev *sdiodev;
|
||||
|
||||
if (!dev) {
|
||||
txrx_err("device not found\n");
|
||||
return;
|
||||
}
|
||||
sdio_dbg("%s", __func__);
|
||||
bus_if = aicbsp_get_drvdata(dev);
|
||||
aicwf_bus_stop(bus_if);
|
||||
|
||||
sdiodev = bus_if->bus_priv.sdio;
|
||||
|
||||
if (bus_if->cmd_buf) {
|
||||
kfree(bus_if->cmd_buf);
|
||||
bus_if->cmd_buf = NULL;
|
||||
}
|
||||
|
||||
if (bus_if->bustx_thread) {
|
||||
complete_all(&bus_if->bustx_trgg);
|
||||
kthread_stop(bus_if->bustx_thread);
|
||||
bus_if->bustx_thread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void aicwf_frame_tx(void *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
|
||||
aicwf_bus_txdata(sdiodev->bus_if, skb);
|
||||
}
|
||||
|
||||
struct aicwf_tx_priv *aicwf_tx_init(void *arg)
|
||||
{
|
||||
struct aicwf_tx_priv *tx_priv;
|
||||
|
||||
tx_priv = kzalloc(sizeof(struct aicwf_tx_priv), GFP_KERNEL);
|
||||
if (!tx_priv)
|
||||
return NULL;
|
||||
|
||||
tx_priv->sdiodev = (struct aic_sdio_dev *)arg;
|
||||
|
||||
atomic_set(&tx_priv->aggr_count, 0);
|
||||
tx_priv->aggr_buf = dev_alloc_skb(MAX_AGGR_TXPKT_LEN);
|
||||
if (!tx_priv->aggr_buf) {
|
||||
txrx_err("Alloc bus->txdata_buf failed!\n");
|
||||
kfree(tx_priv);
|
||||
return NULL;
|
||||
}
|
||||
tx_priv->head = tx_priv->aggr_buf->data;
|
||||
tx_priv->tail = tx_priv->aggr_buf->data;
|
||||
|
||||
return tx_priv;
|
||||
}
|
||||
|
||||
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv)
|
||||
{
|
||||
if (tx_priv && tx_priv->aggr_buf)
|
||||
dev_kfree_skb(tx_priv->aggr_buf);
|
||||
|
||||
kfree(tx_priv);
|
||||
//tx_priv = NULL;
|
||||
}
|
||||
|
||||
static bool aicwf_another_ptk(struct sk_buff *skb)
|
||||
{
|
||||
u8 *data;
|
||||
u16 aggr_len = 0;
|
||||
|
||||
if (skb->data == NULL || skb->len == 0) {
|
||||
return false;
|
||||
}
|
||||
data = skb->data;
|
||||
aggr_len = (*skb->data | (*(skb->data + 1) << 8));
|
||||
if (aggr_len == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long flags = 0;
|
||||
struct sk_buff *skb = NULL;
|
||||
u16 pkt_len = 0;
|
||||
struct sk_buff *skb_inblock = NULL;
|
||||
u16 aggr_len = 0, adjust_len = 0;
|
||||
u8 *data = NULL;
|
||||
|
||||
while (1) {
|
||||
spin_lock_irqsave(&rx_priv->rxqlock, flags);
|
||||
if (aicwf_is_framequeue_empty(&rx_priv->rxq)) {
|
||||
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
|
||||
break;
|
||||
}
|
||||
skb = aicwf_frame_dequeue(&rx_priv->rxq);
|
||||
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
|
||||
if (skb == NULL) {
|
||||
txrx_err("skb_error\r\n");
|
||||
break;
|
||||
}
|
||||
while (aicwf_another_ptk(skb)) {
|
||||
data = skb->data;
|
||||
pkt_len = (*skb->data | (*(skb->data + 1) << 8));
|
||||
|
||||
if ((skb->data[2] & SDIO_TYPE_CFG) != SDIO_TYPE_CFG) { // type : data
|
||||
aggr_len = pkt_len + RX_HWHRD_LEN;
|
||||
|
||||
if (aggr_len & (RX_ALIGNMENT - 1))
|
||||
adjust_len = roundup(aggr_len, RX_ALIGNMENT);
|
||||
else
|
||||
adjust_len = aggr_len;
|
||||
|
||||
skb_inblock = __dev_alloc_skb(aggr_len + CCMP_OR_WEP_INFO, GFP_KERNEL);//8 is for ccmp mic or wep icv
|
||||
if (skb_inblock == NULL) {
|
||||
txrx_err("no more space!\n");
|
||||
aicwf_dev_skb_free(skb);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
skb_put(skb_inblock, aggr_len);
|
||||
memcpy(skb_inblock->data, data, aggr_len);
|
||||
#if 0
|
||||
rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv);
|
||||
#endif
|
||||
skb_pull(skb, adjust_len);
|
||||
} else { // type : config
|
||||
aggr_len = pkt_len;
|
||||
|
||||
if (aggr_len & (RX_ALIGNMENT - 1))
|
||||
adjust_len = roundup(aggr_len, RX_ALIGNMENT);
|
||||
else
|
||||
adjust_len = aggr_len;
|
||||
|
||||
skb_inblock = __dev_alloc_skb(aggr_len+4, GFP_KERNEL);
|
||||
if (skb_inblock == NULL) {
|
||||
txrx_err("no more space!\n");
|
||||
aicwf_dev_skb_free(skb);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
skb_put(skb_inblock, aggr_len+4);
|
||||
memcpy(skb_inblock->data, data, aggr_len+4);
|
||||
if ((*(skb_inblock->data + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP)
|
||||
rwnx_rx_handle_msg(rx_priv->sdiodev, (struct ipc_e2a_msg *)(skb_inblock->data + 4));
|
||||
#if 0
|
||||
if ((*(skb_inblock->data + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM)
|
||||
aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(skb_inblock->data + 4));
|
||||
#endif
|
||||
skb_pull(skb, adjust_len+4);
|
||||
}
|
||||
}
|
||||
|
||||
/* skb_inblock no used currently, just free it! */
|
||||
dev_kfree_skb(skb_inblock);
|
||||
dev_kfree_skb(skb);
|
||||
atomic_dec(&rx_priv->rx_cnt);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_SDIO_PWRCTRL)
|
||||
aicwf_sdio_pwr_stctl(rx_priv->sdiodev, SDIO_ACTIVE_ST);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct recv_msdu *aicwf_rxframe_queue_init(struct list_head *q, int qsize)
|
||||
{
|
||||
int i;
|
||||
struct recv_msdu *req, *reqs;
|
||||
|
||||
reqs = vmalloc(qsize*sizeof(struct recv_msdu));
|
||||
if (reqs == NULL)
|
||||
return NULL;
|
||||
|
||||
req = reqs;
|
||||
for (i = 0; i < qsize; i++) {
|
||||
INIT_LIST_HEAD(&req->rxframe_list);
|
||||
list_add(&req->rxframe_list, q);
|
||||
req->len = 0;
|
||||
req++;
|
||||
}
|
||||
|
||||
return reqs;
|
||||
}
|
||||
|
||||
struct aicwf_rx_priv *aicwf_rx_init(void *arg)
|
||||
{
|
||||
struct aicwf_rx_priv *rx_priv;
|
||||
rx_priv = kzalloc(sizeof(struct aicwf_rx_priv), GFP_KERNEL);
|
||||
if (!rx_priv)
|
||||
return NULL;
|
||||
|
||||
rx_priv->sdiodev = (struct aic_sdio_dev *)arg;
|
||||
aicwf_frame_queue_init(&rx_priv->rxq, 1, MAX_RXQLEN);
|
||||
spin_lock_init(&rx_priv->rxqlock);
|
||||
atomic_set(&rx_priv->rx_cnt, 0);
|
||||
|
||||
INIT_LIST_HEAD(&rx_priv->rxframes_freequeue);
|
||||
spin_lock_init(&rx_priv->freeq_lock);
|
||||
rx_priv->recv_frames = aicwf_rxframe_queue_init(&rx_priv->rxframes_freequeue, MAX_REORD_RXFRAME);
|
||||
if (!rx_priv->recv_frames) {
|
||||
txrx_err("no enough buffer for free recv frame queue!\n");
|
||||
kfree(rx_priv);
|
||||
return NULL;
|
||||
}
|
||||
spin_lock_init(&rx_priv->stas_reord_lock);
|
||||
INIT_LIST_HEAD(&rx_priv->stas_reord_list);
|
||||
|
||||
return rx_priv;
|
||||
}
|
||||
|
||||
|
||||
static void aicwf_recvframe_queue_deinit(struct list_head *q)
|
||||
{
|
||||
struct recv_msdu *req, *next;
|
||||
|
||||
list_for_each_entry_safe(req, next, q, rxframe_list) {
|
||||
list_del_init(&req->rxframe_list);
|
||||
}
|
||||
}
|
||||
|
||||
void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv)
|
||||
{
|
||||
if (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;
|
||||
}
|
||||
|
||||
aicwf_frame_queue_flush(&rx_priv->rxq);
|
||||
aicwf_recvframe_queue_deinit(&rx_priv->rxframes_freequeue);
|
||||
if (rx_priv->recv_frames)
|
||||
vfree(rx_priv->recv_frames);
|
||||
|
||||
kfree(rx_priv);
|
||||
//rx_priv = NULL;
|
||||
}
|
||||
|
||||
bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt)
|
||||
{
|
||||
return aicwf_frame_enq(dev, q, pkt, 0);
|
||||
}
|
||||
|
||||
|
||||
void aicwf_dev_skb_free(struct sk_buff *skb)
|
||||
{
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
|
||||
static struct sk_buff *aicwf_frame_queue_penq(struct frame_queue *pq, int prio, struct sk_buff *p)
|
||||
{
|
||||
struct sk_buff_head *q;
|
||||
|
||||
if (pq->queuelist[prio].qlen >= pq->qmax)
|
||||
return NULL;
|
||||
|
||||
q = &pq->queuelist[prio];
|
||||
__skb_queue_tail(q, p);
|
||||
pq->qcnt++;
|
||||
if (pq->hi_prio < prio)
|
||||
pq->hi_prio = (u16)prio;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void aicwf_frame_queue_flush(struct frame_queue *pq)
|
||||
{
|
||||
int prio;
|
||||
struct sk_buff_head *q;
|
||||
struct sk_buff *p, *next;
|
||||
|
||||
for (prio = 0; prio < pq->num_prio; prio++) {
|
||||
q = &pq->queuelist[prio];
|
||||
skb_queue_walk_safe(q, p, next) {
|
||||
skb_unlink(p, q);
|
||||
aicwf_dev_skb_free(p);
|
||||
pq->qcnt--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len)
|
||||
{
|
||||
int prio;
|
||||
|
||||
memset(pq, 0, offsetof(struct frame_queue, queuelist) + (sizeof(struct sk_buff_head) * num_prio));
|
||||
pq->num_prio = (u16)num_prio;
|
||||
pq->qmax = (u16)max_len;
|
||||
|
||||
for (prio = 0; prio < num_prio; prio++) {
|
||||
skb_queue_head_init(&pq->queuelist[prio]);
|
||||
}
|
||||
}
|
||||
|
||||
struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out)
|
||||
{
|
||||
int prio;
|
||||
|
||||
if (pq->qcnt == 0)
|
||||
return NULL;
|
||||
|
||||
for (prio = 0; prio < pq->hi_prio; prio++)
|
||||
if (!skb_queue_empty(&pq->queuelist[prio]))
|
||||
break;
|
||||
|
||||
if (prio_out)
|
||||
*prio_out = prio;
|
||||
|
||||
return skb_peek_tail(&pq->queuelist[prio]);
|
||||
}
|
||||
|
||||
bool aicwf_is_framequeue_empty(struct frame_queue *pq)
|
||||
{
|
||||
int prio, len = 0;
|
||||
|
||||
for (prio = 0; prio <= pq->hi_prio; prio++)
|
||||
len += pq->queuelist[prio].qlen;
|
||||
|
||||
if (len > 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq)
|
||||
{
|
||||
struct sk_buff_head *q;
|
||||
struct sk_buff *p;
|
||||
int prio;
|
||||
|
||||
if (pq->qcnt == 0)
|
||||
return NULL;
|
||||
|
||||
while ((prio = pq->hi_prio) > 0 && skb_queue_empty(&pq->queuelist[prio]))
|
||||
pq->hi_prio--;
|
||||
|
||||
q = &pq->queuelist[prio];
|
||||
p = __skb_dequeue(q);
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
pq->qcnt--;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* aicwf_txrxif.h
|
||||
*
|
||||
* bus function declarations
|
||||
*
|
||||
* Copyright (C) AICSemi 2018-2020
|
||||
*/
|
||||
|
||||
#ifndef _AICWF_TXRXIF_H_
|
||||
#define _AICWF_TXRXIF_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/sched.h>
|
||||
#include "aicsdio.h"
|
||||
|
||||
#define CMD_BUF_MAX 1536
|
||||
#define TXPKT_BLOCKSIZE 512
|
||||
#define MAX_AGGR_TXPKT_LEN (1536*4)
|
||||
#define CMD_TX_TIMEOUT 5000
|
||||
#define TX_ALIGNMENT 4
|
||||
|
||||
#define RX_HWHRD_LEN 60 //58->60 word allined
|
||||
#define CCMP_OR_WEP_INFO 8
|
||||
#define MAX_RXQLEN 2000
|
||||
#define RX_ALIGNMENT 4
|
||||
|
||||
#define DEBUG_ERROR_LEVEL 0
|
||||
#define DEBUG_DEBUG_LEVEL 1
|
||||
#define DEBUG_INFO_LEVEL 2
|
||||
|
||||
#define DBG_LEVEL DEBUG_DEBUG_LEVEL
|
||||
|
||||
#define txrx_err(fmt, ...) pr_err("aicbsp: txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||
#define sdio_err(fmt, ...) pr_err("aicbsp: sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||
#define usb_err(fmt, ...) pr_err("aicbsp: usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||
#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL
|
||||
#define sdio_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
||||
#define usb_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define sdio_dbg(fmt, ...)
|
||||
#define usb_dbg(fmt, ...)
|
||||
#endif
|
||||
#if DBG_LEVEL >= DEBUG_INFO_LEVEL
|
||||
#define sdio_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
||||
#define usb_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define sdio_info(fmt, ...)
|
||||
#define usb_info(fmt, ...)
|
||||
#endif
|
||||
|
||||
enum aicwf_bus_state {
|
||||
BUS_DOWN_ST,
|
||||
BUS_UP_ST
|
||||
};
|
||||
|
||||
struct aicwf_bus_ops {
|
||||
int (*start) (struct device *dev);
|
||||
void (*stop) (struct device *dev);
|
||||
int (*txdata) (struct device *dev, struct sk_buff *skb);
|
||||
int (*txmsg) (struct device *dev, u8 *msg, uint len);
|
||||
};
|
||||
|
||||
struct frame_queue {
|
||||
u16 num_prio;
|
||||
u16 hi_prio;
|
||||
u16 qmax; /* max number of queued frames */
|
||||
u16 qcnt;
|
||||
struct sk_buff_head queuelist[8];
|
||||
};
|
||||
|
||||
struct aicwf_bus {
|
||||
union {
|
||||
struct aic_sdio_dev *sdio;
|
||||
struct aic_usb_dev *usb;
|
||||
} bus_priv;
|
||||
struct device *dev;
|
||||
struct aicwf_bus_ops *ops;
|
||||
enum aicwf_bus_state state;
|
||||
u8 *cmd_buf;
|
||||
struct completion bustx_trgg;
|
||||
struct completion busrx_trgg;
|
||||
struct task_struct *bustx_thread;
|
||||
struct task_struct *busrx_thread;
|
||||
};
|
||||
|
||||
struct aicwf_tx_priv {
|
||||
#ifdef AICWF_SDIO_SUPPORT
|
||||
struct aic_sdio_dev *sdiodev;
|
||||
int fw_avail_bufcnt;
|
||||
//for cmd tx
|
||||
u8 *cmd_buf;
|
||||
uint cmd_len;
|
||||
bool cmd_txstate;
|
||||
bool cmd_tx_succ;
|
||||
struct semaphore cmd_txsema;
|
||||
wait_queue_head_t cmd_txdone_wait;
|
||||
//for data tx
|
||||
atomic_t tx_pktcnt;
|
||||
|
||||
struct frame_queue txq;
|
||||
spinlock_t txqlock;
|
||||
struct semaphore txctl_sema;
|
||||
#endif
|
||||
#ifdef AICWF_USB_SUPPORT
|
||||
struct aic_usb_dev *usbdev;
|
||||
#endif
|
||||
struct sk_buff *aggr_buf;
|
||||
atomic_t aggr_count;
|
||||
u8 *head;
|
||||
u8 *tail;
|
||||
};
|
||||
|
||||
|
||||
#define MAX_REORD_RXFRAME 250
|
||||
#define REORDER_UPDATE_TIME 50
|
||||
#define AICWF_REORDER_WINSIZE 64
|
||||
#define SN_LESS(a, b) (((a-b)&0x800) != 0)
|
||||
#define SN_EQUAL(a, b) (a == b)
|
||||
|
||||
struct reord_ctrl {
|
||||
struct aicwf_rx_priv *rx_priv;
|
||||
u8 enable;
|
||||
u16 ind_sn;
|
||||
u8 wsize_b;
|
||||
spinlock_t reord_list_lock;
|
||||
struct list_head reord_list;
|
||||
struct timer_list reord_timer;
|
||||
struct work_struct reord_timer_work;
|
||||
};
|
||||
|
||||
struct reord_ctrl_info {
|
||||
u8 mac_addr[6];
|
||||
struct reord_ctrl preorder_ctrl[8];
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct recv_msdu {
|
||||
struct sk_buff *pkt;
|
||||
u8 tid;
|
||||
u16 seq_num;
|
||||
uint len;
|
||||
u8 *rx_data;
|
||||
//for pending rx reorder list
|
||||
struct list_head reord_pending_list;
|
||||
//for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue
|
||||
struct list_head rxframe_list;
|
||||
struct reord_ctrl *preorder_ctrl;
|
||||
};
|
||||
|
||||
struct aicwf_rx_priv {
|
||||
struct aic_sdio_dev *sdiodev;
|
||||
void *rwnx_vif;
|
||||
atomic_t rx_cnt;
|
||||
u32 data_len;
|
||||
spinlock_t rxqlock;
|
||||
struct frame_queue rxq;
|
||||
|
||||
spinlock_t freeq_lock;
|
||||
struct list_head rxframes_freequeue;
|
||||
struct list_head stas_reord_list;
|
||||
spinlock_t stas_reord_lock;
|
||||
struct recv_msdu *recv_frames;
|
||||
};
|
||||
|
||||
static inline int aicwf_bus_start(struct aicwf_bus *bus)
|
||||
{
|
||||
return bus->ops->start(bus->dev);
|
||||
}
|
||||
|
||||
static inline void aicwf_bus_stop(struct aicwf_bus *bus)
|
||||
{
|
||||
bus->ops->stop(bus->dev);
|
||||
}
|
||||
|
||||
static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb)
|
||||
{
|
||||
return bus->ops->txdata(bus->dev, skb);
|
||||
}
|
||||
|
||||
static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len)
|
||||
{
|
||||
return bus->ops->txmsg(bus->dev, msg, len);
|
||||
}
|
||||
|
||||
static inline void aicwf_sched_timeout(u32 millisec)
|
||||
{
|
||||
ulong timeout = 0, expires = 0;
|
||||
expires = jiffies + msecs_to_jiffies(millisec);
|
||||
timeout = millisec;
|
||||
|
||||
while (timeout) {
|
||||
timeout = schedule_timeout(timeout);
|
||||
if (time_after(jiffies, expires))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int aicwf_bus_init(uint bus_hdrlen, struct device *dev);
|
||||
void aicwf_bus_deinit(struct device *dev);
|
||||
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv);
|
||||
void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv);
|
||||
struct aicwf_tx_priv *aicwf_tx_init(void *arg);
|
||||
struct aicwf_rx_priv *aicwf_rx_init(void *arg);
|
||||
void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len);
|
||||
void aicwf_frame_queue_flush(struct frame_queue *pq);
|
||||
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio);
|
||||
bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt);
|
||||
bool aicwf_is_framequeue_empty(struct frame_queue *pq);
|
||||
void aicwf_frame_tx(void *dev, struct sk_buff *skb);
|
||||
void aicwf_dev_skb_free(struct sk_buff *skb);
|
||||
struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq);
|
||||
struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out);
|
||||
|
||||
#endif /* _AICWF_TXRXIF_H_ */
|
||||
+16138
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
int aicwf_get_firmware_array(char* fw_name, u32 **fw_buf);
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#include <linux/slab.h>
|
||||
#include "aicsdio_txrxif.h"
|
||||
#include "aic_bsp_driver.h"
|
||||
|
||||
struct prealloc_txq{
|
||||
int prealloced;
|
||||
void *txq;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct prealloc_txq prealloc_txq;
|
||||
#define MAX_TXQ_SIZE 100 * 1024
|
||||
|
||||
void *aicwf_prealloc_txq_alloc(size_t size)
|
||||
{
|
||||
|
||||
BUG_ON(size > MAX_TXQ_SIZE);
|
||||
|
||||
//check prealloc_txq.size
|
||||
if((int)prealloc_txq.size != (int)size)
|
||||
{
|
||||
AICWFDBG(LOGINFO, "%s size is diff will to be kzalloc \r\n", __func__);
|
||||
|
||||
if(prealloc_txq.txq != NULL)
|
||||
{
|
||||
AICWFDBG(LOGINFO, "%s txq to kfree \r\n", __func__);
|
||||
kfree(prealloc_txq.txq);
|
||||
prealloc_txq.txq = NULL;
|
||||
}
|
||||
|
||||
prealloc_txq.size = size;
|
||||
prealloc_txq.prealloced = 0;
|
||||
}
|
||||
|
||||
//check prealloc or not
|
||||
if(!prealloc_txq.prealloced)
|
||||
{
|
||||
prealloc_txq.txq = kzalloc(size, GFP_KERNEL);
|
||||
if(!prealloc_txq.txq){
|
||||
AICWFDBG(LOGERROR, "%s txq kzalloc fail \r\n", __func__);
|
||||
}else{
|
||||
AICWFDBG(LOGINFO, "%s txq kzalloc successful \r\n", __func__);
|
||||
prealloc_txq.prealloced = 1;
|
||||
}
|
||||
}else{
|
||||
AICWFDBG(LOGINFO, "%s txq not need to kzalloc \r\n", __func__);
|
||||
}
|
||||
|
||||
return prealloc_txq.txq;
|
||||
}
|
||||
void aicwf_prealloc_txq_free(void)
|
||||
{
|
||||
if(prealloc_txq.txq != NULL)
|
||||
{
|
||||
AICWFDBG(LOGINFO, "%s txq to kfree \r\n", __func__);
|
||||
kfree(prealloc_txq.txq);
|
||||
prealloc_txq.txq = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(aicwf_prealloc_txq_alloc);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
|
||||
void aicwf_prealloc_txq_free(void);
|
||||
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
#include <linux/memory.h>
|
||||
#include "md5.h"
|
||||
|
||||
unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
void MD5Init(MD5_CTX *context)
|
||||
{
|
||||
context->count[0] = 0;
|
||||
context->count[1] = 0;
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
|
||||
{
|
||||
unsigned int i = 0,index = 0,partlen = 0;
|
||||
index = (context->count[0] >> 3) & 0x3F;
|
||||
partlen = 64 - index;
|
||||
context->count[0] += inputlen << 3;
|
||||
if(context->count[0] < (inputlen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += inputlen >> 29;
|
||||
|
||||
if(inputlen >= partlen)
|
||||
{
|
||||
memcpy(&context->buffer[index],input,partlen);
|
||||
MD5Transform(context->state,context->buffer);
|
||||
for(i = partlen;i+64 <= inputlen;i+=64)
|
||||
MD5Transform(context->state,&input[i]);
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
memcpy(&context->buffer[index],&input[i],inputlen-i);
|
||||
}
|
||||
void MD5Final(MD5_CTX *context,unsigned char digest[16])
|
||||
{
|
||||
unsigned int index = 0,padlen = 0;
|
||||
unsigned char bits[8];
|
||||
index = (context->count[0] >> 3) & 0x3F;
|
||||
padlen = (index < 56)?(56-index):(120-index);
|
||||
MD5Encode(bits,context->count,8);
|
||||
MD5Update(context,PADDING,padlen);
|
||||
MD5Update(context,bits,8);
|
||||
MD5Encode(digest,context->state,16);
|
||||
}
|
||||
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
|
||||
{
|
||||
unsigned int i = 0,j = 0;
|
||||
while(j < len)
|
||||
{
|
||||
output[j] = input[i] & 0xFF;
|
||||
output[j+1] = (input[i] >> 8) & 0xFF;
|
||||
output[j+2] = (input[i] >> 16) & 0xFF;
|
||||
output[j+3] = (input[i] >> 24) & 0xFF;
|
||||
i++;
|
||||
j+=4;
|
||||
}
|
||||
}
|
||||
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
|
||||
{
|
||||
unsigned int i = 0,j = 0;
|
||||
while(j < len)
|
||||
{
|
||||
output[i] = (input[j]) |
|
||||
(input[j+1] << 8) |
|
||||
(input[j+2] << 16) |
|
||||
(input[j+3] << 24);
|
||||
i++;
|
||||
j+=4;
|
||||
}
|
||||
}
|
||||
void MD5Transform(unsigned int state[4],unsigned char block[64])
|
||||
{
|
||||
unsigned int a = state[0];
|
||||
unsigned int b = state[1];
|
||||
unsigned int c = state[2];
|
||||
unsigned int d = state[3];
|
||||
unsigned int x[64];
|
||||
MD5Decode(x,block,64);
|
||||
FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int count[2];
|
||||
unsigned int state[4];
|
||||
unsigned char buffer[64];
|
||||
}MD5_CTX;
|
||||
|
||||
|
||||
#define F(x,y,z) ((x & y) | (~x & z))
|
||||
#define G(x,y,z) ((x & z) | (y & ~z))
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y ^ (x | ~z))
|
||||
#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
|
||||
#define FF(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += F(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define GG(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += G(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define HH(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += H(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
#define II(a,b,c,d,x,s,ac) \
|
||||
{ \
|
||||
a += I(b,c,d) + x + ac; \
|
||||
a = ROTATE_LEFT(a,s); \
|
||||
a += b; \
|
||||
}
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
|
||||
void MD5Final(MD5_CTX *context,unsigned char digest[16]);
|
||||
void MD5Transform(unsigned int state[4],unsigned char block[64]);
|
||||
void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
|
||||
void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#define RWNX_VERS_REV "241c091M (master)"
|
||||
#define RWNX_VERS_MOD "6.4.3.0"
|
||||
#define RWNX_VERS_BANNER "rwnx v6.4.3.0 - - 241c091M (master)"
|
||||
#define RELEASE_DATE "2023_1219_3cf85031"
|
||||
Reference in New Issue
Block a user