update:add luckfox-pico Ultra support

This commit is contained in:
luckfox-eng29 2024-03-16 17:03:10 +08:00 committed by luckfox-eng33
parent 1e160dee55
commit d3153ac97e
234 changed files with 89019 additions and 2435 deletions

View File

@ -81,6 +81,9 @@ ota -pack update_ota.tar
save -save images, patches, commands used to debug
check -check the environment of building
info -see the current board building information
buildrootconfig -config buildroot and save defconfig"
kernelconfig -config kernel and save defconfig"
```
#### Select the referenced board configuration
```shell
@ -96,55 +99,87 @@ BoardConfig-"启动介质"-"系统版本"-"硬件版本"-"应用场景".mk
BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
0. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1103_Luckfox_Pico-IPC.mk
0. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk
boot medium(启动介质): EMMC
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Ultra
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
1. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk
boot medium(启动介质): EMMC
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Ultra_W
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
2. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
1. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): EMMC
3. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_A
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
2. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): EMMC
4. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
5. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Max
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
6. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
3. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): EMMC
7. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_A
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
4. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): EMMC
8. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
5. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): EMMC
9. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1106_Luckfox_Pico_Pro_Max
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
6. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Mini_B-IPC.mk
10. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Mini_B-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_B
@ -152,7 +187,7 @@ BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
----------------------------------------------------------------
7. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
11. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
@ -160,7 +195,7 @@ BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
----------------------------------------------------------------
8. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
12. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Pro_Max
@ -168,9 +203,19 @@ BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
Which would you like? [0]:
```
#### Custom Board-level WIFI Configuration
* Navigate to the board-level configuration directory
```shell
cd {SDK_PATH}/project/cfg/BoardConfig_IPC/
```
* Open the corresponding board-level configuration file
* Modify the parameters LF_WIFI_PASSWD and LF_WIFI_SSID
```shell
export LF_WIFI_SSID="Your wifi ssid"
export LF_WIFI_PSK="Your wifi password"
```
#### One-click Automatic Compilation
```shell
./build.sh lunch # Select the reference board configuration
@ -239,7 +284,17 @@ The path of the generated files:
```
output/image
```
#### Kernel Config
```shell
./build.sh kernelconfig
```
Open the menuconfig interface for the kernel.
#### Buildroot Config
```shell
./build.sh buildrootconfig
```
Open the menuconfig interface for buildroot.
* Note: This is only applicable when selecting buildroot as the root file system.
## Notices
When copying the source code package under Windows, the executable file under Linux may become a non-executable file, or the soft link fails and cannot be compiled and used.

View File

@ -76,6 +76,9 @@ ota -pack update_ota.tar
save -save images, patches, commands used to debug
check -check the environment of building
info -see the current board building information
buildrootconfig -config buildroot and save defconfig"
kernelconfig -config kernel and save defconfig"
```
#### 选择参考的板级配置
```shell
@ -91,55 +94,87 @@ BoardConfig-"启动介质"-"系统版本"-"硬件版本"-"应用场景".mk
BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
0. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1103_Luckfox_Pico-IPC.mk
0. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra-IPC.mk
boot medium(启动介质): EMMC
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Ultra
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
1. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1106_Luckfox_Pico_Ultra_W-IPC.mk
boot medium(启动介质): EMMC
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Ultra_W
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
2. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
1. BoardConfig_IPC/BoardConfig-EMMC-Buildroot-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): EMMC
3. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_A
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
2. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): EMMC
4. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
5. BoardConfig_IPC/BoardConfig-SD_CARD-Buildroot-RV1106_Luckfox_Pico_Max-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Max
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
6. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
3. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): EMMC
7. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico_Mini_A-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_A
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
4. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): EMMC
8. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
5. BoardConfig_IPC/BoardConfig-EMMC-Ubuntu-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): EMMC
9. BoardConfig_IPC/BoardConfig-SD_CARD-Ubuntu-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): SD_CARD
system version(系统版本): Ubuntu
hardware version(硬件版本): RV1106_Luckfox_Pico_Pro_Max
applicaton(应用场景): IPC
----------------------------------------------------------------
----------------------------------------------------------------
6. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Mini_B-IPC.mk
10. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Mini_B-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Mini_B
@ -147,7 +182,7 @@ BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
----------------------------------------------------------------
7. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
11. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1103_Luckfox_Pico_Plus-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1103_Luckfox_Pico_Plus
@ -155,7 +190,7 @@ BoardConfig-"boot medium"-"system version"-"hardware version"-"applicaton".mk
----------------------------------------------------------------
----------------------------------------------------------------
8. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
12. BoardConfig_IPC/BoardConfig-SPI_NAND-Buildroot-RV1106_Luckfox_Pico_Pro_Max-IPC.mk
boot medium(启动介质): SPI_NAND
system version(系统版本): Buildroot
hardware version(硬件版本): RV1106_Luckfox_Pico_Pro_Max
@ -166,7 +201,17 @@ Which would you like? [0]:
```
输入对应的序号选择对应的参考板级。
#### 自定义板级 WIFI 配置
* 进入板级配置存放目录
```shell
cd {SDK_PATH}/project/cfg/BoardConfig_IPC/
```
* 打开对应的板级配置文件
* 修改参数LF_WIFI_PASSWD和LF_WIFI_SSID
```shell
export LF_WIFI_SSID="Your wifi ssid"
export LF_WIFI_PSK="Your wifi password"
```
#### 一键自动编译
* 编译busybox/buildroot
```shell
@ -227,8 +272,17 @@ output/out/media_out
```
生成文件的存放目录:
output/image
#### 内核设置
``` shell
./build.sh kernelconfig
```
打开 kernel 的 menuconfig 界面
#### buildroot 设置
```shell
./build.sh buildrootconfig
```
打开 buildroot 的 menuconfig 界面
* 注:仅在选择 buildroot 作为 rootfs 时才能正常运行
### 注意事项
在windows下复制源码包时linux下的可执行文件可能变为非可执行文件或者软连接失效导致无法编译使用。

View File

@ -1,4 +1,11 @@
# Updatelog
## V1.3 Updatelog
1. Added support for Luckfox-pico Ultra / Luckfox-pico Ultra W
2. Restructured the board support files, adding Wifi settings to the Luckfox-pico Ultra W board support files.
3. Added `kernelconfig` and `buildrootconfig` commands to `./build.sh`, enabling direct access to menuconfig. After configuration, modifications are automatically applied by replacing the corresponding defconfig file
4. Created symbolic links for device tree files, kernel configuration files, and buildroot configuration files, facilitating direct editing within the `config` folder
5. Implemented automatic switching of buildroot sources, enabling selection of repository sources based on network conditions before building the buildroot root file system
6. Partial bug fixes
## V1.2 Updatelog
1. Added compatibility for Ubuntu system
2. Restored support for busybox, allowing users to choose between busybox, buildroot, and Ubuntu according to their needs
@ -27,4 +34,4 @@
4. ADB
1. Automatically starts on boot
## V1.0 Updatelog
* Initial upload, default system is busybox
* Initial upload, default system is busybox

7
UPDATE_LOG_CN.md Normal file → Executable file
View File

@ -1,4 +1,11 @@
# 更新日志
## V1.3 更新日志
1. 添加对Luckfox-pico Ultra/Luckfox-pico Ultra W的支持
2. 修改了板级支持文件的结构在Luckfox-pico Ultra W板级支持文件添加了Wifi设置
3. 添加了./build.sh的kernelconfig和buildrootconfig命令可以直接打开menuconfig设置后自动修改替换对应的defconfig文件
4. 添加了设备树文件内核设置文件和buildroot设置文件的软链接可以直接再conifg文件夹下进行编辑
5. 添加了buildroot源自动切换功能可以在构建buildroot根文件系统前根据网络情况选择仓库源
6. 部分bug修复
## V1.2 更新日志
1. 添加ubuntu系统兼容
2. 恢复对busybox的支持使用户可以根据自身需求busybox、buildroot和ubuntu

View File

@ -1 +1 @@
project/build.sh
./project/build.sh

View File

@ -125,6 +125,39 @@ int PICO_GPIOS[] = {
};
int PICO_ULTRA_GPIOS[] = {
LUCKFOX_PICO_ULTRA_GPIO0,
LUCKFOX_PICO_ULTRA_GPIO1,
LUCKFOX_PICO_ULTRA_GPIO2,
LUCKFOX_PICO_ULTRA_GPIO3,
LUCKFOX_PICO_ULTRA_GPIO4,
LUCKFOX_PICO_ULTRA_GPIO5,
LUCKFOX_PICO_ULTRA_GPIO6,
LUCKFOX_PICO_ULTRA_GPIO7,
LUCKFOX_PICO_ULTRA_GPIO8,
LUCKFOX_PICO_ULTRA_GPIO9,
LUCKFOX_PICO_ULTRA_GPIO10,
LUCKFOX_PICO_ULTRA_GPIO11,
LUCKFOX_PICO_ULTRA_GPIO12,
LUCKFOX_PICO_ULTRA_GPIO13,
LUCKFOX_PICO_ULTRA_GPIO14,
LUCKFOX_PICO_ULTRA_GPIO15,
LUCKFOX_PICO_ULTRA_GPIO16,
LUCKFOX_PICO_ULTRA_GPIO17,
LUCKFOX_PICO_ULTRA_GPIO18,
LUCKFOX_PICO_ULTRA_GPIO19,
LUCKFOX_PICO_ULTRA_GPIO20,
LUCKFOX_PICO_ULTRA_GPIO21,
LUCKFOX_PICO_ULTRA_GPIO22,
LUCKFOX_PICO_ULTRA_GPIO23,
LUCKFOX_PICO_ULTRA_GPIO24,
LUCKFOX_PICO_ULTRA_GPIO25,
LUCKFOX_PICO_ULTRA_GPIO26,
LUCKFOX_PICO_ULTRA_GPIO27,
LUCKFOX_PICO_ULTRA_GPIO28,
LUCKFOX_PICO_ULTRA_GPIO29,
};
void Delay_ms(uint32_t xms)
{
uint32_t i;
@ -158,12 +191,13 @@ int main(int argc, char *argv[])
printf("* 1. LUCKFOX PICO\r\n");
printf("* 2. LUCKFOX PICO PLUS\r\n");
printf("* 3. LUCKFOX PICO MAX\r\n");
printf("* 4. LUCKFOX PICO MAX\r\n");
printf("-----------------------------\r\n");
while (1)
{
printf("Which would you like? :");
input_char = getchar();
if (input_char >= '1' && input_char <= '3')
if (input_char >= '1' && input_char <= '4')
{
break;
}
@ -187,6 +221,12 @@ int main(int argc, char *argv[])
GPIO_END_PIN = 22;
TEST_PIN = PICO_MAX_GPIOS;
}
else if (input_char == '4')
{
GPIO_BEGIN_PIN = 2;
GPIO_END_PIN = 27;
TEST_PIN = PICO_ULTRA_GPIOS;
}
else
{
exit(0);
@ -230,14 +270,12 @@ int main(int argc, char *argv[])
for (int x = GPIO_BEGIN_PIN; x <= GPIO_END_PIN; x++)
{
luckfox_gpio_set_value(TEST_PIN[x], 1);
printf("GP%d : GPIO%d set \r\n", x, TEST_PIN[x]);
Delay_ms(delay_time);
}
for (int x = GPIO_BEGIN_PIN; x <= GPIO_END_PIN; x++)
{
luckfox_gpio_set_value(TEST_PIN[x], 0);
printf("GP%d : GPIO%d reset \r\n", x, TEST_PIN[x]);
Delay_ms(delay_time);

View File

@ -36,6 +36,7 @@
int PICO_PWMS[] = {0, 1, 10, 11};
int PICO_MAX_PWMS[] = {5, 6, 10, 11};
int PICO_ULTRA_PWMS[] = {5, 6, 10, 11};
int *TEST_PWM;
void Delay_ms(uint32_t xms)
@ -71,6 +72,7 @@ int main(int argc, char *argv[])
printf("Please select your test borad\r\n");
printf("* 1. LUCKFOX PICO & LUCKFOX PICO PLUS\r\n");
printf("* 2. LUCKFOX PICO MAX\r\n");
printf("* 3. LUCKFOX PICO ULTRA\r\n");
printf("-----------------------------\r\n");
while (1)
{
@ -90,6 +92,10 @@ int main(int argc, char *argv[])
{
TEST_PWM = PICO_MAX_PWMS;
}
else if (input_char == '3')
{
TEST_PWM = PICO_ULTRA_PWMS;
}
else
{
exit(0);

View File

@ -187,6 +187,51 @@
#define LUCKFOX_PICO_GPIO17 GPIO(GPIO4,PB0)
#define LUCKFOX_PICO_GPIO16 GPIO(GPIO4,PB1)
/**********************************************/
#define LUCKFOX_PICO_ULTRA_GPIO0 GPIO(GPIO1,PB2)
#define LUCKFOX_PICO_ULTRA_GPIO1 GPIO(GPIO1,PB3)
#define LUCKFOX_PICO_ULTRA_GPIO2 GPIO(GPIO1,PA0)
#define LUCKFOX_PICO_ULTRA_GPIO3 GPIO(GPIO1,PA1)
#define LUCKFOX_PICO_ULTRA_GPIO4 GPIO(GPIO1,PB0)
#define LUCKFOX_PICO_ULTRA_GPIO5 GPIO(GPIO1,PB1)
#define LUCKFOX_PICO_ULTRA_GPIO6 GPIO(GPIO1,PD0)
#define LUCKFOX_PICO_ULTRA_GPIO7 GPIO(GPIO1,PD1)
#define LUCKFOX_PICO_ULTRA_GPIO8 GPIO(GPIO1,PC2)
#define LUCKFOX_PICO_ULTRA_GPIO9 GPIO(GPIO1,PC3)
#define LUCKFOX_PICO_ULTRA_GPIO10 GPIO(GPIO1,PC1)
/**********************************************/
#define LUCKFOX_PICO_ULTRA_GPIO16 GPIO(GPIO1,PC6)
#define LUCKFOX_PICO_ULTRA_GPIO15 GPIO(GPIO2,PA7)
#define LUCKFOX_PICO_ULTRA_GPIO14 GPIO(GPIO2,PA6)
#define LUCKFOX_PICO_ULTRA_GPIO13 GPIO(GPIO1,PD3)
#define LUCKFOX_PICO_ULTRA_GPIO12 GPIO(GPIO1,PC0)
#define LUCKFOX_PICO_ULTRA_GPIO11 GPIO(GPIO1,PD2)
/**********************************************/
#define LUCKFOX_PICO_ULTRA_GPIO19 GPIO(GPIO1,PC7)
#define LUCKFOX_PICO_ULTRA_GPIO18 GPIO(GPIO2,PB0)
#define LUCKFOX_PICO_ULTRA_GPIO17 GPIO(GPIO2,PB1)
/**********************************************/
#define LUCKFOX_PICO_ULTRA_GPIO27 GPIO(GPIO1,PC4)
#define LUCKFOX_PICO_ULTRA_GPIO26 GPIO(GPIO1,PC5)
#define LUCKFOX_PICO_ULTRA_GPIO25 GPIO(GPIO2,PA1)
#define LUCKFOX_PICO_ULTRA_GPIO24 GPIO(GPIO2,PA0)
#define LUCKFOX_PICO_ULTRA_GPIO23 GPIO(GPIO2,PA5)
#define LUCKFOX_PICO_ULTRA_GPIO22 GPIO(GPIO2,PA4)
#define LUCKFOX_PICO_ULTRA_GPIO21 GPIO(GPIO2,PA2)
#define LUCKFOX_PICO_ULTRA_GPIO20 GPIO(GPIO2,PA3)
/**********************************************/
#define LUCKFOX_PICO_ULTRA_GPIO28 GPIO(GPIO4,PC0)
#define LUCKFOX_PICO_ULTRA_GPIO29 GPIO(GPIO4,PC1)
enum gpio_direction
{
GPIO_DIRECTION_OUTPUT = 0,

View File

@ -15,9 +15,16 @@ include $(MAKEFILE_DIR)/Makefile.param
################################################################################
app_src := $(wildcard ./*/Makefile)
app_src += $(component_src)
app_src := $(dir $(app_src))
app_src := $(filter-out ./component/,$(app_src))
component_src := $(wildcard ./component/*/Makefile)
all_src += $(component_src)
all_src += $(app_src)
all_src := $(dir $(all_src))
ifeq ($(RK_ENABLE_FASTBOOT),y)
pkg-build := fastboot-build
endif
@ -32,7 +39,8 @@ fastboot-build:
distclean: clean
clean:
$(foreach target,$(app_src),make clean -C $(target)||exit -1;)
$(foreach target,$(all_src),make clean -C $(target)||exit -1;)
@rm -rf ./wifi_app/wpa_supplicant.conf
@rm -rf $(RK_APP_OUTPUT)
info:

Binary file not shown.

View File

@ -1,9 +0,0 @@
ctrl_interface=/var/run/wpa_supplicant
ap_scan=1
update_config=1
network={
ssid="SSID"
psk="PASSWORD"
key_mgmt=WPA-PSK
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1106
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"
# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_w_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
#export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y
# enable rockchip wifi
#export RK_ENABLE_WIFI=y

View File

@ -0,0 +1,116 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1106
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"
# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra-w.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_w_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Kernel defconfig fragment
export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
#export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y
# enable rockchip wifi
export RK_ENABLE_WIFI=y
export RK_ENABLE_WIFI_CHIP=AIC8800DC
# config wifi ssid and passwd
export LF_WIFI_SSID="Your wifi ssid"
export LF_WIFI_PSK="Your wifi password"

View File

@ -0,0 +1,111 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1106
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"
# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra-w.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES github/gitee
export LF_SUBMODULES_BY=gitee
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
# export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y
# enable rockchip wifi
#export RK_ENABLE_WIFI=y

View File

@ -0,0 +1,120 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1106
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"
# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-ultra-w.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES github/gitee
export LF_SUBMODULES_BY=gitee
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_w_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Kernel defconfig fragment
export RK_KERNEL_DEFCONFIG_FRAGMENT=rv1106-bt.config
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
# export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y
# enable rockchip wifi
export RK_ENABLE_WIFI=y
export RK_ENABLE_WIFI_CHIP=AIC8800DC
# config wifi ssid and passwd
export LF_WIFI_SSID="Your wifi ssid"
export LF_WIFI_PSK="Your wifi password"

View File

@ -20,8 +20,8 @@ export RK_KERNEL_DTS=rv1103g-luckfox-pico.dts
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,7 +58,7 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
@ -78,7 +78,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -20,8 +20,8 @@ export RK_KERNEL_DTS=rv1103g-luckfox-pico-mini-a.dts
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,7 +58,7 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
@ -78,7 +78,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -0,0 +1,105 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1103
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="24M"
# Kernel dts
export RK_KERNEL_DTS=rv1103g-luckfox-pico-plus.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs),-(media)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
# export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y

View File

@ -0,0 +1,105 @@
#!/bin/bash
#################################################
# Board Config
#################################################
# Target CHIP
export RK_CHIP=rv1106
# app config
export RK_APP_TYPE=RKIPC_RV1106
# Config CMA size in environment
export RK_BOOTARGS_CMA_SIZE="66M"
# Kernel dts
export RK_KERNEL_DTS=rv1106g-luckfox-pico-pro-max.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
# specify post.sh for delete/overlay files
# export RK_PRE_BUILD_OEM_SCRIPT=rv1103-spi_nor-post.sh
# config partition in environment
# RK_PARTITION_CMD_IN_ENV format:
# <partdef>[,<partdef>]
# <partdef> := <size>[@<offset>](part-name)
# Note:
# If the first partition offset is not 0x0, it must be added. Otherwise, it needn't adding.
export RK_PARTITION_CMD_IN_ENV="32K(env),512K@32K(idblock),256K(uboot),32M(boot),512M(oem),256M(userdata),6G(rootfs),-(media)"
# config partition's filesystem type (squashfs is readonly)
# emmc: squashfs/ext4
# nand: squashfs/ubifs
# spi nor: squashfs/jffs2
# RK_PARTITION_FS_TYPE_CFG format:
# AAAA:/BBBB/CCCC@ext4
# AAAA ----------> partition name
# /BBBB/CCCC ----> partition mount point
# ext4 ----------> partition filesystem type
export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/oem@ext4
# config filesystem compress (Just for squashfs or ubifs)
# squashfs: lz4/lzo/lzma/xz/gzip, default xz
# ubifs: lzo/zlib, default lzo
# export RK_SQUASHFS_COMP=xz
# export RK_UBIFS_COMP=lzo
#################################################
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=buildroot
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_defconfig
#################################################
# Defconfig
#################################################
# Target arch
export RK_ARCH=arm
# Target Toolchain Cross Compile
export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
#misc image
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
# Config sensor IQ files
# RK_CAMERA_SENSOR_IQFILES format:
# "iqfile1 iqfile2 iqfile3 ..."
# ./build.sh media and copy <SDK root dir>/output/out/media_out/isp_iqfiles/$RK_CAMERA_SENSOR_IQFILES
export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json"
#export RK_CAMERA_SENSOR_IQFILES="sc4336_OT01_40IRC_F16.json sc3336_CMK-OT2119-PC1_30IRC-F16.json sc530ai_CMK-OT2115-PC1_30IRC-F16.json"
# Config sensor lens CAC calibrattion bin files
export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
# export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y
# enable rockchip test
export RK_ENABLE_ROCKCHIP_TEST=y

View File

@ -20,8 +20,8 @@ export RK_KERNEL_DTS=rv1103g-luckfox-pico.dts
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,7 +58,7 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES : github/gitee
@ -81,7 +81,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -20,8 +20,8 @@ export RK_KERNEL_DTS=rv1103g-luckfox-pico-mini-a.dts
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,7 +58,7 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES : github/gitee
@ -81,7 +81,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -14,14 +14,14 @@ export RK_APP_TYPE=RKIPC_RV1103
export RK_BOOTARGS_CMA_SIZE="24M"
# Kernel dts
export RK_KERNEL_DTS=rv1103g-luckfox-pico-plus-sd.dts
export RK_KERNEL_DTS=rv1103g-luckfox-pico-plus.dts
#################################################
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,7 +58,7 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES : github/gitee
@ -81,7 +81,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -20,8 +20,8 @@ export RK_KERNEL_DTS=rv1106g-luckfox-pico-pro-max.dts
# BOOT_MEDIUM
#################################################
# Target boot medium: emmc/spi_nor/spi_nand
export RK_BOOT_MEDIUM=emmc
# Target boot medium: sd_card/spi_nor/spi_nand
export RK_BOOT_MEDIUM=sd_card
# Uboot defconfig fragment
export RK_UBOOT_DEFCONFIG_FRAGMENT=rk-emmc.config
@ -58,11 +58,11 @@ export RK_PARTITION_FS_TYPE_CFG=rootfs@IGNORE@ext4,userdata@/userdata@ext4,oem@/
# TARGET_ROOTFS
#################################################
# Target rootfs : ubuntu(only emmc)/buildroot/busybox
# Target rootfs : ubuntu(only sd_card)/buildroot/busybox
export LF_TARGET_ROOTFS=ubuntu
# SUBMODULES : github/gitee
export LF_SUBMODULES_BY=github
export LF_SUBMODULES_BY=gitee
# Buildroot defconfig
export RK_BUILDROOT_DEFCONFIG=luckfox_pico_defconfig
@ -81,7 +81,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -78,7 +78,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -78,7 +78,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig

View File

@ -78,7 +78,7 @@ export RK_TOOLCHAIN_CROSS=arm-rockchip830-linux-uclibcgnueabihf
export RK_MISC=wipe_all-misc.img
# Uboot defconfig
export RK_UBOOT_DEFCONFIG=rv1106_defconfig
export RK_UBOOT_DEFCONFIG=luckfox_rv1106_uboot_defconfig
# Kernel defconfig
export RK_KERNEL_DEFCONFIG=luckfox_rv1106_linux_defconfig
@ -95,7 +95,7 @@ export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16"
#export RK_CAMERA_SENSOR_CAC_BIN="CAC_sc4336_OT01_40IRC_F16 CAC_sc530ai_CMK-OT2115-PC1_30IRC-F16"
# build ipc web backend
# export RK_APP_IPCWEB_BACKEND=y
#export RK_APP_IPCWEB_BACKEND=y
# enable install app to oem partition
export RK_BUILD_APP_TO_OEM_PARTITION=y

View File

@ -35,6 +35,7 @@ ifeq ($(BUILDROOT_DEFCONFIG),)
BUILDROOT_DEFCONFIG := luckfox_pico_defconfig
endif
SYSDRV_ROOTFS_FS_TYPE ?= $(fs_type)
ifneq ($(RK_ROOTFS_FS_TPYE),)
SYSDRV_ROOTFS_FS_TYPE := $(RK_ROOTFS_FS_TPYE)
@ -99,6 +100,10 @@ ifneq ($(OUTPUT_SYSDRV_RAMDISK_DIR),)
SYSDRV_BUILD_RAMDISK_FLAG := YES
endif
ifeq ($(RK_BOOT_MEDIUM),emmc)
ENABLE_EMMC := YES
endif
################################################################################
## rootfs Select
################################################################################
@ -113,6 +118,8 @@ endif
ifneq ($(findstring $(TARGET_ROOTFS),custom),)
ROOTFS_BUILD_ENV :=
else ifneq ($(findstring $(TARGET_ROOTFS),alpine),)
ROOTFS_BUILD_ENV := alpine
else ifneq ($(findstring $(TARGET_ROOTFS),ubuntu),)
ROOTFS_BUILD_ENV := ubuntu
else ifneq ($(findstring $(TARGET_ROOTFS),buildroot),)
@ -176,6 +183,15 @@ KERNEL_CMDLINE_FRAGMENT += rootfstype=$(SYSDRV_ROOTFS_FS_TYPE) \
root=/dev/mmcblk0p$(ROOTFS_PART_NUM)
endif
ifeq ($(BOOT_MEDIUM), sd_card)
SYSDRV_ROOTFS_BUILD_TARGET := rootfs_ext4
ifeq ($(SYSDRV_ROOTFS_FS_TYPE),)
SYSDRV_ROOTFS_FS_TYPE := ext4
endif
KERNEL_CMDLINE_FRAGMENT += rootfstype=$(SYSDRV_ROOTFS_FS_TYPE) \
root=/dev/mmcblk1p$(ROOTFS_PART_NUM)
endif
ifeq ($(BOOT_MEDIUM), spi_nor)
SYSDRV_ROOTFS_BUILD_TARGET := rootfs_jffs2
ifeq ($(SYSDRV_ROOTFS_FS_TYPE),)
@ -283,11 +299,15 @@ SYSDRV_KERNEL_MOD_PATH:=$(SYSDRV_DIR)/out/kernel_drv_ko
SYSDRV_ROOTFS_OUT_IMAGE := $(SYSDRV_DIR_OUT_IMAGE)/rootfs_base.img
SYSDRV_UBOOT_ENV_CFG_FILE :=$(SYSDRV_DIR_OUT_IMAGE)/.env.txt
HCITOOL_TOOL_PATH :=$(SYSDRV_DIR)/tools/board/buildroot/hcitool_patch
MPV_PATCH_PATH :=$(SYSDRV_DIR)/tools/board/buildroot/mpv_patch
export SYSDRV_DIR_OUT_PC
export SYSDRV_DIR_OUT_BOARD
export SYSDRV_DIR_OUT_ROOTFS
export SYSDRV_KERNEL_MOD_PATH
################################################################################
## Check Configuraton
################################################################################
@ -389,11 +409,20 @@ uboot: prepare
$(SYSDRV_DIR_OUT_IMAGE)/$(DOWNLOAD_BIN))
uboot_clean:
rm -rf $(UBOOT_DIR)/fit
pushd $(UBOOT_DIR);$(MAKE) CROSS_COMPILE=$(CROSS_COMPILE) distclean >/dev/null;popd
##########################################################################################
# build kernel
##########################################################################################
kernel_menuconfig:
cp $(KERNEL_DIR)/arch/arm/configs/$(KERNEL_CFG) $(KERNEL_DIR)/.config
$(MAKE) -C $(KERNEL_DIR) ARCH=$(ARCH) menuconfig
$(MAKE) -C $(KERNEL_DIR) ARCH=$(ARCH) savedefconfig
kernel_savedefconfig:
cp $(KERNEL_DIR)/defconfig $(KERNEL_DIR)/arch/arm/configs/$(KERNEL_CFG)
kernel: prepare
@echo -e "$(C_GREEN) ==sysdrv== build kernel $(C_NORMAL)"
ifeq ($(RK_ENABLE_FASTBOOT), y)
@ -445,6 +474,8 @@ kernel_clean:
##########################################################################################
rootfs_prepare: prepare
@echo -e "$(C_GREEN) ==sysdrv== prepare rootfs $(C_NORMAL)"
rm -rf $(SYSDRV_DIR_OUT_ROOTFS)
mkdir -p $(SYSDRV_DIR_OUT_ROOTFS)
tar xf $(SYSDRV_DIR)/tools/board/rootfs_script.tar -C $(SYSDRV_DIR_OUT_ROOTFS)
tar xjf $(TOOLCHAIN_DIR)/$(TOOLCHAIN_RUNTIME_LIB)/$(TOOLCHAIN_RUNTIME_LIB_C) -C $(SYSDRV_DIR_OUT_ROOTFS)
pushd $(SYSDRV_DIR_OUT_ROOTFS)/lib/ ; mv -fv \
@ -509,24 +540,46 @@ busybox_clean:
# author :luckfox team
# date:2023-11-11
##########################################################################################
buildroot_menuconfig:
$(MAKE) menuconfig -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
$(MAKE) source -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
@echo -e "$(C_GREEN) ==sysdrv== buildroot memnuconfig $(C_NORMAL)"
$(MAKE) $(BUILDROOT_DEFCONFIG) -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
$(MAKE) menuconfig -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
# $(MAKE) source -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
buildroot_savedefconfig:
@echo -e "$(C_GREEN) ==sysdrv== buildroot savedefconfig $(C_NORMAL)"
$(MAKE) savedefconfig -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
buildroot_create:
@echo -e "$(C_GREEN) ==sysdrv== buildroot create $(C_NORMAL)"
rm $(BUILDROOT_DIR)/$(BUILDROOT_VER) -rf ;\
mkdir -p $(BUILDROOT_DIR)
tar xzf $(SYSDRV_DIR)/tools/board/buildroot/$(BUILDROOT_VER).tar.gz -C $(BUILDROOT_DIR)
cp $(SYSDRV_DIR)/tools/board/buildroot/luckfox_pico_defconfig $(BUILDROOT_DIR)/$(BUILDROOT_VER)/configs/
cp $(SYSDRV_DIR)/tools/board/buildroot/luckfox_pico_w_defconfig $(BUILDROOT_DIR)/$(BUILDROOT_VER)/configs/
cp $(SYSDRV_DIR)/tools/board/buildroot/busybox.config $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/busybox/
cp ${HCITOOL_TOOL_PATH}/0001-Fixed-header-file-errors.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/
cp ${HCITOOL_TOOL_PATH}/0002-Fix-build-errors.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/
cp ${HCITOOL_TOOL_PATH}/0003-fix-compat-wordexp.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/
cp ${MPV_PATCH_PATH}/0002-change-j1.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/mpv/
buildroot: prepare
@echo -e "$(C_GREEN) ==sysdrv== build buildroot $(C_NORMAL)"
test -f $(BUILDROOT_DIR)/$(BUILDROOT_VER)/output/target/bin/busybox || (\
rm $(BUILDROOT_DIR)/$(BUILDROOT_VER) -rf ;\
@echo -e "$(C_GREEN) ==sysdrv== build buildroot $(C_NORMAL)"
test -d $(BUILDROOT_DIR)/$(BUILDROOT_VER) || (\
mkdir -p $(BUILDROOT_DIR) ;\
tar xzf $(SYSDRV_DIR)/tools/board/buildroot/$(BUILDROOT_VER).tar.gz -C $(BUILDROOT_DIR) ;\
cp $(SYSDRV_DIR)/tools/board/buildroot/luckfox_pico_defconfig $(BUILDROOT_DIR)/$(BUILDROOT_VER)/configs/ ;\
cp $(SYSDRV_DIR)/tools/board/buildroot/luckfox_pico_w_defconfig $(BUILDROOT_DIR)/$(BUILDROOT_VER)/configs/ ;\
cp $(SYSDRV_DIR)/tools/board/buildroot/busybox.config $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/busybox/ ;\
cp ${HCITOOL_TOOL_PATH}/0001-Fixed-header-file-errors.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/ ;\
cp ${HCITOOL_TOOL_PATH}/0002-Fix-build-errors.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/ ;\
cp ${HCITOOL_TOOL_PATH}/0003-fix-compat-wordexp.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/bluez5_utils/ ;\
cp ${MPV_PATCH_PATH}/0002-change-j1.patch $(BUILDROOT_DIR)/$(BUILDROOT_VER)/package/mpv/ ;\
);
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) $(BUILDROOT_DEFCONFIG) -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
$(SYSDRV_DIR)/tools/board/mirror_select/buildroot_mirror_select.sh $(BUILDROOT_DIR)/$(BUILDROOT_VER)/.config
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) source -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
$(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -j$(SYSDRV_JOBS) -C $(BUILDROOT_DIR)/$(BUILDROOT_VER)
@ -547,10 +600,14 @@ else
cp $(SYSDRV_DIR)/tools/board/buildroot/sshd_defconfig $(SYSDRV_DIR_OUT_ROOTFS)/etc/ssh/sshd_config
cp $(SYSDRV_DIR)/tools/board/buildroot/samba_defconfig $(SYSDRV_DIR_OUT_ROOTFS)/etc/samba/smb.conf
cp $(SYSDRV_DIR)/tools/board/buildroot/smbpasswd_defconfig $(SYSDRV_DIR_OUT_ROOTFS)/etc/samba/smbpasswd
cp $(SYSDRV_DIR)/tools/board/buildroot/profile_defconfig $(SYSDRV_DIR_OUT_ROOTFS)/etc/profile
cp $(SYSDRV_DIR)/tools/board/buildroot/iomux $(SYSDRV_DIR_OUT_ROOTFS)/usr/bin/
cp $(SYSDRV_DIR)/tools/board/buildroot/S99hciinit $(SYSDRV_DIR_OUT_ROOTFS)/etc/init.d/
cp $(SYSDRV_DIR)/tools/board/buildroot/S50sshd $(SYSDRV_DIR_OUT_ROOTFS)/etc/init.d/
cp $(SYSDRV_DIR)/tools/board/buildroot/S99python $(SYSDRV_DIR_OUT_ROOTFS)/etc/init.d/
cp $(SYSDRV_DIR)/tools/board/luckfox_config/S99luckfoxconfigload $(SYSDRV_DIR_OUT_ROOTFS)/etc/init.d/
cp $(SYSDRV_DIR)/tools/board/luckfox_config/luckfox-config $(SYSDRV_DIR_OUT_ROOTFS)/usr/bin/
cp $(SYSDRV_DIR)/tools/board/android-tools/S90usb0config $(SYSDRV_DIR_OUT_ROOTFS)/etc/init.d/
endif
buildroot_clean:
@ -563,7 +620,7 @@ buildroot_clean:
##########################################################################################
ubuntu: prepare
@echo -e "$(C_GREEN) ==sysdrv== build ubuntu $(C_NORMAL)"
echo "====$(LF_TARGET_ROOTFS)===="
@echo -e "$(C_GREEN) ==$(LF_TARGET_ROOTFS)== $(C_NORMAL)"
test -f $(SYSDRV_DIR)/tools/board/ubuntu/$(UBUNTU_VER).tar.gz || (\
pushd $(SYSDRV_DIR)/tools/board/ubuntu/ ;\
./split_and_check_md5.sh merge ./$(UBUNTU_VER).tar.gz ;\
@ -574,6 +631,12 @@ ubuntu: prepare
rm $(SYSDRV_DIR_OUT_ROOTFS)/* -rf ;\
tar xzf $(SYSDRV_DIR)/tools/board/ubuntu/$(UBUNTU_VER).tar.gz -C $(SYSDRV_DIR_OUT_ROOTFS) ;\
);
ifeq ($(ENABLE_EMMC),YES)
cp $(SYSDRV_DIR)/tools/board/emmc/emmc_fstab $(SYSDRV_DIR_OUT_ROOTFS)/etc/fstab
cp $(SYSDRV_DIR)/tools/board/emmc/emmc_filesystem_resize.sh $(SYSDRV_DIR_OUT_ROOTFS)/usr/bin/filesystem_resize.sh
cp $(SYSDRV_DIR)/tools/board/emmc/emmc_rc.local $(SYSDRV_DIR_OUT_ROOTFS)/etc/rc.local
endif
ubuntu_clean:
$(AT)rm -rf $(SYSDRV_DIR_OUT_ROOTFS)
@ -676,6 +739,10 @@ rootfs_initramfs:
rootfs_clean:
$(AT)rm $(SYSDRV_DIR_OUT_ROOTFS)/ -rf
test ! -d $(BUILDROOT_DIR)/$(BUILDROOT_VER)/output/target || (\
rm -rf $(BUILDROOT_DIR)/$(BUILDROOT_VER)/output/target ;\
find $(BUILDROOT_DIR)/$(BUILDROOT_VER) -name ".stamp_target_installed" -exec rm {} \; ;\
);
##########################################################################################
# build env.img
@ -687,6 +754,11 @@ ifeq ($(BOOT_MEDIUM),emmc)
@test "$(ROOTFS_PART_NUM)" = "FAIL" || \
echo "sys_bootargs=root=/dev/mmcblk0p$(ROOTFS_PART_NUM)" >> $(SYSDRV_UBOOT_ENV_CFG_FILE)
endif
ifeq ($(BOOT_MEDIUM),sd_card)
@echo "blkdevparts=mmcblk1:$(CONFIG_SYSDRV_PARTITION)" > $(SYSDRV_UBOOT_ENV_CFG_FILE)
@test "$(ROOTFS_PART_NUM)" = "FAIL" || \
echo "sys_bootargs=root=/dev/mmcblk1p$(ROOTFS_PART_NUM)" >> $(SYSDRV_UBOOT_ENV_CFG_FILE)
endif
ifeq ($(BOOT_MEDIUM),spi_nor)
@echo "mtdparts=sfc_nor:$(CONFIG_SYSDRV_PARTITION)" > $(SYSDRV_UBOOT_ENV_CFG_FILE)
@test "$(ROOTFS_PART_NUM)" = "FAIL" || \

View File

@ -66,6 +66,10 @@ ifneq ($(findstring $(RK_ENABLE_WIFI_CHIP),"AP6XXX"),)
#@make -C bcmdhd_chipalive/
endif
ifneq ($(findstring $(RK_ENABLE_WIFI_CHIP),"AIC8800DC"),)
@make -C aic8800dc/
endif
else
build-usb:
@ -78,6 +82,7 @@ build-sdio:
@make -C atbm/
@make -C atbm6441/
#@make -C bcmdhd_chipalive/
@make -C aic8800dc/
endif
@ -87,6 +92,7 @@ build-sdio-clean:
@make -C hichannel/ clean
@make -C atbm/ clean
@make -C atbm6441/ clean
@make -C aic8800dc/ clean
build-usb-clean:
@make -C rtl8188ftv clean

3
sysdrv/drv_ko/wifi/aic8800dc/.gitignore vendored Executable file
View File

@ -0,0 +1,3 @@
*.symvers
*.order
.tmp_versions/

View File

@ -0,0 +1,18 @@
config AIC_WLAN_SUPPORT
bool "AIC wireless Support"
default n
help
This is support for aic wireless chip.
config AIC_FW_PATH
depends on AIC_WLAN_SUPPORT
string "Firmware & config file path"
#default "/vendor/etc/firmware"
default "/lib/firmware/aic8800_sdio"
help
Path to the firmware & config file.
if AIC_WLAN_SUPPORT
source "drivers/net/wireless/aic8800/aic8800_fdrv/Kconfig"
source "drivers/net/wireless/aic8800/aic8800_btlpm/Kconfig"
endif

View File

@ -0,0 +1,87 @@
CONFIG_AIC8800_BTLPM_SUPPORT := m
CONFIG_AIC8800_WLAN_SUPPORT := m
CONFIG_AIC_WLAN_SUPPORT := m
obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) += aic8800_btlpm/
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) += aic8800_fdrv/
obj-$(CONFIG_AIC_WLAN_SUPPORT) += aic8800_bsp/
# Platform support list
CONFIG_PLATFORM_ROCKCHIP = y
CONFIG_PLATFORM_ROCKCHIP2 = n
CONFIG_PLATFORM_ALLWINNER = n
CONFIG_PLATFORM_AMLOGIC = n
CONFIG_PLATFORM_UBUNTU = n
MAKEFLAGS +=-j$(shell nproc)
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
ARCH ?= arm
CROSS_COMPILE ?= arm-rockchip830-linux-uclibcgnueabihf-
KDIR := ../../../source/kernel
ccflags-y += -DANDROID_PLATFORM
ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
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-
ccflags-y += -DANDROID_PLATFORM
ccflags-y += -DCONFIG_PLATFORM_ROCKCHIP2
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
KDIR = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9
ARCH = arm64
CROSS_COMPILE = /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/out/gcc-linaro-5.3.1-2016.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
ccflags-y += -DANDROID_PLATFORM
ARCH = arm
CROSS_COMPILE = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androidkernel-
KDIR = /home/yaya/D/Workspace/CyberQuantum/JinHaoYue/amls905x3/SDK/20191101-0tt-asop/android9.0/out/target/product/u202/obj/KERNEL_OBJ/
endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
KDIR = /lib/modules/$(shell uname -r)/build
PWD = $(shell pwd)
KVER = $(shell uname -r)
MODDESTDIR = /lib/modules/$(KVER)/kernel/drivers/net/wireless/aic8800
ARCH = x86_64
CROSS_COMPILE =
endif
all: modules
modules:
make -C $(KDIR) M=$(shell pwd) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
$(CROSS_COMPILE)strip --strip-debug $(shell pwd)/*/*.ko
cp $(shell pwd)/aic8800_fdrv/aic8800_fdrv.ko $(M_OUT_DIR)
cp $(shell pwd)/aic8800_btlpm/aic8800_btlpm.ko $(M_OUT_DIR)
cp $(shell pwd)/aic8800_bsp/aic8800_bsp.ko $(M_OUT_DIR)
cp -r $(shell pwd)/aic8800dc_fw $(M_OUT_DIR)
install:
mkdir -p $(MODDESTDIR)
install -p -m 644 aic8800_bsp/aic8800_bsp.ko $(MODDESTDIR)/
install -p -m 644 aic8800_fdrv/aic8800_fdrv.ko $(MODDESTDIR)/
install -p -m 644 aic8800_btlpm/aic8800_btlpm.ko $(MODDESTDIR)/
/sbin/depmod -a ${KVER}
uninstall:
rm -rfv $(MODDESTDIR)/aic8800_bsp.ko
rm -rfv $(MODDESTDIR)/aic8800_fdrv.ko
rm -rfv $(MODDESTDIR)/aic8800_btlpm.ko
/sbin/depmod -a ${KVER}
clean:
cd aic8800_bsp/;make clean;cd ..
cd aic8800_fdrv/;make clean;cd ..
cd aic8800_btlpm/;make clean;cd ..
rm -rf modules.order Module.symvers .tmp_versions/

View File

@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@ -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

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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");

File diff suppressed because it is too large Load Diff

View File

@ -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_*/

View File

@ -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;
}

View File

@ -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_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
int aicwf_get_firmware_array(char* fw_name, u32 **fw_buf);

View File

@ -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);

View File

@ -0,0 +1,4 @@
void aicwf_prealloc_txq_free(void);

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@ -0,0 +1,5 @@
config AIC8800_BTLPM_SUPPORT
tristate "AIC8800 bluetooth Support"
help
This is support for aic bluetooh driver.

View File

@ -0,0 +1,98 @@
CONFIG_AIC8800_BTLPM_SUPPORT = m
obj-$(CONFIG_AIC8800_BTLPM_SUPPORT) := aic8800_btlpm.o
ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp
# Platform support list
CONFIG_PLATFORM_ROCKCHIP ?= n
CONFIG_PLATFORM_ROCKCHIP2 ?= n
CONFIG_PLATFORM_ALLWINNER ?= n
CONFIG_PLATFORM_AMLOGIC ?= n
CONFIG_PLATFORM_UBUNTU ?= y
CONFIG_SUPPORT_LPM = y
CONFIG_AUTO_PM ?= n
aic8800_btlpm-y := \
aic_bluetooth_main.o \
rfkill.o \
ifeq ($(CONFIG_PLATFORM_UBUNTU), n)
aic8800_btlpm-$(CONFIG_SUPPORT_LPM) += lpm.o
endif
ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src)
ccflags-$(CONFIG_AUTO_PM) += -DCONFIG_AUTO_PM
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
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/3229/Android10/SDK/kernel/
#ARCH ?= arm
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3229/Android10/SDK/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/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/3328/Android9/SDK/SDK/kernel
#ARCH ?= arm64
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3328/Android9/SDK/SDK/prebuilts/gcc/linux-x86/aarch64/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
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-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
KDIR ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/lichee/kernel/linux-4.9/
ARCH ?= arm64
CROSS_COMPILE ?= /home/yaya/E/Allwinner/R818/R818/AndroidQ/android/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_AMLOGIC), y)
ccflags-$(CONFIG_PLATFORM_NANOPI) += -DCONFIG_PLATFORM_NANOPI
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,88 @@
#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 "lpm.h"
#include "rfkill.h"
#define DRV_CONFIG_FW_NAME "fw.bin"
#define DRV_DESCRIPTION "AIC BLUETOOTH"
#define DRV_COPYRIGHT "Copyright(c) 2015-2020 AICSemi"
#define DRV_AUTHOR "AICSemi"
#define DRV_VERS_MOD "1.0"
static struct platform_device *aicbt_pdev;
static struct platform_driver aicbt_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "aic_bt",
},
//.probe = aicbt_probe,
//.remove = aicbt_remove,
};
static int __init aic_bluetooth_mod_init(void)
{
int ret;
printk("%s\n", __func__);
ret = platform_driver_register(&aicbt_driver);
if (ret) {
pr_err("register platform driver failed: %d\n", ret);
return ret;
}
aicbt_pdev = platform_device_alloc("aic-bt", -1);
ret = platform_device_add(aicbt_pdev);
if (ret) {
pr_err("register platform device failed: %d\n", ret);
goto err0;
}
ret = rfkill_bluetooth_init(aicbt_pdev);
if (ret) {
pr_err("rfkill init fail\n");
goto err1;
}
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
ret = bluesleep_init(aicbt_pdev);
if (ret) {
pr_err("bluesleep init fail\n");
goto err2;
}
#endif
return 0;
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
err2:
#endif
rfkill_bluetooth_remove(aicbt_pdev);
err1:
platform_device_del(aicbt_pdev);
err0:
platform_driver_unregister(&aicbt_driver);
return ret;
}
static void __exit aic_bluetooth_mod_exit(void)
{
printk("%s\n", __func__);
#if defined(ANDROID_PLATFORM) && !defined(CONFIG_PLATFORM_ROCKCHIP) && !defined(CONFIG_PLATFORM_ROCKCHIP2)
bluesleep_exit(aicbt_pdev);
#endif
rfkill_bluetooth_remove(aicbt_pdev);
platform_device_del(aicbt_pdev);
platform_driver_unregister(&aicbt_driver);
}
module_init(aic_bluetooth_mod_init);
module_exit(aic_bluetooth_mod_exit);
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERS_MOD);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,19 @@
#ifndef __AIC_BSP_EXPORT_H
#define __AIC_BSP_EXPORT_H
#define AIC_BLUETOOTH 0
#define AIC_WIFI 1
#define AIC_PWR_OFF 0
#define AIC_PWR_ON 1
struct aicbsp_feature_t {
bool band_5g_support;
uint32_t sdio_clock;
uint8_t sdio_phase;
uint8_t irqf;
};
int aicbsp_set_subsys(int, int);
int aicbsp_get_feature(struct aicbsp_feature_t *feature);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
/*
* Copyright (C) 2015 Spreadtrum Communications Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LPM_H
#define __LPM_H
int bluesleep_init(struct platform_device *pdev);
int bluesleep_exit(struct platform_device *dev);
#endif

View File

@ -0,0 +1,81 @@
/*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/gpio.h>
#include <linux/ioport.h>
#include <linux/clk.h>
#include <linux/of_gpio.h>
#include <linux/version.h>
#include "aic_bsp_export.h"
static struct rfkill *bt_rfk;
static const char bt_name[] = "bluetooth";
static int bluetooth_set_power(void *data, bool blocked)
{
pr_info("%s: start_block=%d\n", __func__, blocked);
if (!blocked) {
aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON);
} else {
aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_OFF);
}
pr_info("%s: end_block=%d\n", __func__, blocked);
return 0;
}
static struct rfkill_ops rfkill_bluetooth_ops = {
.set_block = bluetooth_set_power,
};
int rfkill_bluetooth_init(struct platform_device *pdev)
{
int rc = 0;
pr_info("-->%s\n", __func__);
bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH,
&rfkill_bluetooth_ops, NULL);
if (!bt_rfk) {
rc = -ENOMEM;
goto err_rfkill_alloc;
}
/* userspace cannot take exclusive control */
rfkill_init_sw_state(bt_rfk, true);
rc = rfkill_register(bt_rfk);
if (rc)
goto err_rfkill_reg;
pr_info("<--%s\n", __func__);
return 0;
err_rfkill_reg:
rfkill_destroy(bt_rfk);
err_rfkill_alloc:
return rc;
}
int rfkill_bluetooth_remove(struct platform_device *dev)
{
pr_info("-->%s\n", __func__);
rfkill_unregister(bt_rfk);
rfkill_destroy(bt_rfk);
pr_info("<--%s\n", __func__);
return 0;
}

View File

@ -0,0 +1,17 @@
/*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __RFKILL_H__
#define __RFKILL_H__
int rfkill_bluetooth_init(struct platform_device *pdev);
int rfkill_bluetooth_remove(struct platform_device *pdev);
#endif

View File

@ -0,0 +1,10 @@
*.o
*.ko
*.order
*.symvers
*.o.d
*.o.cmd
*.ko.cmd
*.mod
*.mod.c
*.mod.cmd

View File

@ -0,0 +1,5 @@
config AIC8800_WLAN_SUPPORT
tristate "AIC8800 wlan Support"
help
This is support for aic wifi driver.

View File

@ -0,0 +1,384 @@
EXTRA_CFLAGS += $(USER_EXTRA_CFLAGS)
EXTRA_CFLAGS += -Wno-implicit-fallthrough
EXTRA_CFLAGS += -Wno-unused-function
#EXTRA_CFLAGS += -Wno-maybe-uninitialized
# EXTRA_CFLAGS += -Wno-unused-variable
RWNX_VERS_NUM := 6.4.3.0
CONFIG_COUNTRY_CODE = "00"
MODULE_NAME = aic8800_fdrv
CONFIG_AIC8800_WLAN_SUPPORT = m
# Support of bootrom start
CONFIG_START_FROM_BOOTROM = y
# Support of pmic setting, new version bootrom avaliable
CONFIG_PMIC_SETTING ?=y
# Select 8800DC/DW DCDC_VRF mode, check your board
CONFIG_VRF_DCDC_MODE = y
# ROM patch enabled option
CONFIG_ROM_PATCH_EN ?=y
# Support chip with mcu
CONFIG_MCU_INTEGRATED ?= n
CONFIG_MCU_MESSAGE ?= n
ifeq ($(CONFIG_MCU_INTEGRATED), y)
CONFIG_PMIC_SETTING = n
else
CONFIG_MCU_MESSAGE ?= n
endif
#
# WAITING FOR KCONFIG {
#
CONFIG_RWNX_FULLMAC ?= y
CONFIG_RWNX_FHOST ?= n
#
# DEBUG OPTIONS
CONFIG_RWNX_UM_HELPER_DFLT ?= "/dini/dini_bin/rwnx_umh.sh"
#
# FW ARCH:
CONFIG_RWNX_SDM ?= n
CONFIG_RWNX_TL4 ?= n
# IPC version
CONFIG_RWNX_OLD_IPC ?= n
# Support of P2P DebugFS for enabling/disabling NoA and OppPS
CONFIG_RWNX_P2P_DEBUGFS := n
#
# } // WAITING FOR KCONFIG
#
# Enable A-MSDU support (need FW support)
## Select this if FW is compiled with AMSDU support
CONFIG_RWNX_SPLIT_TX_BUF ?= n
## Select this TO send AMSDU
CONFIG_RWNX_AMSDUS_TX ?= n
# Enable BFMER support (need FW support)
CONFIG_RWNX_BFMER ?= n
CONFIG_SDIO_SUPPORT =y
CONFIG_USB_SUPPORT =n
CONFIG_RX_REORDER ?=y
CONFIG_ARP_OFFLOAD =y
CONFIG_RADAR_OR_IR_DETECT =n
CONFIG_DOWNLOAD_FW =n
CONFIG_RFTEST=y
CONFIG_USB_BT =y
CONFIG_USE_5G ?= y
CONFIG_SDIO_PWRCTRL ?= y
CONFIG_CREATE_TRACE_POINTS = n
CONFIG_TXRX_THREAD_PRIO = y
# CONFIG_COEX = n for BT_ONLY, CONFIG_COEX =y for combo and sw
CONFIG_COEX = y
CONFIG_RX_NETIF_RECV_SKB = y
CONFIG_GPIO_WAKEUP = n
CONFIG_SET_VENDOR_EXTENSION_IE = n
CONFIG_SUPPORT_REALTIME_CHANGE_MAC = y
CONFIG_WPA3_FOR_OLD_KERNEL ?= n
CONFIG_VHT_FOR_OLD_KERNEL ?= n
CONFIG_HE_FOR_OLD_KERNEL ?= n
CONFIG_PREALLOC_RX_SKB = n
CONFIG_WIFI_SUSPEND_FOR_LINUX = n
# Need to set fw path in BOARD_KERNEL_CMDLINE
CONFIG_USE_FW_REQUEST = n
CONFIG_USE_P2P0=n
CONFIG_BR_SUPPORT =n
BR_NAME = br0
CONFIG_FDRV_NO_REG_SDIO=n
CONFIG_SCHED_SCAN = n
CONFIG_OOB = n
CONFIG_USE_CUSTOMER_MAC = n
CONFIG_PREALLOC_TXQ = y
CONFIG_DPD = y
CONFIG_FORCE_DPD_CALIB = y
CONFIG_FILTER_TCP_ACK =n
CONFIG_RESV_MEM_SUPPORT = y
CONFIG_GKI = n
CONFIG_TEMP_COMP = n
# Support of MU-MIMO transmission (need FW support)
ifeq ($(CONFIG_RWNX_BFMER), y)
CONFIG_RWNX_MUMIMO_TX ?= n
else
CONFIG_RWNX_MUMIMO_TX = n
endif
# Enable handling of radar event
CONFIG_RWNX_RADAR ?= y
# Enable HW queue for Broadcast/Multicast traffic (need FW support)
CONFIG_RWNX_BCMC ?= y
# Enable Monitor+Data interface support (need FW support)
CONFIG_RWNX_MON_DATA =y
# extra DEBUG config
CONFIG_RWNX_SW_PROFILING ?= n
CONFIG_RWNX_DBG ?= y
CONFIG_DEBUG_FS ?= n
obj-$(CONFIG_AIC8800_WLAN_SUPPORT) := $(MODULE_NAME).o
$(MODULE_NAME)-y := \
rwnx_msg_tx.o \
rwnx_msg_rx.o \
rwnx_utils.o \
rwnx_cmds.o \
rwnx_irqs.o \
rwnx_cfgfile.o \
rwnx_strs.o \
rwnx_rx.o \
rwnx_tx.o \
rwnx_txq.o \
rwnx_main.o \
rwnx_mod_params.o \
rwnx_mesh.o \
rwnx_platform.o \
rwnx_pci.o \
rwnx_dini.o \
rwnx_v7.o \
ipc_host.o \
rwnx_tdls.o \
aic_vendor.o \
md5.o \
aicwf_compat_8800dc.o \
aicwf_compat_8800d80.o \
rwnx_wakelock.o \
regdb.o \
aicwf_rx_prealloc.o
$(MODULE_NAME)-$(CONFIG_BR_SUPPORT) += aic_br_ext.o
$(MODULE_NAME)-$(CONFIG_RWNX_RADAR) += rwnx_radar.o
$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_debugfs.o
$(MODULE_NAME)-$(CONFIG_DEBUG_FS) += rwnx_fw_trace.o
$(MODULE_NAME)-$(CONFIG_NL80211_TESTMODE) += rwnx_testmode.o
$(MODULE_NAME)-$(CONFIG_RWNX_BFMER) += rwnx_bfmer.o
$(MODULE_NAME)-$(CONFIG_RWNX_MUMIMO_TX) += rwnx_mu_group.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += sdio_host.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_txrxif.o
$(MODULE_NAME)-$(CONFIG_SDIO_SUPPORT) += aicwf_sdio.o
$(MODULE_NAME)-$(CONFIG_FILTER_TCP_ACK) += aicwf_tcp_ack.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += usb_host.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_txrxif.o
$(MODULE_NAME)-$(CONFIG_USB_SUPPORT) += aicwf_usb.o
$(MODULE_NAME)-$(CONFIG_GKI) += rwnx_gki.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
# FW VARS
ccflags-y += -DNX_VIRT_DEV_MAX=4
#for 8800D and DCDW u01
#ccflags-y += -DNX_REMOTE_STA_MAX=10
#for 8800DCDW u02
ccflags-y += -DNX_REMOTE_STA_MAX_FOR_OLD_IC=10
ccflags-y += -DNX_REMOTE_STA_MAX=32
ccflags-y += -DNX_MU_GROUP_MAX=62
ccflags-y += -DNX_TXDESC_CNT=64
ccflags-y += -DNX_TX_MAX_RATES=4
ccflags-y += -DNX_CHAN_CTXT_CNT=3
# FW ARCH:
ccflags-$(CONFIG_RWNX_SDM) += -DCONFIG_RWNX_SDM
ccflags-$(CONFIG_RWNX_TL4) += -DCONFIG_RWNX_TL4
ccflags-$(CONFIG_RWNX_OLD_IPC) += -DCONFIG_RWNX_OLD_IPC
ccflags-$(CONFIG_PLATFORM_NANOPI_M4) += -DCONFIG_NANOPI_M4
ccflags-$(CONFIG_PLATFORM_INGENIC_T20) += -DCONFIG_INGENIC_T20
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
ccflags-$(CONFIG_START_FROM_BOOTROM) += -DCONFIG_START_FROM_BOOTROM
ccflags-$(CONFIG_PMIC_SETTING) += -DCONFIG_PMIC_SETTING
ccflags-$(CONFIG_VRF_DCDC_MODE) += -DCONFIG_VRF_DCDC_MODE
ccflags-$(CONFIG_ROM_PATCH_EN) += -DCONFIG_ROM_PATCH_EN
ccflags-$(CONFIG_HE_FOR_OLD_KERNEL) += -DCONFIG_HE_FOR_OLD_KERNEL
ccflags-$(CONFIG_MCU_INTEGRATED) += -DCONFIG_MCU_INTEGRATED
ccflags-$(CONFIG_MCU_MESSAGE) += -DCONFIG_MCU_MESSAGE
ccflags-$(CONFIG_COEX) += -DCONFIG_COEX
ccflags-y += -DCONFIG_RWNX_FULLMAC
ccflags-y += -I$(srctree)
ccflags-y += -I$(srctree)/$(src)
ccflags-y += -I$(srctree)/$(src)/../aic8800_bsp
ccflags-y += -DCONFIG_AIC_FW_PATH=\"$(CONFIG_AIC_FW_PATH)\"
ccflags-$(CONFIG_RWNX_RADAR) += -DCONFIG_RWNX_RADAR
ccflags-$(CONFIG_RWNX_MON_DATA) += -DCONFIG_RWNX_MON_DATA
ccflags-$(CONFIG_RWNX_BFMER) += -DCONFIG_RWNX_BFMER
ccflags-$(CONFIG_RWNX_SPLIT_TX_BUF) += -DCONFIG_RWNX_SPLIT_TX_BUF
ifeq ($(CONFIG_RWNX_SPLIT_TX_BUF), y)
ccflags-$(CONFIG_RWNX_AMSDUS_TX) += -DCONFIG_RWNX_AMSDUS_TX
endif
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-y += -DDEFAULT_COUNTRY_CODE=""\$(CONFIG_COUNTRY_CODE)"\"
ccflags-$(CONFIG_USE_5G) += -DUSE_5G
ccflags-$(CONFIG_CREATE_TRACE_POINTS) += -DCREATE_TRACE_POINTS
ccflags-$(CONFIG_TXRX_THREAD_PRIO) += -DCONFIG_TXRX_THREAD_PRIO
ccflags-$(CONFIG_GPIO_WAKEUP) += -DCONFIG_GPIO_WAKEUP
ccflags-$(CONFIG_SET_VENDOR_EXTENSION_IE) += -DCONFIG_SET_VENDOR_EXTENSION_IE
ccflags-$(CONFIG_SUPPORT_REALTIME_CHANGE_MAC) += -DCONFIG_SUPPORT_REALTIME_CHANGE_MAC
ccflags-$(CONFIG_WPA3_FOR_OLD_KERNEL) += -DCONFIG_WPA3_FOR_OLD_KERNEL
ccflags-$(CONFIG_VHT_FOR_OLD_KERNEL) += -DCONFIG_VHT_FOR_OLD_KERNEL
ccflags-$(CONFIG_PREALLOC_RX_SKB) += -DCONFIG_PREALLOC_RX_SKB
ccflags-$(CONFIG_WIFI_SUSPEND_FOR_LINUX) += -DCONFIG_WIFI_SUSPEND_FOR_LINUX
ccflags-$(CONFIG_USE_FW_REQUEST) += -DCONFIG_USE_FW_REQUEST
ccflags-$(CONFIG_USE_P2P0) += -DCONFIG_USE_P2P0
ccflags-$(CONFIG_FDRV_NO_REG_SDIO) += -DCONFIG_FDRV_NO_REG_SDIO
ccflags-$(CONFIG_SCHED_SCAN) += -DCONFIG_SCHED_SCAN
ccflags-$(CONFIG_OOB) += -DCONFIG_OOB
ccflags-$(CONFIG_USE_CUSTOMER_MAC) += -DCONFIG_USE_CUSTOMER_MAC
ccflags-$(CONFIG_PREALLOC_TXQ) += -DCONFIG_PREALLOC_TXQ
ccflags-$(CONFIG_DPD) += -DCONFIG_DPD
ccflags-$(CONFIG_FORCE_DPD_CALIB) += -DCONFIG_FORCE_DPD_CALIB -DCONFIG_DPD
ccflags-$(CONFIG_FILTER_TCP_ACK) += -DCONFIG_FILTER_TCP_ACK
ccflags-$(CONFIG_RESV_MEM_SUPPORT) += -DCONFIG_RESV_MEM_SUPPORT
ccflags-$(CONFIG_GKI) += -DCONFIG_GKI
ccflags-$(CONFIG_TEMP_COMP) += -DCONFIG_TEMP_COMP
ifeq ($(CONFIG_SDIO_SUPPORT), y)
ccflags-y += -DAICWF_SDIO_SUPPORT
ccflags-$(CONFIG_SDIO_PWRCTRL) += -DCONFIG_SDIO_PWRCTRL
endif
ifeq ($(CONFIG_USB_SUPPORT), y)
ccflags-y += -DAICWF_USB_SUPPORT
endif
ifeq ($(CONFIG_BR_SUPPORT), y)
ccflags-y += -DCONFIG_BR_SUPPORT
ccflags-y += '-DCONFIG_BR_SUPPORT_BRNAME="'$(BR_NAME)'"'
endif
ifeq ($(CONFIG_RWNX_MUMIMO_TX), y)
ccflags-y += -DCONFIG_USER_MAX=2
else
ccflags-y += -DCONFIG_USER_MAX=1
endif
ifeq ($(CONFIG_RWNX_BCMC), y)
ccflags-y += -DNX_TXQ_CNT=5
else
ccflags-y += -DNX_TXQ_CNT=4
endif
# For old kernel (<=3.19)
ifeq ($(shell test $(VERSION) -lt 4 -a "$(CONFIG_VENDOR_RWNX)" = y ; echo $$?),0)
ccflags-y += -DCONFIG_VENDOR_RWNX_VHT_NO80
endif
ccflags-$(CONFIG_RX_REORDER) += -DAICWF_RX_REORDER
ccflags-$(CONFIG_ARP_OFFLOAD) += -DAICWF_ARP_OFFLOAD
ccflags-$(CONFIG_RADAR_DETECT) += -DRADAR_OR_IR_DETECT
ccflags-$(CONFIG_DOWNLOAD_FW) += -DCONFIG_DOWNLOAD_FW
ccflags-$(CONFIG_RX_NETIF_RECV_SKB) += -DCONFIG_RX_NETIF_RECV_SKB
# 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
ccflags-y += -DAIC_TRACE_INCLUDE_PATH=$(src)
ifeq ($(CONFIG_PLATFORM_ROCKCHIP), y)
#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/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/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/Android/kernel
#ARCH ?= arm64
#CROSS_COMPILE ?= /home/yaya/E/Rockchip/3566/Android/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/oudu/kernel
KDIR ?= ~/E/Rockchip/3566/Android11/rk3566_rk3568_android11_oranth/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-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP) += -DCONFIG_PLATFORM_ROCKCHIP
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ROCKCHIP2), y)
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-
ccflags-$(CONFIG_PLATFORM_ROCKCHIP2) += -DCONFIG_PLATFORM_ROCKCHIP2
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_ALLWINNER), y)
ccflags-$(CONFIG_PLATFORM_ALLWINNER) += -DCONFIG_PLATFORM_ALLWINNER
ccflags-y += -DANDROID_PLATFORM
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
ccflags-y += -DANDROID_PLATFORM
endif
ifeq ($(CONFIG_PLATFORM_UBUNTU), y)
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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2017 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*****************************************************************************/
#ifndef _AIC_BR_EXT_H_
#define _AIC_BR_EXT_H_
#define CL_IPV6_PASS 1
#define MACADDRLEN 6
#define WLAN_ETHHDR_LEN 14
#define NAT25_HASH_BITS 4
#define NAT25_HASH_SIZE (1 << NAT25_HASH_BITS)
#define NAT25_AGEING_TIME 300
#define NDEV_FMT "%s"
#define NDEV_ARG(ndev) ndev->name
#define ADPT_FMT "%s"
//#define ADPT_ARG(adapter) (adapter->pnetdev ? adapter->pnetdev->name : NULL)
#define FUNC_NDEV_FMT "%s(%s)"
#define FUNC_NDEV_ARG(ndev) __func__, ndev->name
#define FUNC_ADPT_FMT "%s(%s)"
//#define FUNC_ADPT_ARG(adapter) __func__, (adapter->pnetdev ? adapter->pnetdev->name : NULL)
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ARG(x) ((u8 *)(x))[0], ((u8 *)(x))[1], ((u8 *)(x))[2], ((u8 *)(x))[3], ((u8 *)(x))[4], ((u8 *)(x))[5]
#ifdef CL_IPV6_PASS
#define MAX_NETWORK_ADDR_LEN 17
#else
#define MAX_NETWORK_ADDR_LEN 11
#endif
struct nat25_network_db_entry {
struct nat25_network_db_entry *next_hash;
struct nat25_network_db_entry **pprev_hash;
atomic_t use_count;
unsigned char macAddr[6];
unsigned long ageing_timer;
unsigned char networkAddr[MAX_NETWORK_ADDR_LEN];
};
enum NAT25_METHOD {
NAT25_MIN,
NAT25_CHECK,
NAT25_INSERT,
NAT25_LOOKUP,
NAT25_PARSE,
NAT25_MAX
};
struct br_ext_info {
unsigned int nat25_disable;
unsigned int macclone_enable;
unsigned int dhcp_bcst_disable;
int addPPPoETag; /* 1: Add PPPoE relay-SID, 0: disable */
unsigned char nat25_dmzMac[MACADDRLEN];
unsigned int nat25sc_disable;
};
void nat25_db_cleanup(struct rwnx_vif *vif);
#endif /* _AIC_BR_EXT_H_ */

View File

@ -0,0 +1,58 @@
#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,
};
struct aicbsp_feature_t {
int hwinfo;
uint32_t sdio_clock;
uint8_t sdio_phase;
int fwlog_en;
uint8_t irqf;
};
enum skb_buff_id {
AIC_RESV_MEM_TXDATA,
};
#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);
bool aicbsp_get_load_fw_in_fdrv(void);
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

View File

@ -0,0 +1,909 @@
#include "aic_vendor.h"
#include "rwnx_defs.h"
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/rtnetlink.h>
#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",
.flags = 0,
.ring_id = 0,
.verbose_level = 0,
.written_bytes = 0,
.read_bytes = 0,
.written_records = 0,
},
};
static struct wlan_driver_wake_reason_cnt_t wake_reason_cnt = {
.total_cmd_event_wake = 10,
};
#endif
int aic_dev_start_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif,
u8 mkeep_alive_id, u8 *ip_pkt, u16 ip_pkt_len, u8 *src_mac, u8 *dst_mac, u32 period_msec)
{
u8 *data, *pos;
data = kzalloc(ip_pkt_len + 14, GFP_KERNEL);
if (!data)
return -ENOMEM;
pos = data;
memcpy(pos, dst_mac, 6);
pos += 6;
memcpy(pos, src_mac, 6);
pos += 6;
/* Mapping Ethernet type (ETHERTYPE_IP: 0x0800) */
*(pos++) = 0x08;
*(pos++) = 0x00;
/* Mapping IP pkt */
memcpy(pos, ip_pkt, ip_pkt_len);
pos += ip_pkt_len;
//add send 802.3 pkt(raw data)
kfree(data);
return 0;
}
int aic_dev_stop_mkeep_alive(struct rwnx_hw *rwnx_hw, struct rwnx_vif *rwnx_vif, u8 mkeep_alive_id)
{
int res = -1;
/*
* The mkeep_alive packet is for STA interface only; if the bss is configured as AP,
* dongle shall reject a mkeep_alive request.
*/
if (rwnx_vif->wdev.iftype != NL80211_IFTYPE_STATION)
return res;
printk("%s execution\n", __func__);
//add send stop keep alive
res = 0;
return res;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
static int aicwf_vendor_start_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
/* max size of IP packet for keep alive */
const int MKEEP_ALIVE_IP_PKT_MAX = 256;
int ret = 0, rem, type;
u8 mkeep_alive_id = 0;
u8 *ip_pkt = NULL;
u16 ip_pkt_len = 0;
u8 src_mac[6];
u8 dst_mac[6];
u32 period_msec = 0;
const struct nlattr *iter;
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev);
gfp_t kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
printk("%s\n", __func__);
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case MKEEP_ALIVE_ATTRIBUTE_ID:
mkeep_alive_id = nla_get_u8(iter);
break;
case MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN:
ip_pkt_len = nla_get_u16(iter);
if (ip_pkt_len > MKEEP_ALIVE_IP_PKT_MAX) {
ret = -EINVAL;
goto exit;
}
break;
case MKEEP_ALIVE_ATTRIBUTE_IP_PKT:
if (!ip_pkt_len) {
ret = -EINVAL;
printk("ip packet length is 0\n");
goto exit;
}
ip_pkt = (u8 *)kzalloc(ip_pkt_len, kflags);
if (ip_pkt == NULL) {
ret = -ENOMEM;
printk("Failed to allocate mem for ip packet\n");
goto exit;
}
memcpy(ip_pkt, (u8 *)nla_data(iter), ip_pkt_len);
break;
case MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR:
memcpy(src_mac, nla_data(iter), 6);
break;
case MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR:
memcpy(dst_mac, nla_data(iter), 6);
break;
case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC:
period_msec = nla_get_u32(iter);
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
ret = -EINVAL;
goto exit;
}
}
if (ip_pkt == NULL) {
ret = -EINVAL;
printk("ip packet is NULL\n");
goto exit;
}
ret = aic_dev_start_mkeep_alive(rwnx_hw, rwnx_vif, mkeep_alive_id, ip_pkt, ip_pkt_len, src_mac,
dst_mac, period_msec);
if (ret < 0) {
printk("start_mkeep_alive is failed ret: %d\n", ret);
}
exit:
if (ip_pkt) {
kfree(ip_pkt);
}
return ret;
}
static int aicwf_vendor_stop_mkeep_alive(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type;
u8 mkeep_alive_id = 0;
const struct nlattr *iter;
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct rwnx_vif *rwnx_vif = container_of(wdev, struct rwnx_vif, wdev);
printk("%s\n", __func__);
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case MKEEP_ALIVE_ATTRIBUTE_ID:
mkeep_alive_id = nla_get_u8(iter);
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
ret = -EINVAL;
break;
}
}
ret = aic_dev_stop_mkeep_alive(rwnx_hw, rwnx_vif, mkeep_alive_id);
if (ret < 0) {
printk("stop_mkeep_alive is failed ret: %d\n", ret);
}
return ret;
}
static int aicwf_vendor_get_ver(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type;
const struct nlattr *iter;
int payload = 0;
char version[128];
int attr = -1;
struct sk_buff *reply;
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case LOGGER_ATTRIBUTE_DRIVER_VER:
memcpy(version, RWNX_VERS_BANNER, sizeof(RWNX_VERS_BANNER));
payload = strlen(version);
attr = LOGGER_ATTRIBUTE_DRIVER_VER;
break;
case LOGGER_ATTRIBUTE_FW_VER:
memcpy(version, wiphy->fw_version, sizeof(wiphy->fw_version));
payload = strlen(version);
attr = LOGGER_ATTRIBUTE_FW_VER;
break;
default:
AICWFDBG(LOGERROR, "%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
if (attr < 0)
return -EINVAL;
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
if (nla_put(reply, attr,
payload, version)) {
wiphy_err(wiphy, "%s put version error\n", __func__);
goto out_put_fail;
}
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "%s reply cmd error\n", __func__);
return ret;
out_put_fail:
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_subcmd_get_channel_list(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type;
const struct nlattr *iter;
struct sk_buff *reply;
int num_channels = 0;
int *channel_list = NULL;
int payload;
int i = 0;
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
struct ieee80211_supported_band *rwnx_band_2GHz = rwnx_hw->wiphy->bands[NL80211_BAND_2GHZ];
struct ieee80211_supported_band *rwnx_band_5GHz = rwnx_hw->wiphy->bands[NL80211_BAND_5GHZ];
num_channels += rwnx_band_2GHz->n_channels;
num_channels += (rwnx_hw->band_5g_support) ? rwnx_band_5GHz->n_channels : 0;
channel_list = (int *)kzalloc(sizeof(int) * num_channels, GFP_KERNEL);
if (!channel_list)
return -ENOMEM;
for (i = 0; i < rwnx_band_2GHz->n_channels; i++)
channel_list[i] = rwnx_band_2GHz->channels[i].center_freq;
for (; rwnx_hw->band_5g_support && i < num_channels; i++)
channel_list[i] = rwnx_band_5GHz->channels[i].center_freq;
payload = sizeof(num_channels) + sizeof(int) * num_channels + 4;
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case GSCAN_ATTRIBUTE_BAND:
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
if (nla_put_u32(reply, GSCAN_ATTRIBUTE_NUM_CHANNELS, num_channels))
goto out_put_fail;
if (nla_put(reply, GSCAN_ATTRIBUTE_CHANNEL_LIST, sizeof(int) * num_channels, channel_list))
goto out_put_fail;
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "%s reply cmd error\n", __func__);
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
kfree(channel_list);
return ret;
out_put_fail:
kfree(channel_list);
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_subcmd_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type;
const struct nlattr *iter;
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case ANDR_WIFI_ATTRIBUTE_COUNTRY:
printk("%s(%d), ANDR_WIFI_ATTRIBUTE_COUNTRY: %s\n", __func__, __LINE__, (char *)nla_data(iter));
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
/* TODO
* Add handle in the future!
*/
return ret;
}
static int aicwf_vendor_logger_trigger_memory_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
/* TODO
* Add handle in the future!
*/
return 0;
}
static int aicwf_vendor_subcmd_get_feature_set(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret;
struct sk_buff *reply;
uint32_t feature = 0, payload;
struct rwnx_hw *rwnx_hw = wiphy_priv(wiphy);
payload = sizeof(feature);
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
/* TODO
* Add handle in the future!
*/
/*bit 1:Basic infrastructure mode*/
if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION))
feature |= WIFI_FEATURE_INFRA;
/*bit 2:Support for 5 GHz Band*/
if (rwnx_hw->band_5g_support)
feature |= WIFI_FEATURE_INFRA_5G;
/*bit3:HOTSPOT is a supplicant feature, enable it by default*/
feature |= WIFI_FEATURE_HOTSPOT;
/*bit 4:P2P*/
if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
(wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO)))
feature |= WIFI_FEATURE_P2P;
/*bit 5:soft AP feature supported*/
if (wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
feature |= WIFI_FEATURE_SOFT_AP;
/*bit 18:WiFi Logger*/
feature |= WIFI_FEATURE_LOGGER;
/*bit 21:WiFi mkeep_alive*/
feature |= WIFI_FEATURE_MKEEP_ALIVE;
if (nla_put_u32(reply, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, feature)) {
wiphy_err(wiphy, "%s put u32 error\n", __func__);
goto out_put_fail;
}
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "%s reply cmd error\n", __func__);
return ret;
out_put_fail:
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_logger_get_feature(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret;
struct sk_buff *reply;
uint32_t feature = 0, payload;
payload = sizeof(feature);
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
feature |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
feature |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
/*vts will test wake reason state function*/
feature |= WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
if (nla_put_u32(reply, ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET, feature)) {
wiphy_err(wiphy, "put skb u32 failed\n");
goto out_put_fail;
}
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "reply cmd error\n");
return ret;
out_put_fail:
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_logger_get_ring_status(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret;
struct sk_buff *reply;
uint32_t payload;
uint32_t ring_buffer_nums = sizeof(ring_buffer) / sizeof(ring_buffer[0]);
payload = sizeof(ring_buffer_nums) + sizeof(ring_buffer);
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
if (nla_put_u32(reply, LOGGER_ATTRIBUTE_RING_NUM, ring_buffer_nums)) {
wiphy_err(wiphy, "put skb u32 failed\n");
goto out_put_fail;
}
if (nla_put(reply, LOGGER_ATTRIBUTE_RING_STATUS, sizeof(ring_buffer), ring_buffer)) {
wiphy_err(wiphy, "put skb failed\n");
goto out_put_fail;
}
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "reply cmd error\n");
return ret;
out_put_fail:
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_logger_start_logging(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type, intval, size, i;
const struct nlattr *iter;
struct wifi_ring_buffer_status rb;
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case LOGGER_ATTRIBUTE_LOG_LEVEL:
rb.verbose_level = nla_get_u32(iter);
break;
case LOGGER_ATTRIBUTE_RING_FLAGS:
rb.flags = nla_get_u32(iter);
break;
case LOGGER_ATTRIBUTE_LOG_TIME_INTVAL:
intval = nla_get_u32(iter);
break;
case LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE:
size = nla_get_u32(iter);
break;
case LOGGER_ATTRIBUTE_RING_NAME:
strcpy(rb.name, nla_data(iter));
break;
default:
AICWFDBG(LOGERROR, "%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
ret = -EINVAL;
for (i = 0; i < sizeof(ring_buffer) / sizeof(ring_buffer[0]); i++) {
if (strcmp(rb.name, ring_buffer[i].name) == 0) {
ret = 0;
break;
}
}
/* TODO
* Add handle in the future
*/
return ret;
}
static int aicwf_vendor_logger_get_ring_data(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type, i;
const struct nlattr *iter;
struct wifi_ring_buffer_status rb;
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case LOGGER_ATTRIBUTE_RING_NAME:
strcpy(rb.name, nla_data(iter));
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
ret = -EINVAL;
for (i = 0; i < sizeof(ring_buffer) / sizeof(ring_buffer[0]); i++) {
if (strcmp(rb.name, ring_buffer[i].name) == 0) {
ret = 0;
break;
}
}
/* TODO
* Add handle in the future
*/
return ret;
}
static int aicwf_vendor_logger_get_wake_reason_stats(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret;
struct sk_buff *reply;
uint32_t payload;
payload = sizeof(wake_reason_cnt.total_cmd_event_wake);
reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
if (!reply)
return -ENOMEM;
/* TODO
* Add handle in the future
*/
if (nla_put_u32(reply, WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT, wake_reason_cnt.total_cmd_event_wake))
goto out_put_fail;
ret = cfg80211_vendor_cmd_reply(reply);
if (ret)
wiphy_err(wiphy, "reply cmd error\n");
return ret;
out_put_fail:
kfree_skb(reply);
return -EMSGSIZE;
}
static int aicwf_vendor_apf_subcmd_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
/* TODO
* Add handle in the future
*/
return 0;
}
static int aicwf_vendor_sub_cmd_set_mac(struct wiphy *wiphy, struct wireless_dev *wdev,
const void *data, int len)
{
int ret = 0, rem, type;
const struct nlattr *iter;
u8 mac[ETH_ALEN];
nla_for_each_attr(iter, data, len, rem) {
type = nla_type(iter);
switch (type) {
case WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR:
memcpy(mac, nla_data(iter), ETH_ALEN);
printk("%s, %02X:%02X:%02X:%02X:%02X:%02X\n", __func__,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
break;
default:
pr_err("%s(%d), Unknown type: %d\n", __func__, __LINE__, type);
return -EINVAL;
}
}
/* TODO
* Add handle in the future
*/
return ret;
}
#endif
static const struct nla_policy
aicwf_cfg80211_mkeep_alive_policy[MKEEP_ALIVE_ATTRIBUTE_MAX+1] = {
[0] = {.type = NLA_UNSPEC },
[MKEEP_ALIVE_ATTRIBUTE_ID] = { .type = NLA_U8 },
[MKEEP_ALIVE_ATTRIBUTE_IP_PKT] = { .type = NLA_MSECS },
[MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN] = { .type = NLA_U16 },
[MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR] = { .type = NLA_MSECS,
.len = ETH_ALEN },
[MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR] = { .type = NLA_MSECS,
.len = ETH_ALEN },
[MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC] = { .type = NLA_U32 },
};
static const struct nla_policy
aicwf_cfg80211_logger_policy[LOGGER_ATTRIBUTE_MAX + 1] = {
[0] = {.type = NLA_UNSPEC },
[LOGGER_ATTRIBUTE_DRIVER_VER] = { .type = NLA_BINARY },
[LOGGER_ATTRIBUTE_FW_VER] = { .type = NLA_BINARY },
[LOGGER_ATTRIBUTE_LOG_LEVEL] = { .type = NLA_U32 },
[LOGGER_ATTRIBUTE_RING_FLAGS] = { .type = NLA_U32 },
[LOGGER_ATTRIBUTE_LOG_TIME_INTVAL] = { .type = NLA_U32 },
[LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE] = { .type = NLA_U32 },
[LOGGER_ATTRIBUTE_RING_NAME] = { .type = NLA_STRING },
};
static const struct nla_policy
aicwf_cfg80211_subcmd_policy[GSCAN_ATTRIBUTE_MAX + 1] = {
[0] = {.type = NLA_UNSPEC },
[GSCAN_ATTRIBUTE_BAND] = { .type = NLA_U32 },
};
static const struct nla_policy
aicwf_cfg80211_andr_wifi_policy[ANDR_WIFI_ATTRIBUTE_MAX + 1] = {
[0] = {.type = NLA_UNSPEC },
[ANDR_WIFI_ATTRIBUTE_COUNTRY] = { .type = NLA_STRING },
};
static const struct nla_policy
aicwf_cfg80211_subcmd_set_mac_policy[WIFI_VENDOR_ATTR_DRIVER_MAX + 1] = {
[0] = {.type = NLA_UNSPEC },
[WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR] = { .type = NLA_MSECS, .len = ETH_ALEN },
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
static int aicwf_dump_interface(struct wiphy *wiphy,
struct wireless_dev *wdev, struct sk_buff *skb,
const void *data, int data_len,
unsigned long *storage)
{
return 0;
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
const struct wiphy_vendor_command aicwf_vendor_cmd[] = {
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_start_mkeep_alive,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_mkeep_alive_policy,
.maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_stop_mkeep_alive,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_mkeep_alive_policy,
.maxattr = MKEEP_ALIVE_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_GET_VER
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_get_ver,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = GSCAN_SUBCMD_GET_CHANNEL_LIST
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_get_channel_list,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_policy,
.maxattr = GSCAN_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = WIFI_SUBCMD_SET_COUNTRY_CODE
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_set_country_code,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_andr_wifi_policy,
.maxattr = ANDR_WIFI_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_TRIGGER_MEM_DUMP
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_trigger_memory_dump,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = WIFI_SUBCMD_GET_FEATURE_SET
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_subcmd_get_feature_set,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_GET_FEATURE
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_feature,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_GET_RING_STATUS
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_ring_status,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_START_LOGGING
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_start_logging,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_GET_RING_DATA
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_ring_data,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_logger_policy,
.maxattr = LOGGER_ATTRIBUTE_MAX
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = LOGGER_GET_WAKE_REASON_STATS
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_logger_get_wake_reason_stats,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = APF_SUBCMD_GET_CAPABILITIES
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
.doit = aicwf_vendor_apf_subcmd_get_capabilities,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = VENDOR_CMD_RAW_DATA,
#endif
},
{
{
.vendor_id = GOOGLE_OUI,
.subcmd = VENDOR_NL80211_SUBCMD_SET_MAC
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = aicwf_vendor_sub_cmd_set_mac,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_set_mac_policy,
.maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,
#endif
},
{
{
.vendor_id = BRCM_OUI,
.subcmd = VENDOR_NL80211_SUBCMD_SET_MAC
},
.flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = aicwf_vendor_sub_cmd_set_mac,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
.dumpit = aicwf_dump_interface,
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
.policy = aicwf_cfg80211_subcmd_set_mac_policy,
.maxattr = WIFI_VENDOR_ATTR_DRIVER_MAX,
#endif
},
};
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
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;
}

View File

@ -0,0 +1,346 @@
#ifndef _AIC_VENDOR_H
#define _AIC_VENDOR_H
#include <linux/types.h>
#define GOOGLE_OUI 0x001A11
#define BRCM_OUI 0x001018
typedef enum {
START_MKEEP_ALIVE,
STOP_MKEEP_ALIVE,
} GetCmdType;
typedef enum {
/* don't use 0 as a valid subcommand */
VENDOR_NL80211_SUBCMD_UNSPECIFIED,
/* define all vendor startup commands between 0x0 and 0x0FFF */
VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
/* define all GScan related commands between 0x1000 and 0x10FF */
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
/* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */
ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100,
ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF,
/* define all RTT related commands between 0x1100 and 0x11FF */
ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
/* define all Logger related commands between 0x1400 and 0x14FF */
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
/* define all wifi offload related commands between 0x1600 and 0x16FF */
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
/* define all NAN related commands between 0x1700 and 0x17FF */
ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
/* define all Android Packet Filter related commands between 0x1800 and 0x18FF */
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
/* This is reserved for future usage */
} ANDROID_VENDOR_SUB_COMMAND;
typedef enum {
WIFI_OFFLOAD_SUBCMD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
WIFI_OFFLOAD_SUBCMD_STOP_MKEEP_ALIVE,
} WIFI_OFFLOAD_SUB_COMMAND;
enum mkeep_alive_attributes {
MKEEP_ALIVE_ATTRIBUTE_ID = 0x1,
MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC,
MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST,
MKEEP_ALIVE_ATTRIBUTE_MAX = MKEEP_ALIVE_ATTRIBUTE_AFTER_LAST - 1
};
enum debug_sub_command {
LOGGER_START_LOGGING = ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START,
LOGGER_TRIGGER_MEM_DUMP,
LOGGER_GET_MEM_DUMP,
LOGGER_GET_VER,
LOGGER_GET_RING_STATUS,
LOGGER_GET_RING_DATA,
LOGGER_GET_FEATURE,
LOGGER_RESET_LOGGING,
LOGGER_TRIGGER_DRIVER_MEM_DUMP,
LOGGER_GET_DRIVER_MEM_DUMP,
LOGGER_START_PKT_FATE_MONITORING,
LOGGER_GET_TX_PKT_FATES,
LOGGER_GET_RX_PKT_FATES,
LOGGER_GET_WAKE_REASON_STATS,
LOGGER_DEBUG_GET_DUMP,
LOGGER_FILE_DUMP_DONE_IND,
LOGGER_SET_HAL_START,
LOGGER_HAL_STOP,
LOGGER_SET_HAL_PID,
};
enum logger_attributes {
LOGGER_ATTRIBUTE_INVALID = 0,
LOGGER_ATTRIBUTE_DRIVER_VER,
LOGGER_ATTRIBUTE_FW_VER,
LOGGER_ATTRIBUTE_RING_ID,
LOGGER_ATTRIBUTE_RING_NAME,
LOGGER_ATTRIBUTE_RING_FLAGS,
LOGGER_ATTRIBUTE_LOG_LEVEL,
LOGGER_ATTRIBUTE_LOG_TIME_INTVAL,
LOGGER_ATTRIBUTE_LOG_MIN_DATA_SIZE,
LOGGER_ATTRIBUTE_FW_DUMP_LEN,
LOGGER_ATTRIBUTE_FW_DUMP_DATA,
// LOGGER_ATTRIBUTE_FW_ERR_CODE,
LOGGER_ATTRIBUTE_RING_DATA,
LOGGER_ATTRIBUTE_RING_STATUS,
LOGGER_ATTRIBUTE_RING_NUM,
LOGGER_ATTRIBUTE_DRIVER_DUMP_LEN,
LOGGER_ATTRIBUTE_DRIVER_DUMP_DATA,
LOGGER_ATTRIBUTE_PKT_FATE_NUM,
LOGGER_ATTRIBUTE_PKT_FATE_DATA,
LOGGER_ATTRIBUTE_AFTER_LAST,
LOGGER_ATTRIBUTE_MAX = LOGGER_ATTRIBUTE_AFTER_LAST - 1,
};
enum wifi_sub_command {
GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */
GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */
GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */
GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */
GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */
GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */
GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */
GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */
GSCAN_SUBCMD_GET_CHANNEL_LIST, /* 0x1009 */
WIFI_SUBCMD_GET_FEATURE_SET, /* 0x100A */
WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x100B */
WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x100C */
WIFI_SUBCMD_NODFS_SET, /* 0x100D */
WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x100E */
/* Add more sub commands here */
GSCAN_SUBCMD_SET_EPNO_SSID, /* 0x100F */
WIFI_SUBCMD_SET_SSID_WHITE_LIST, /* 0x1010 */
WIFI_SUBCMD_SET_ROAM_PARAMS, /* 0x1011 */
WIFI_SUBCMD_ENABLE_LAZY_ROAM, /* 0x1012 */
WIFI_SUBCMD_SET_BSSID_PREF, /* 0x1013 */
WIFI_SUBCMD_SET_BSSID_BLACKLIST, /* 0x1014 */
GSCAN_SUBCMD_ANQPO_CONFIG, /* 0x1015 */
WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x1016 */
WIFI_SUBCMD_CONFIG_ND_OFFLOAD, /* 0x1017 */
/* Add more sub commands here */
GSCAN_SUBCMD_MAX,
APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
APF_SUBCMD_SET_FILTER,
};
enum gscan_attributes {
GSCAN_ATTRIBUTE_NUM_BUCKETS = 10,
GSCAN_ATTRIBUTE_BASE_PERIOD,
GSCAN_ATTRIBUTE_BUCKETS_BAND,
GSCAN_ATTRIBUTE_BUCKET_ID,
GSCAN_ATTRIBUTE_BUCKET_PERIOD,
GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS,
GSCAN_ATTRIBUTE_BUCKET_CHANNELS,
GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN,
GSCAN_ATTRIBUTE_REPORT_THRESHOLD,
GSCAN_ATTRIBUTE_NUM_SCANS_TO_CACHE,
GSCAN_ATTRIBUTE_BAND = GSCAN_ATTRIBUTE_BUCKETS_BAND,
GSCAN_ATTRIBUTE_ENABLE_FEATURE = 20,
GSCAN_ATTRIBUTE_SCAN_RESULTS_COMPLETE, /* indicates no more results */
GSCAN_ATTRIBUTE_FLUSH_FEATURE, /* Flush all the configs */
GSCAN_ENABLE_FULL_SCAN_RESULTS,
GSCAN_ATTRIBUTE_REPORT_EVENTS,
/* remaining reserved for additional attributes */
GSCAN_ATTRIBUTE_NUM_OF_RESULTS = 30,
GSCAN_ATTRIBUTE_FLUSH_RESULTS,
GSCAN_ATTRIBUTE_SCAN_RESULTS, /* flat array of wifi_scan_result */
GSCAN_ATTRIBUTE_SCAN_ID, /* indicates scan number */
GSCAN_ATTRIBUTE_SCAN_FLAGS, /* indicates if scan was aborted */
GSCAN_ATTRIBUTE_AP_FLAGS, /* flags on significant change event */
GSCAN_ATTRIBUTE_NUM_CHANNELS,
GSCAN_ATTRIBUTE_CHANNEL_LIST,
GSCAN_ATTRIBUTE_CH_BUCKET_BITMASK,
GSCAN_ATTRIBUTE_AFTER_LAST,
GSCAN_ATTRIBUTE_MAX = GSCAN_ATTRIBUTE_AFTER_LAST - 1,
};
enum andr_wifi_attributes {
ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET,
ANDR_WIFI_ATTRIBUTE_FEATURE_SET,
ANDR_WIFI_ATTRIBUTE_PNO_RANDOM_MAC_OUI,
ANDR_WIFI_ATTRIBUTE_NODFS_SET,
ANDR_WIFI_ATTRIBUTE_COUNTRY,
ANDR_WIFI_ATTRIBUTE_ND_OFFLOAD_VALUE,
// Add more attribute here
ANDR_WIFI_ATTRIBUTE_AFTER_LAST,
ANDR_WIFI_ATTRIBUTE_MAX = ANDR_WIFI_ATTRIBUTE_AFTER_LAST - 1,
};
enum wifi_support_feature {
/* Feature enums */
WIFI_FEATURE_INFRA = 0x0001, /* Basic infrastructure mode */
WIFI_FEATURE_INFRA_5G = 0x0002, /* Support for 5, GHz Band */
WIFI_FEATURE_HOTSPOT = 0x0004, /* Support for GAS/ANQP */
WIFI_FEATURE_P2P = 0x0008, /* Wifi-Direct */
WIFI_FEATURE_SOFT_AP = 0x0010, /* Soft AP */
WIFI_FEATURE_GSCAN = 0x0020, /* Google-Scan APIs */
WIFI_FEATURE_NAN = 0x0040, /* Neighbor Awareness Networking */
WIFI_FEATURE_D2D_RTT = 0x0080, /* Device-to-device RTT */
WIFI_FEATURE_D2AP_RTT = 0x0100, /* Device-to-AP RTT */
WIFI_FEATURE_BATCH_SCAN = 0x0200, /* Batched Scan (legacy) */
WIFI_FEATURE_PNO = 0x0400, /* Preferred network offload */
WIFI_FEATURE_ADDITIONAL_STA = 0x0800, /* Support for two STAs */
WIFI_FEATURE_TDLS = 0x1000, /* Tunnel directed link setup */
WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000, /* Support for TDLS off channel */
WIFI_FEATURE_EPR = 0x4000, /* Enhanced power reporting */
WIFI_FEATURE_AP_STA = 0x8000, /* Support for AP STA Concurrency */
WIFI_FEATURE_LINK_LAYER_STATS = 0x10000, /* Support for Linkstats */
WIFI_FEATURE_LOGGER = 0x20000, /* WiFi Logger */
WIFI_FEATURE_HAL_EPNO = 0x40000, /* WiFi PNO enhanced */
WIFI_FEATURE_RSSI_MONITOR = 0x80000, /* RSSI Monitor */
WIFI_FEATURE_MKEEP_ALIVE = 0x100000, /* WiFi mkeep_alive */
WIFI_FEATURE_CONFIG_NDO = 0x200000, /* ND offload configure */
WIFI_FEATURE_TX_TRANSMIT_POWER = 0x400000, /* Capture Tx transmit power levels */
WIFI_FEATURE_CONTROL_ROAMING = 0x800000, /* Enable/Disable firmware roaming */
WIFI_FEATURE_IE_WHITELIST = 0x1000000, /* Support Probe IE white listing */
WIFI_FEATURE_SCAN_RAND = 0x2000000, /* Support MAC & Probe Sequence Number randomization */
WIFI_FEATURE_INVALID = 0xFFFFFFFF, /* Invalid Feature */
};
enum wifi_logger_feature {
WIFI_LOGGER_MEMORY_DUMP_SUPPORTED = (1 << (0)), // Memory dump of FW
WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), // PKT status
WIFI_LOGGER_CONNECT_EVENT_SUPPORTED = (1 << (2)), // Connectivity event
WIFI_LOGGER_POWER_EVENT_SUPPORTED = (1 << (3)), // POWER of Driver
WIFI_LOGGER_WAKE_LOCK_SUPPORTED = (1 << (4)), // WAKE LOCK of Driver
WIFI_LOGGER_VERBOSE_SUPPORTED = (1 << (5)), // verbose log of FW
WIFI_LOGGER_WATCHDOG_TIMER_SUPPORTED = (1 << (6)), // monitor the health of FW
WIFI_LOGGER_DRIVER_DUMP_SUPPORTED = (1 << (7)), // dumps driver state
WIFI_LOGGER_PACKET_FATE_SUPPORTED = (1 << (8)), // tracks connection packets' fate
};
enum wake_stats_attributes {
WAKE_STAT_ATTRIBUTE_TOTAL_CMD_EVENT,
WAKE_STAT_ATTRIBUTE_CMD_EVENT_WAKE,
WAKE_STAT_ATTRIBUTE_CMD_EVENT_COUNT,
WAKE_STAT_ATTRIBUTE_CMD_COUNT_USED,
WAKE_STAT_ATTRIBUTE_TOTAL_DRIVER_FW,
WAKE_STAT_ATTRIBUTE_DRIVER_FW_WAKE,
WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT,
WAKE_STAT_ATTRIBUTE_DRIVER_FW_COUNT_USED,
WAKE_STAT_ATTRIBUTE_TOTAL_RX_DATA_WAKE,
WAKE_STAT_ATTRIBUTE_RX_UNICAST_COUNT,
WAKE_STAT_ATTRIBUTE_RX_MULTICAST_COUNT,
WAKE_STAT_ATTRIBUTE_RX_BROADCAST_COUNT,
WAKE_STAT_ATTRIBUTE_RX_ICMP_PKT,
WAKE_STAT_ATTRIBUTE_RX_ICMP6_PKT,
WAKE_STAT_ATTRIBUTE_RX_ICMP6_RA,
WAKE_STAT_ATTRIBUTE_RX_ICMP6_NA,
WAKE_STAT_ATTRIBUTE_RX_ICMP6_NS,
WAKE_STAT_ATTRIBUTE_IPV4_RX_MULTICAST_ADD_CNT,
WAKE_STAT_ATTRIBUTE_IPV6_RX_MULTICAST_ADD_CNT,
WAKE_STAT_ATTRIBUTE_OTHER__RX_MULTICAST_ADD_CNT,
WAKE_STAT_ATTRIBUTE_RX_MULTICAST_PKT_INFO,
WAKE_STAT_ATTRIBUTE_AFTER_LAST,
WAKE_STAT_ATTRIBUTE_MAX = WAKE_STAT_ATTRIBUTE_AFTER_LAST - 1,
};
enum vendor_nl80211_subcmd {
/* copied from wpa_supplicant brcm definations */
VENDOR_NL80211_SUBCMD_UNSPEC = 0,
VENDOR_NL80211_SUBCMD_SET_PMK = 4,
VENDOR_NL80211_SUBCMD_SET_MAC = 6,
VENDOR_NL80211_SCMD_ACS = 9,
VENDOR_NL80211_SCMD_MAX = 10,
};
enum nl80211_vendor_subcmd_attributes {
WIFI_VENDOR_ATTR_DRIVER_CMD = 0,
WIFI_VENDOR_ATTR_DRIVER_KEY_PMK = 1,
WIFI_VENDOR_ATTR_DRIVER_MAC_ADDR = 3,
WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST = 5,
WIFI_VENDOR_ATTR_DRIVER_MAX =
WIFI_VENDOR_ATTR_DRIVER_AFTER_LAST - 1,
};
typedef int wifi_ring_buffer_id;
struct wifi_ring_buffer_status {
u8 name[32];
u32 flags;
wifi_ring_buffer_id ring_id;
u32 ring_buffer_byte_size;
u32 verbose_level;
u32 written_bytes;
u32 read_bytes;
u32 written_records;
};
struct rx_data_cnt_details_t {
int rx_unicast_cnt; /*Total rx unicast packet which woke up host */
int rx_multicast_cnt; /*Total rx multicast packet which woke up host */
int rx_broadcast_cnt; /*Total rx broadcast packet which woke up host */
};
struct rx_wake_pkt_type_classification_t {
int icmp_pkt; /*wake icmp packet count */
int icmp6_pkt; /*wake icmp6 packet count */
int icmp6_ra; /*wake icmp6 RA packet count */
int icmp6_na; /*wake icmp6 NA packet count */
int icmp6_ns; /*wake icmp6 NS packet count */
//ToDo: Any more interesting classification to add?
};
struct rx_multicast_cnt_t{
int ipv4_rx_multicast_addr_cnt; /*Rx wake packet was ipv4 multicast */
int ipv6_rx_multicast_addr_cnt; /*Rx wake packet was ipv6 multicast */
int other_rx_multicast_addr_cnt;/*Rx wake packet was non-ipv4 and non-ipv6*/
};
struct wlan_driver_wake_reason_cnt_t {
int total_cmd_event_wake; /* Total count of cmd event wakes */
int *cmd_event_wake_cnt; /* Individual wake count array, each index a reason */
int cmd_event_wake_cnt_sz; /* Max number of cmd event wake reasons */
int cmd_event_wake_cnt_used; /* Number of cmd event wake reasons specific to the driver */
int total_driver_fw_local_wake; /* Total count of drive/fw wakes, for local reasons */
int *driver_fw_local_wake_cnt; /* Individual wake count array, each index a reason */
int driver_fw_local_wake_cnt_sz; /* Max number of local driver/fw wake reasons */
int driver_fw_local_wake_cnt_used; /* Number of local driver/fw wake reasons specific to the driver */
int total_rx_data_wake; /* total data rx packets, that woke up host */
struct rx_data_cnt_details_t rx_wake_details;
struct rx_wake_pkt_type_classification_t rx_wake_pkt_classification_info;
struct rx_multicast_cnt_t rx_multicast_wake_pkt_info;
};
typedef struct wl_mkeep_alive_pkt {
u16 version; /* Version for mkeep_alive */
u16 length; /* length of fixed parameters in the structure */
u32 period_msec; /* high bit on means immediate send */
u16 len_bytes;
u8 keep_alive_id; /* 0 - 3 for N = 4 */
u8 data[1];
} wl_mkeep_alive_pkt_t;
#endif /* _AIC_VENDOR_H */

View File

@ -0,0 +1,64 @@
#include "rwnx_main.h"
#include "rwnx_msg_tx.h"
#include "reg_access.h"
#include "aicwf_compat_8800d80.h"
#define FW_USERCONFIG_NAME_8800D80 "aic_userconfig_8800d80.txt"
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
u32** buffer, const char *filename);
void rwnx_plat_userconfig_parsing2(char *buffer, int size);
void rwnx_plat_userconfig_parsing3(char *buffer, int size);
void rwnx_release_firmware_common(u32** buffer);
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm)
{
int ret = 0;
if ((ret = rwnx_send_txpwr_lvl_v3_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_ofst2x_req(rwnx_hw))) {
return -1;
}
if (testmode == 0) {
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1;
}
}
return 0 ;
}
int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw)
{
int size;
u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800D80;
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_userconfig_parsing3((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
return 0;
}

View File

@ -0,0 +1,9 @@
#ifndef _AICWF_COMPAT_8800D80_H_
#define _AICWF_COMPAT_8800D80_H_
#include <linux/types.h>
int aicwf_set_rf_config_8800d80(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
int rwnx_plat_userconfig_load_8800d80(struct rwnx_hw *rwnx_hw);
#endif

View File

@ -0,0 +1,542 @@
#include "rwnx_main.h"
#include "rwnx_msg_tx.h"
#include "reg_access.h"
#include "aic_bsp_export.h"
#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"
#define FW_USERCONFIG_NAME_8800DW "aic_userconfig_8800dw.txt"
int rwnx_plat_bin_fw_upload_2(struct rwnx_hw *rwnx_hw, u32 fw_addr,
char *filename);
int rwnx_request_firmware_common(struct rwnx_hw *rwnx_hw,
u32** buffer, const char *filename);
void rwnx_plat_userconfig_parsing2(char *buffer, int size);
void rwnx_release_firmware_common(u32** buffer);
u32 wifi_txgain_table_24g_8800dcdw[32] =
{
0xA4B22189, //index 0
0x00007825,
0xA4B2214B, //index 1
0x00007825,
0xA4B2214F, //index 2
0x00007825,
0xA4B221D5, //index 3
0x00007825,
0xA4B221DC, //index 4
0x00007825,
0xA4B221E5, //index 5
0x00007825,
0xAC9221E5, //index 6
0x00006825,
0xAC9221EF, //index 7
0x00006825,
0xBC9221EE, //index 8
0x00006825,
0xBC9221FF, //index 9
0x00006825,
0xBC9221FF, //index 10
0x00004025,
0xB792203F, //index 11
0x00004026,
0xDC92203F, //index 12
0x00004025,
0xE692203F, //index 13
0x00004025,
0xFF92203F, //index 14
0x00004035,
0xFFFE203F, //index 15
0x00004832
};
u32 wifi_txgain_table_24g_1_8800dcdw[32] =
{
0x096E2011, //index 0
0x00004001,
0x096E2015, //index 1
0x00004001,
0x096E201B, //index 2
0x00004001,
0x116E2018, //index 3
0x00004001,
0x116E201E, //index 4
0x00004001,
0x116E2023, //index 5
0x00004001,
0x196E2021, //index 6
0x00004001,
0x196E202B, //index 7
0x00004001,
0x216E202B, //index 8
0x00004001,
0x236E2027, //index 9
0x00004001,
0x236E2031, //index 10
0x00004001,
0x246E2039, //index 11
0x00004001,
0x26922039, //index 12
0x00004001,
0x2E92203F, //index 13
0x00004001,
0x3692203F, //index 14
0x00004001,
0x3FF2203F, //index 15
0x00004001,
};
u32 wifi_txgain_table_24g_8800dcdw_h[32] =
{
0xA55629C9, //index 0
0x00005825,
0xAE5629C9, //index 1
0x00005825,
0xAD5629CD, //index 2
0x00005825,
0xAD5629D1, //index 3
0x00005825,
0xAD5629D7, //index 4
0x00005825,
0xAD5629DE, //index 5
0x00005825,
0xAD5629E6, //index 6
0x00005825,
0xBD5629E6, //index 7
0x00005825,
0xBD5629F0, //index 8
0x00005825,
0xCD5629F0, //index 9
0x00005825,
0xE55629F0, //index 10
0x00005825,
0xE55629FF, //index 11
0x00005825,
0xE55629FF, //index 12
0x00002825,
0xE75629FF, //index 13
0x00002825,
0xFF5629FF, //index 14
0x00001825,
0xFF5628FF, //index 15
0x00001025,
};
u32 wifi_txgain_table_24g_1_8800dcdw_h[32] =
{
0x941A2048, //index 0
0x00001825,
0x961A2048, //index 1
0x00001825,
0x9D1A2048, //index 2
0x00001825,
0x9A1A204F, //index 3
0x00001825,
0x961A204F, //index 4
0x00001825,
0x9A1A2057, //index 5
0x00001825,
0x9C1A2057, //index 6
0x00001825,
0xA31A205B, //index 7
0x00001825,
0xAB1A205B, //index 8
0x00001825,
0xAD1A205B, //index 9
0x00001825,
0xA71A2064, //index 10
0x00001825,
0xAD1A2070, //index 11
0x00001825,
0xAD72207F, //index 12
0x00001825,
0xBCAE207F, //index 13
0x00001825,
0xBFB2207F, //index 14
0x00001825,
0xD73A207F, //index 15
0x00001825,
};
u32 wifi_rxgain_table_24g_20m_8800dcdw[64] = {
0x82f282d1,//index 0
0x9591a324,
0x80808419,
0x000000f0,
0x42f282d1,//index 1
0x95923524,
0x80808419,
0x000000f0,
0x22f282d1,//index 2
0x9592c724,
0x80808419,
0x000000f0,
0x02f282d1,//index 3
0x9591a324,
0x80808419,
0x000000f0,
0x06f282d1,//index 4
0x9591a324,
0x80808419,
0x000000f0,
0x0ef29ad1,//index 5
0x9591a324,
0x80808419,
0x000000f0,
0x0ef29ad3,//index 6
0x95923524,
0x80808419,
0x000000f0,
0x0ef29ad7,//index 7
0x9595a324,
0x80808419,
0x000000f0,
0x02f282d2,//index 8
0x95951124,
0x80808419,
0x000000f0,
0x02f282f4,//index 9
0x95951124,
0x80808419,
0x000000f0,
0x02f282e6,//index 10
0x9595a324,
0x80808419,
0x000000f0,
0x02f282e6,//index 11
0x9599a324,
0x80808419,
0x000000f0,
0x02f282e6,//index 12
0x959da324,
0x80808419,
0x000000f0,
0x02f282e6,//index 13
0x959f5924,
0x80808419,
0x000000f0,
0x06f282e6,//index 14
0x959f5924,
0x80808419,
0x000000f0,
0x0ef29ae6,//index 15
0x959f5924, //loft [35:34]=3
0x80808419,
0x000000f0
};
u32 wifi_rxgain_table_24g_40m_8800dcdw[64] = {
0x83428151,//index 0
0x9631a328,
0x80808419,
0x000000f0,
0x43428151,//index 1
0x96323528,
0x80808419,
0x000000f0,
0x23428151,//index 2
0x9632c728,
0x80808419,
0x000000f0,
0x03428151,//index 3
0x9631a328,
0x80808419,
0x000000f0,
0x07429951,//index 4
0x9631a328,
0x80808419,
0x000000f0,
0x0f42d151,//index 5
0x9631a328,
0x80808419,
0x000000f0,
0x0f42d153,//index 6
0x96323528,
0x80808419,
0x000000f0,
0x0f42d157,//index 7
0x9635a328,
0x80808419,
0x000000f0,
0x03428152,//index 8
0x96351128,
0x80808419,
0x000000f0,
0x03428174,//index 9
0x96351128,
0x80808419,
0x000000f0,
0x03428166,//index 10
0x9635a328,
0x80808419,
0x000000f0,
0x03428166,//index 11
0x9639a328,
0x80808419,
0x000000f0,
0x03428166,//index 12
0x963da328,
0x80808419,
0x000000f0,
0x03428166,//index 13
0x963f5928,
0x80808419,
0x000000f0,
0x07429966,//index 14
0x963f5928,
0x80808419,
0x000000f0,
0x0f42d166,//index 15
0x963f5928,
0x80808419,
0x000000f0
};
#define RAM_LMAC_FW_ADDR 0x00150000
#ifdef CONFIG_DPD
#if (defined(CONFIG_DPD) && !defined(CONFIG_FORCE_DPD_CALIB))
extern int is_file_exist(char* name);
#endif
extern rf_misc_ram_lite_t dpd_res;
int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t ram_base_addr, ram_byte_cnt;
AICWFDBG(LOGINFO, "bit_mask[1]=%x\n", dpd_res->bit_mask[1]);
if (dpd_res->bit_mask[1] == 0) {
AICWFDBG(LOGERROR, "void dpd_res, bypass it.\n");
return 0;
}
if (testmode == 1) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
if ((ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm))) {
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
return ret;
}
misc_ram_addr = cfm.memdata;
AICWFDBG(LOGINFO, "misc_ram_addr: %x\n", misc_ram_addr);
/* Copy dpd_res on the Embedded side */
// bit_mask
AICWFDBG(LOGINFO, "bit_mask[0]=%x\n", dpd_res->bit_mask[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, bit_mask);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, bit_mask) + MEMBER_SIZE(rf_misc_ram_t, reserved);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->bit_mask[0]);
if (ret) {
AICWFDBG(LOGERROR, "bit_mask wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// dpd_high
AICWFDBG(LOGINFO, "dpd_high[0]=%x\n", dpd_res->dpd_high[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, dpd_high);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, dpd_high);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->dpd_high[0]);
if (ret) {
AICWFDBG(LOGERROR, "dpd_high wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
// loft_res
AICWFDBG(LOGINFO, "loft_res[0]=%x\n", dpd_res->loft_res[0]);
ram_base_addr = misc_ram_addr + offsetof(rf_misc_ram_t, loft_res);
ram_byte_cnt = MEMBER_SIZE(rf_misc_ram_t, loft_res);
ret = rwnx_send_dbg_mem_block_write_req(rwnx_hw, ram_base_addr, ram_byte_cnt, (u32 *)&dpd_res->loft_res[0]);
if (ret) {
AICWFDBG(LOGERROR, "loft_res wr fail: %x, ret:%d\r\n", ram_base_addr, ret);
return ret;
}
return ret;
}
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res)
{
int ret = 0;
int size;
u32 *dst=NULL;
char *filename = FW_DPDRESULT_NAME_8800DC;
AICWFDBG(LOGINFO, "dpd_res file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of dpd_res file\n");
dst = NULL;
return -1;
}
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d, dst[0]=%x\n", filename, size, dst[0]);
memcpy((u8 *)dpd_res, (u8 *)dst, sizeof(rf_misc_ram_lite_t));
if (dst) {
rwnx_release_firmware_common(&dst);
}
return ret;
}
#endif
#endif
int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw)
{
int ret = 0;
uint32_t cfg_base = 0x10164;
struct dbg_mem_read_cfm cfm;
uint32_t misc_ram_addr;
uint32_t misc_ram_size = 12;
int i;
if (testmode == 1) {
cfg_base = RAM_LMAC_FW_ADDR + 0x0164;
}
// init misc ram
printk("%s\n", __func__);
ret = rwnx_send_dbg_mem_read_req(rwnx_hw, cfg_base + 0x14, &cfm);
if (ret) {
AICWFDBG(LOGERROR, "rf misc ram[0x%x] rd fail: %d\n", cfg_base + 0x14, ret);
return ret;
}
misc_ram_addr = cfm.memdata;
AICWFDBG(LOGERROR, "misc_ram_addr=%x\n", misc_ram_addr);
for (i = 0; i < (misc_ram_size / 4); i++) {
ret = rwnx_send_dbg_mem_write_req(rwnx_hw, misc_ram_addr + i * 4, 0);
if (ret) {
AICWFDBG(LOGERROR, "rf misc ram[0x%x] wr fail: %d\n", misc_ram_addr + i * 4, ret);
return ret;
}
}
return ret;
}
int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm){
int ret = 0;
if ((ret = rwnx_send_txpwr_lvl_req(rwnx_hw))) {
return -1;
}
if ((ret = rwnx_send_txpwr_ofst_req(rwnx_hw))) {
return -1;
}
if (testmode == 0) {
if (IS_CHIP_ID_H()) {
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw_h, 128)))
return -1;
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw_h, 128)))
return -1;
} else {
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 1, (u8_l *)wifi_txgain_table_24g_8800dcdw, 128)))
return -1;
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 16, 1, (u8_l *)wifi_txgain_table_24g_1_8800dcdw, 128)))
return -1;
}
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 0, 0, (u8_l *)wifi_rxgain_table_24g_20m_8800dcdw, 256)))
return -1;
if ((ret = rwnx_send_rf_config_req(rwnx_hw, 32, 0, (u8_l *)wifi_rxgain_table_24g_40m_8800dcdw, 256)))
return -1;
if ((ret = rwnx_send_rf_calib_req(rwnx_hw, cfm))) {
return -1;
}
} else if (testmode == 1) {
if (chip_sub_id >= 1) {
#ifdef CONFIG_DPD
#ifndef CONFIG_FORCE_DPD_CALIB
if (is_file_exist(FW_DPDRESULT_NAME_8800DC) == 1) {
AICWFDBG(LOGINFO, "%s load dpd bin\n", __func__);
ret = aicwf_fdrv_dpd_result_load_8800dc(rwnx_hw, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "load dpd bin fail: %d\n", ret);
return ret;
}
}
#endif
if (dpd_res.bit_mask[1]) {
ret = aicwf_fdrv_dpd_result_apply_8800dc(rwnx_hw, &dpd_res);
if (ret) {
AICWFDBG(LOGINFO, "apply dpd bin fail: %d\n", ret);
return ret;
}
}
#else
{
ret = aicwf_fdrv_misc_ram_init_8800dc(rwnx_hw);
if (ret) {
AICWFDBG(LOGINFO, "misc ram init fail: %d\n", ret);
return ret;
}
}
#endif
ret = rwnx_send_rf_calib_req(rwnx_hw, cfm);
if (ret) {
AICWFDBG(LOGINFO, "rf calib req fail: %d\n", ret);
return ret;
}
}
}
return 0 ;
}
int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw){
int size;
u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800DC;
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_userconfig_parsing2((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
return 0;
}
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw){
int size;
u32 *dst=NULL;
char *filename = FW_USERCONFIG_NAME_8800DC;
AICWFDBG(LOGINFO, "userconfig file path:%s \r\n", filename);
/* load file */
size = rwnx_request_firmware_common(rwnx_hw, &dst, filename);
if (size <= 0) {
AICWFDBG(LOGERROR, "wrong size of firmware file\n");
dst = NULL;
return 0;
}
/* Copy the file on the Embedded side */
AICWFDBG(LOGINFO, "### Load file done: %s, size=%d\n", filename, size);
rwnx_plat_userconfig_parsing2((char *)dst, size);
rwnx_release_firmware_common(&dst);
AICWFDBG(LOGINFO, "userconfig download complete\n\n");
return 0;
}

View File

@ -0,0 +1,15 @@
#include <linux/types.h>
#include "aic_bsp_export.h"
#ifdef CONFIG_DPD
int aicwf_fdrv_dpd_result_apply_8800dc(struct rwnx_hw * rwnx_hw, rf_misc_ram_lite_t * dpd_res);
#ifndef CONFIG_FORCE_DPD_CALIB
int aicwf_fdrv_dpd_result_load_8800dc(struct rwnx_hw *rwnx_hw, rf_misc_ram_lite_t *dpd_res);
#endif
#endif
int aicwf_fdrv_misc_ram_init_8800dc(struct rwnx_hw *rwnx_hw);
int aicwf_set_rf_config_8800dc(struct rwnx_hw *rwnx_hw, struct mm_set_rf_calib_cfm *cfm);
int rwnx_plat_userconfig_load_8800dc(struct rwnx_hw *rwnx_hw);
int rwnx_plat_userconfig_load_8800dw(struct rwnx_hw *rwnx_hw);

View File

@ -0,0 +1,56 @@
#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
#define LOGIRQ 0x0020
#define LOGSDPWRC 0x0040
#define LOGWAKELOCK 0x0080
#define LOGRXPOLL 0x0100
extern int aicwf_dbg_level;
void rwnx_data_dump(char* tag, void* data, unsigned long len);
#define AICWF_LOG "AICWFDBG("
#define AICWFDBG(level, args, arg...) \
do { \
if (aicwf_dbg_level & level) { \
printk(AICWF_LOG#level")\t" args, ##arg); \
} \
} while (0)
#define RWNX_DBG(fmt, ...) \
do { \
if (aicwf_dbg_level & LOGTRACE) { \
printk(AICWF_LOG"LOGTRACE)\t"fmt , ##__VA_ARGS__); \
} \
} while (0)
#if 0
#define RWNX_DBG(fmt, ...) \
do { \
if (aicwf_dbg_level & LOGTRACE) { \
printk(AICWF_LOG"LOGTRACE"")\t" fmt, ##__VA_ARGS__); \
} \
} while (0)
#define AICWFDBG(args, level) \
do { \
if (aicwf_dbg_level & level) { \
printk(AICWF_LOG"(%s)\t" ,#level); \
printf args; \
} \
} while (0)
#endif

View File

@ -0,0 +1,97 @@
#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include "aicwf_rx_prealloc.h"
#ifdef CONFIG_PREALLOC_RX_SKB
struct aicwf_rx_buff_list aic_rx_buff_list;
int aic_rxbuff_num_max = 30;
int aic_rxbuff_size = (64 * 512);
struct rx_buff *aicwf_prealloc_rxbuff_alloc(spinlock_t *lock)
{
unsigned long flags;
struct rx_buff *rxbuff = NULL;
spin_lock_irqsave(lock, flags);
if (list_empty(&aic_rx_buff_list.rxbuff_list)) {
spin_unlock_irqrestore(lock, flags);
printk("%s %d, rxbuff list is empty\n", __func__, __LINE__);
return NULL;
} else {
rxbuff = list_first_entry(&aic_rx_buff_list.rxbuff_list,
struct rx_buff, queue);
list_del_init(&rxbuff->queue);
atomic_dec(&aic_rx_buff_list.rxbuff_list_len);
}
spin_unlock_irqrestore(lock, flags);
//printk("len:%d\n", aic_rx_buff_list.rxbuff_list_len);
memset(rxbuff->data, 0, aic_rxbuff_size);
rxbuff->len = 0;
rxbuff->start = NULL;
rxbuff->read = NULL;
rxbuff->end = NULL;
return rxbuff;
}
void aicwf_prealloc_rxbuff_free(struct rx_buff *rxbuff, spinlock_t *lock)
{
unsigned long flags;
spin_lock_irqsave(lock, flags);
list_add_tail(&rxbuff->queue, &aic_rx_buff_list.rxbuff_list);
atomic_inc(&aic_rx_buff_list.rxbuff_list_len);
spin_unlock_irqrestore(lock, flags);
}
int aicwf_prealloc_init()
{
struct rx_buff *rxbuff;
int i = 0;
printk("%s enter\n", __func__);
INIT_LIST_HEAD(&aic_rx_buff_list.rxbuff_list);
for (i = 0 ; i < aic_rxbuff_num_max ; i++) {
rxbuff = kzalloc(sizeof(struct rx_buff), GFP_KERNEL);
if (rxbuff) {
rxbuff->data = kzalloc(aic_rxbuff_size, GFP_KERNEL);
if (rxbuff->data == NULL) {
printk("failed to alloc rxbuff data\n");
kfree(rxbuff);
continue;
}
rxbuff->len = 0;
rxbuff->start = NULL;
rxbuff->read = NULL;
rxbuff->end = NULL;
list_add_tail(&rxbuff->queue, &aic_rx_buff_list.rxbuff_list);
atomic_inc(&aic_rx_buff_list.rxbuff_list_len);
}
}
printk("pre alloc rxbuff list len: %d\n", (int)atomic_read(&aic_rx_buff_list.rxbuff_list_len));
return 0;
}
void aicwf_prealloc_exit()
{
struct rx_buff *rxbuff;
struct rx_buff *pos;
printk("%s enter\n", __func__);
printk("free pre alloc rxbuff list %d\n", (int)atomic_read(&aic_rx_buff_list.rxbuff_list_len));
list_for_each_entry_safe(rxbuff, pos, &aic_rx_buff_list.rxbuff_list, queue) {
list_del_init(&rxbuff->queue);
kfree(rxbuff->data);
kfree(rxbuff);
}
}
#endif

View File

@ -0,0 +1,24 @@
#ifndef _AICWF_RX_PREALLOC_H_
#define _AICWF_RX_PREALLOC_H_
#ifdef CONFIG_PREALLOC_RX_SKB
struct rx_buff {
struct list_head queue;
unsigned char *data;
u32 len;
uint8_t *start;
uint8_t *end;
uint8_t *read;
};
struct aicwf_rx_buff_list {
struct list_head rxbuff_list;
atomic_t rxbuff_list_len;
};
struct rx_buff *aicwf_prealloc_rxbuff_alloc(spinlock_t *lock);
void aicwf_prealloc_rxbuff_free(struct rx_buff *rxbuff, spinlock_t *lock);
int aicwf_prealloc_init(void);
void aicwf_prealloc_exit(void);
#endif
#endif /* _AICWF_RX_PREALLOC_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
/**
* 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 "rwnx_cmds.h"
#include "aicwf_rx_prealloc.h"
#define AICWF_SDIO_NAME "aicwf_sdio"
#define SDIOWIFI_FUNC_BLOCKSIZE 512
#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
#define DATA_FLOW_CTRL_THRESH 2
typedef enum {
SDIO_TYPE_DATA = 0X00,
SDIO_TYPE_CFG = 0X10,
SDIO_TYPE_CFG_CMD_RSP = 0X11,
SDIO_TYPE_CFG_DATA_CFM = 0X12,
SDIO_TYPE_CFG_PRINT = 0X13
} sdio_type;
/* SDIO Device ID */
#define SDIO_VENDOR_ID_AIC8801 0x5449
#define SDIO_VENDOR_ID_AIC8800DC 0xc8a1
#define SDIO_VENDOR_ID_AIC8800D80 0xc8a1
#define SDIO_DEVICE_ID_AIC8801 0x0145
#define SDIO_DEVICE_ID_AIC8800DC 0xc08d
#define SDIO_DEVICE_ID_AIC8800D80 0x0082
enum AICWF_IC{
PRODUCT_ID_AIC8801 = 0,
PRODUCT_ID_AIC8800DC,
PRODUCT_ID_AIC8800DW,
PRODUCT_ID_AIC8800D80
};
struct rwnx_hw;
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_hw *rwnx_hw;
struct sdio_func *func;
struct device *dev;
struct aicwf_bus *bus_if;
struct rwnx_cmd_mgr cmd_mgr;
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;
spinlock_t wslock;//AIDEN test
bool oob_enable;
atomic_t is_bus_suspend;
};
extern struct aicwf_rx_buff_list aic_rx_buff_list;
int aicwf_sdio_writeb(struct aic_sdio_dev *sdiodev, uint regaddr, u8 val);
void aicwf_sdio_hal_irqhandler(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_flow_ctrl_msg(struct aic_sdio_dev *sdiodev);
#ifdef CONFIG_PREALLOC_RX_SKB
int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct rx_buff *rxbbuf, u32 size);
#else
int aicwf_sdio_recv_pkt(struct aic_sdio_dev *sdiodev, struct sk_buff *skbbuf, u32 size);
#endif
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 aicwf_sdio_exit(void);
void aicwf_sdio_register(void);
int aicwf_sdio_txpkt(struct aic_sdio_dev *sdiodev, struct sk_buff *pkt);
int sdio_bustx_thread(void *data);
int sdio_busrx_thread(void *data);
#ifdef CONFIG_OOB
//new oob feature
int sdio_busirq_thread(void *data);
#endif //CONFIG_OOB
int aicwf_sdio_aggr(struct aicwf_tx_priv *tx_priv, struct sk_buff *pkt);
int aicwf_sdio_send(struct aicwf_tx_priv *tx_priv, u8 txnow);
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);
extern void aicwf_hostif_fail(void);
#ifdef CONFIG_PLATFORM_AMLOGIC
extern void extern_wifi_set_enable(int is_on);
extern void sdio_reinit(void);
#endif /*CONFIG_PLATFORM_AMLOGIC*/
uint8_t crc8_ponl_107(uint8_t *p_buffer, uint16_t cal_size);
#endif /* AICWF_SDIO_SUPPORT */
#endif /*_AICWF_SDMMC_H_*/

View File

@ -0,0 +1,633 @@
#include"aicwf_tcp_ack.h"
//#include"rwnx_tx.h"
//#include "aicwf_tcp_ack.h"
#include"rwnx_defs.h"
extern int intf_tx(struct rwnx_hw *priv,struct msg_buf *msg);
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg)
{
//printk("%s \n",__func__);
int len=sizeof(struct msg_buf) ;
msg = kzalloc(len , GFP_KERNEL);
if(!msg)
printk("%s: alloc failed \n", __func__);
memset(msg,0,len);
return msg;
}
void intf_tcp_drop_msg(struct rwnx_hw *priv,
struct msg_buf *msg)
{
//printk("%s \n",__func__);
if (msg->skb)
dev_kfree_skb_any(msg->skb);
kfree(msg);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
void tcp_ack_timeout(unsigned long data)
#else
void tcp_ack_timeout(struct timer_list *t)
#endif
{
//printk("%s \n",__func__);
struct tcp_ack_info *ack_info;
struct msg_buf *msg;
struct tcp_ack_manage *ack_m = NULL;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
ack_info = (struct tcp_ack_info *)data;
#else
ack_info = container_of(t,struct tcp_ack_info,timer);
#endif
ack_m = container_of(ack_info, struct tcp_ack_manage,
ack_info[ack_info->ack_info_num]);
write_seqlock_bh(&ack_info->seqlock);
msg = ack_info->msgbuf;
if (ack_info->busy && msg && !ack_info->in_send_msg) {
ack_info->msgbuf = NULL;
ack_info->drop_cnt = 0;
ack_info->in_send_msg = msg;
write_sequnlock_bh(&ack_info->seqlock);
intf_tx(ack_m->priv, msg);//send skb
//ack_info->in_send_msg = NULL;//add by dwx
//write_sequnlock_bh(&ack_info->seqlock);
//intf_tx(ack_m->priv, msg);
return;
}
write_sequnlock_bh(&ack_info->seqlock);
}
void tcp_ack_init(struct rwnx_hw *priv)
{
int i;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
printk("%s \n",__func__);
memset(ack_m, 0, sizeof(struct tcp_ack_manage));
ack_m->priv = priv;
spin_lock_init(&ack_m->lock);
atomic_set(&ack_m->max_drop_cnt, TCP_ACK_DROP_CNT);
ack_m->last_time = jiffies;
ack_m->timeout = msecs_to_jiffies(ACK_OLD_TIME);
for (i = 0; i < TCP_ACK_NUM; i++) {
ack_info = &ack_m->ack_info[i];
ack_info->ack_info_num = i;
seqlock_init(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack_info->timeout = msecs_to_jiffies(ACK_OLD_TIME);
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
setup_timer(&ack_info->timer, tcp_ack_timeout,
(unsigned long)ack_info);
#else
timer_setup(&ack_info->timer,tcp_ack_timeout,0);
#endif
}
atomic_set(&ack_m->enable, 1);
ack_m->ack_winsize = MIN_WIN;
}
void tcp_ack_deinit(struct rwnx_hw *priv)
{
int i;
struct tcp_ack_manage *ack_m = &priv->ack_m;
struct msg_buf *drop_msg = NULL;
printk("%s \n",__func__);
atomic_set(&ack_m->enable, 0);
for (i = 0; i < TCP_ACK_NUM; i++) {
drop_msg = NULL;
write_seqlock_bh(&ack_m->ack_info[i].seqlock);
del_timer(&ack_m->ack_info[i].timer);
drop_msg = ack_m->ack_info[i].msgbuf;
ack_m->ack_info[i].msgbuf = NULL;
write_sequnlock_bh(&ack_m->ack_info[i].seqlock);
if (drop_msg)
intf_tcp_drop_msg(priv, drop_msg);//drop skb
}
}
int tcp_check_quick_ack(unsigned char *buf,
struct tcp_ack_msg *msg)
{
int ip_hdr_len;
unsigned char *temp;
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct tcphdr *tcphdr;
ethhdr = (struct ethhdr *)buf;
if (ethhdr->h_proto != htons(ETH_P_IP))
return 0;
iphdr = (struct iphdr *)(ethhdr + 1);
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
return 0;
ip_hdr_len = iphdr->ihl * 4;
temp = (unsigned char *)(iphdr) + ip_hdr_len;
tcphdr = (struct tcphdr *)temp;
/* TCP_FLAG_ACK */
if (!(temp[13] & 0x10))
return 0;
if (temp[13] & 0x8) {
msg->saddr = iphdr->daddr;
msg->daddr = iphdr->saddr;
msg->source = tcphdr->dest;
msg->dest = tcphdr->source;
msg->seq = ntohl(tcphdr->seq);
return 1;
}
return 0;
}
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len,
unsigned short *win_scale)
{
//printk("%s \n",__func__);
int drop = 1;
int len = tcphdr->doff * 4;
unsigned char *ptr;
if(tcp_tot_len > len) {
drop = 0;
} else {
len -= sizeof(struct tcphdr);
ptr = (unsigned char *)(tcphdr + 1);
while ((len > 0) && drop) {
int opcode = *ptr++;
int opsize;
switch (opcode) {
case TCPOPT_EOL:
break;
case TCPOPT_NOP:
len--;
continue;
default:
opsize = *ptr++;
if (opsize < 2)
break;
if (opsize > len)
break;
switch (opcode) {
/* TODO: Add other ignore opt */
case TCPOPT_TIMESTAMP:
break;
case TCPOPT_WINDOW:
if (*ptr < 15)
*win_scale = (1 << (*ptr));
printk("%d\n",*win_scale);
break;
default:
drop = 2;
}
ptr += opsize - 2;
len -= opsize;
}
}
}
return drop;
}
/* flag:0 for not tcp ack
* 1 for ack which can be drop
* 2 for other ack whith more info
*/
int tcp_check_ack(unsigned char *buf,
struct tcp_ack_msg *msg,
unsigned short *win_scale)
{
int ret;
int ip_hdr_len;
int tcp_tot_len;
unsigned char *temp;
struct ethhdr *ethhdr;
struct iphdr *iphdr;
struct tcphdr *tcphdr;
ethhdr =(struct ethhdr *)buf;
if (ethhdr->h_proto != htons(ETH_P_IP))
return 0;
iphdr = (struct iphdr *)(ethhdr + 1);
if (iphdr->version != 4 || iphdr->protocol != IPPROTO_TCP)
return 0;
ip_hdr_len = iphdr->ihl * 4;
temp = (unsigned char *)(iphdr) + ip_hdr_len;
tcphdr = (struct tcphdr *)temp;
/* TCP_FLAG_ACK */
if (!(temp[13] & 0x10))
return 0;
tcp_tot_len = ntohs(iphdr->tot_len) - ip_hdr_len;// tcp total len
ret = is_drop_tcp_ack(tcphdr, tcp_tot_len, win_scale);
//printk("is drop:%d \n",ret);
if (ret > 0) {
msg->saddr = iphdr->saddr;
msg->daddr = iphdr->daddr;
msg->source = tcphdr->source;
msg->dest = tcphdr->dest;
msg->seq = ntohl(tcphdr->ack_seq);
msg->win = ntohs(tcphdr->window);
}
return ret;
}
/* return val: -1 for not match, others for match */
int tcp_ack_match(struct tcp_ack_manage *ack_m,
struct tcp_ack_msg *ack_msg)
{
int i, ret = -1;
unsigned start;
struct tcp_ack_info *ack_info;
struct tcp_ack_msg *ack;
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
ack_info = &ack_m->ack_info[i];
do {
start = read_seqbegin(&ack_info->seqlock);
ret = -1;
ack = &ack_info->ack_msg;
if (ack_info->busy &&
ack->dest == ack_msg->dest &&
ack->source == ack_msg->source &&
ack->saddr == ack_msg->saddr &&
ack->daddr == ack_msg->daddr)
ret = i;
} while(read_seqretry(&ack_info->seqlock, start));
}
return ret;
}
void tcp_ack_update(struct tcp_ack_manage *ack_m)
{
int i;
struct tcp_ack_info *ack_info;
if (time_after(jiffies, ack_m->last_time + ack_m->timeout)) {
spin_lock_bh(&ack_m->lock);
ack_m->last_time = jiffies;
for (i = TCP_ACK_NUM - 1; i >= 0; i--) {
ack_info = &ack_m->ack_info[i];
write_seqlock_bh(&ack_info->seqlock);
if (ack_info->busy &&
time_after(jiffies, ack_info->last_time +
ack_info->timeout)) {
ack_m->free_index = i;
ack_m->max_num--;
ack_info->busy = 0;
}
write_sequnlock_bh(&ack_info->seqlock);
}
spin_unlock_bh(&ack_m->lock);
}
}
/* return val: -1 for no index, others for index */
int tcp_ack_alloc_index(struct tcp_ack_manage *ack_m)
{
int i, ret = -1;
struct tcp_ack_info *ack_info;
unsigned start;
spin_lock_bh(&ack_m->lock);
if (ack_m->max_num == TCP_ACK_NUM) {
spin_unlock_bh(&ack_m->lock);
return -1;
}
if (ack_m->free_index >= 0) {
i = ack_m->free_index;
ack_m->free_index = -1;
ack_m->max_num++;
spin_unlock_bh(&ack_m->lock);
return i;
}
for (i = 0; ((ret < 0) && (i < TCP_ACK_NUM)); i++) {
ack_info = &ack_m->ack_info[i];
do {
start = read_seqbegin(&ack_info->seqlock);
ret = -1;
if (!ack_info->busy) {
ack_m->free_index = -1;
ack_m->max_num++;
ret = i;
}
} while(read_seqretry(&ack_info->seqlock, start));
}
spin_unlock_bh(&ack_m->lock);
return ret;
}
/* return val: 0 for not handle tx, 1 for handle tx */
int tcp_ack_handle(struct msg_buf *new_msgbuf,
struct tcp_ack_manage *ack_m,
struct tcp_ack_info *ack_info,
struct tcp_ack_msg *ack_msg,
int type)
{
int quick_ack = 0;
struct tcp_ack_msg *ack;
int ret = 0;
struct msg_buf *drop_msg = NULL;
//printk("%s %d",__func__,type);
write_seqlock_bh(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack = &ack_info->ack_msg;
if (type == 2) {
if (U32_BEFORE(ack->seq, ack_msg->seq)) {
ack->seq = ack_msg->seq;
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq,
ack_info->psh_seq)) {
ack_info->psh_flag = 0;
}
if (ack_info->msgbuf) {
//printk("%lx \n",ack_info->msgbuf);
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
del_timer(&ack_info->timer);
}else{
//printk("msgbuf is NULL \n");
}
ack_info->in_send_msg = NULL;
ack_info->drop_cnt = atomic_read(&ack_m->max_drop_cnt);
} else {
printk("%s before abnormal ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
} else if (U32_BEFORE(ack->seq, ack_msg->seq)) {
if (ack_info->msgbuf) {
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
}
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
ack_info->psh_flag = 0;
quick_ack = 1;
} else {
ack_info->drop_cnt++;
}
ack->seq = ack_msg->seq;
if (quick_ack || (!ack_info->in_send_msg &&
(ack_info->drop_cnt >=
atomic_read(&ack_m->max_drop_cnt)))) {
ack_info->drop_cnt = 0;
ack_info->in_send_msg = new_msgbuf;
del_timer(&ack_info->timer);
} else {
ret = 1;
ack_info->msgbuf = new_msgbuf;
if (!timer_pending(&ack_info->timer))
mod_timer(&ack_info->timer,
(jiffies + msecs_to_jiffies(5)));
}
} else {
printk("%s before ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
write_sequnlock_bh(&ack_info->seqlock);
if (drop_msg)
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
return ret;
}
int tcp_ack_handle_new(struct msg_buf *new_msgbuf,
struct tcp_ack_manage *ack_m,
struct tcp_ack_info *ack_info,
struct tcp_ack_msg *ack_msg,
int type)
{
int quick_ack = 0;
struct tcp_ack_msg *ack;
int ret = 0;
struct msg_buf *drop_msg = NULL;
struct msg_buf * send_msg = NULL;
//printk("",);
write_seqlock_bh(&ack_info->seqlock);
ack_info->last_time = jiffies;
ack = &ack_info->ack_msg;
if(U32_BEFORE(ack->seq, ack_msg->seq)){
if (ack_info->msgbuf) {
drop_msg = ack_info->msgbuf;
ack_info->msgbuf = NULL;
//ack_info->drop_cnt++;
}
if (ack_info->psh_flag &&
!U32_BEFORE(ack_msg->seq, ack_info->psh_seq)) {
ack_info->psh_flag = 0;
quick_ack = 1;
} else {
ack_info->drop_cnt++;
}
ack->seq = ack_msg->seq;
if(quick_ack || (!ack_info->in_send_msg &&
(ack_info->drop_cnt >=
atomic_read(&ack_m->max_drop_cnt)))){
ack_info->drop_cnt = 0;
send_msg = new_msgbuf;
ack_info->in_send_msg = send_msg;
del_timer(&ack_info->timer);
}else{
ret = 1;
ack_info->msgbuf = new_msgbuf;
if (!timer_pending(&ack_info->timer))
mod_timer(&ack_info->timer,
(jiffies + msecs_to_jiffies(5)));
}
//ret = 1;
}else {
printk("%s before ack: %d, %d\n",
__func__, ack->seq, ack_msg->seq);
drop_msg = new_msgbuf;
ret = 1;
}
/*if(send_msg){
intf_tx(ack_m->priv,send_msg);
ack_info->in_send_msg=NULL;
}*/
//ack_info->in_send_msg=NULL;
write_sequnlock_bh(&ack_info->seqlock);
/*if(send_msg){
intf_tx(ack_m->priv,send_msg);
//ack_info->in_send_msg=NULL;
}*/
if (drop_msg)
intf_tcp_drop_msg(ack_m->priv, drop_msg);// drop skb
return ret;
}
void filter_rx_tcp_ack(struct rwnx_hw *priv,
unsigned char *buf, unsigned plen)
{
int index;
struct tcp_ack_msg ack_msg;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
if (!atomic_read(&ack_m->enable))
return;
if ((plen > MAX_TCP_ACK) ||
!tcp_check_quick_ack(buf, &ack_msg))
return;
index = tcp_ack_match(ack_m, &ack_msg);
if (index >= 0) {
ack_info = ack_m->ack_info + index;
write_seqlock_bh(&ack_info->seqlock);
ack_info->psh_flag = 1;
ack_info->psh_seq = ack_msg.seq;
write_sequnlock_bh(&ack_info->seqlock);
}
}
/* return val: 0 for not filter, 1 for filter */
int filter_send_tcp_ack(struct rwnx_hw *priv,
struct msg_buf *msgbuf,
unsigned char *buf, unsigned int plen)
{
//printk("%s \n",__func__);
int ret = 0;
int index, drop;
unsigned short win_scale = 0;
unsigned int win = 0;
struct tcp_ack_msg ack_msg;
struct tcp_ack_msg *ack;
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
if (plen > MAX_TCP_ACK)
return 0;
tcp_ack_update(ack_m);
drop = tcp_check_ack(buf, &ack_msg, &win_scale);
//printk("drop:%d win_scale:%d",drop,win_scale);
if (!drop && (0 == win_scale))
return 0;
index = tcp_ack_match(ack_m, &ack_msg);
if (index >= 0) {
ack_info = ack_m->ack_info + index;
if ((0 != win_scale) &&
(ack_info->win_scale != win_scale)) {
write_seqlock_bh(&ack_info->seqlock);
ack_info->win_scale = win_scale;
write_sequnlock_bh(&ack_info->seqlock);
}
if (drop > 0 && atomic_read(&ack_m->enable)) {
win = ack_info->win_scale * ack_msg.win;
if ((win_scale!=0) && (win < (ack_m->ack_winsize * SIZE_KB)))
{
drop = 2;
printk("%d %d %d",win_scale,win,(ack_m->ack_winsize * SIZE_KB));
}
ret = tcp_ack_handle_new(msgbuf, ack_m, ack_info,
&ack_msg, drop);
}
goto out;
}
index = tcp_ack_alloc_index(ack_m);
if (index >= 0) {
write_seqlock_bh(&ack_m->ack_info[index].seqlock);
ack_m->ack_info[index].busy = 1;
ack_m->ack_info[index].psh_flag = 0;
ack_m->ack_info[index].last_time = jiffies;
ack_m->ack_info[index].drop_cnt =
atomic_read(&ack_m->max_drop_cnt);
ack_m->ack_info[index].win_scale =
(win_scale != 0) ? win_scale : 1;
//ack_m->ack_info[index].msgbuf = NULL;
//ack_m->ack_info[index].in_send_msg = NULL;
ack = &ack_m->ack_info[index].ack_msg;
ack->dest = ack_msg.dest;
ack->source = ack_msg.source;
ack->saddr = ack_msg.saddr;
ack->daddr = ack_msg.daddr;
ack->seq = ack_msg.seq;
write_sequnlock_bh(&ack_m->ack_info[index].seqlock);
}
out:
return ret;
}
void move_tcpack_msg(struct rwnx_hw *priv,
struct msg_buf *msg)
{
struct tcp_ack_info *ack_info;
struct tcp_ack_manage *ack_m = &priv->ack_m;
int i = 0;
if (!atomic_read(&ack_m->enable))
return;
//if (msg->len > MAX_TCP_ACK)
// return;
for (i = 0; i < TCP_ACK_NUM; i++) {
ack_info = &ack_m->ack_info[i];
write_seqlock_bh(&ack_info->seqlock);
if (ack_info->busy && (ack_info->in_send_msg == msg))
ack_info->in_send_msg = NULL;
write_sequnlock_bh(&ack_info->seqlock);
}
}

View File

@ -0,0 +1,111 @@
#ifndef _AICWF_TCP_ACK_H_
#define _AICWF_TCP_ACK_H_
#include <uapi/linux/if_ether.h>
#include <uapi/linux/tcp.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/in.h>
#include <linux/moduleparam.h>
#include <net/tcp.h>
#include <linux/timer.h>
#define TCP_ACK_NUM 32
#define TCP_ACK_EXIT_VAL 0x800
#define TCP_ACK_DROP_CNT 10
#define ACK_OLD_TIME 4000
#define U32_BEFORE(a, b) ((__s32)((__u32)a - (__u32)b) <= 0)
#define MAX_TCP_ACK 200
/*min window size in KB, it's 256KB*/
#define MIN_WIN 256
#define SIZE_KB 1024
struct msg_buf {
//struct list_head list;
struct sk_buff *skb;
struct rwnx_vif *rwnx_vif;
/* data just tx cmd use,not include the head */
/*void *data;
void *tran_data;
unsigned long pcie_addr;
u8 type;
u8 mode;
u16 len;
unsigned long timeout;*/
/* marlin 2 */
/*unsigned int fifo_id;
struct sprdwl_msg_list *msglist;*/
/* marlin 3 */
/*unsigned char buffer_type;
struct sprdwl_xmit_msg_list *xmit_msg_list;
unsigned char msg_type;
unsigned long last_time;
u8 ctxt_id;*/
};
struct tcp_ack_msg {
u16 source;
u16 dest;
s32 saddr;
s32 daddr;
u32 seq;
u16 win;
};
struct tcp_ack_info {
int ack_info_num;
int busy;
int drop_cnt;
int psh_flag;
u32 psh_seq;
u16 win_scale;
/* seqlock for ack info */
seqlock_t seqlock;
unsigned long last_time;
unsigned long timeout;
struct timer_list timer;
struct msg_buf *msgbuf;
struct msg_buf *in_send_msg;
struct tcp_ack_msg ack_msg;
};
struct tcp_ack_manage {
/* 1 filter */
atomic_t enable;
int max_num;
int free_index;
unsigned long last_time;
unsigned long timeout;
atomic_t max_drop_cnt;
/* lock for tcp ack alloc and free */
spinlock_t lock;
struct rwnx_hw *priv;
struct tcp_ack_info ack_info[TCP_ACK_NUM];
/*size in KB*/
unsigned int ack_winsize;
};
struct msg_buf *intf_tcp_alloc_msg(struct msg_buf *msg);
void tcp_ack_init(struct rwnx_hw *priv);
void tcp_ack_deinit(struct rwnx_hw *priv);
int is_drop_tcp_ack(struct tcphdr *tcphdr, int tcp_tot_len, unsigned short *win_scale);
int is_tcp_ack(struct sk_buff *skb, unsigned short *win_scale);
int filter_send_tcp_ack(struct rwnx_hw *priv, struct msg_buf *msgbuf,unsigned char *buf, unsigned int plen);
void filter_rx_tcp_ack(struct rwnx_hw *priv,unsigned char *buf, unsigned plen);
void move_tcpack_msg(struct rwnx_hw *priv, struct msg_buf * msg);
#endif

View File

@ -0,0 +1,885 @@
/**
* 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 "lmac_msg.h"
#include "aicwf_txrxif.h"
#include "rwnx_platform.h"
#include "rwnx_defs.h"
#include "rwnx_msg_rx.h"
#include "rwnx_rx.h"
#include "aicwf_rx_prealloc.h"
#ifdef AICWF_SDIO_SUPPORT
#include "sdio_host.h"
#endif
#include "aic_bsp_export.h"
#ifdef CONFIG_PREALLOC_RX_SKB
void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len)
{
//int prio;
memset(pq, 0, offsetof(struct rx_frame_queue, queuelist) + (sizeof(struct list_head)));
pq->qmax = (u16)max_len;
INIT_LIST_HEAD(&pq->queuelist);
#if 0
memset(pq, 0, offsetof(struct rx_frame_queue, queuelist) + (sizeof(struct list_head) * num_prio));
pq->num_prio = (u16)num_prio;
pq->qmax = (u16)max_len;
for (prio = 0; prio < num_prio; prio++) {
INIT_LIST_HEAD(&pq->queuelist[prio]);
}
#endif
}
//extern struct aic_sdio_dev *g_sdiodev;
void rxbuff_queue_flush(struct aicwf_rx_priv* rx_priv)
{
//int prio;
struct rx_frame_queue *pq = &rx_priv->rxq;
struct list_head *pos;
struct list_head *n;
struct list_head *head;
struct rx_buff *tempbuf = NULL;
head = &pq->queuelist;
list_for_each_safe(pos, n, head) {
tempbuf = list_entry(pos, struct rx_buff, queue);
list_del_init(&tempbuf->queue);
#if 0
rxbuff_free(tempbuf);
#else
aicwf_prealloc_rxbuff_free(tempbuf, &rx_priv->rxbuff_lock);
#endif
pq->qcnt--;
}
}
#endif
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);
//new oob feature
init_completion(&bus_if->busirq_trgg);
#ifdef AICWF_SDIO_SUPPORT
spin_lock_init(&bus_if->bus_priv.sdio->wslock);//AIDEN test
bus_if->bustx_thread = kthread_run(sdio_bustx_thread, (void *)bus_if, "aicwf_bustx_thread");
bus_if->busrx_thread = kthread_run(sdio_busrx_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busrx_thread");
//new oob feature
#ifdef CONFIG_OOB
if(bus_if->bus_priv.sdio->oob_enable){
bus_if->busirq_thread = kthread_run(sdio_busirq_thread, (void *)bus_if->bus_priv.sdio->rx_priv, "aicwf_busirq_thread");
}
#endif //CONFIG_OOB
#endif
#ifdef AICWF_USB_SUPPORT
bus_if->bustx_thread = kthread_run(usb_bustx_thread, (void *)bus_if, "aicwf_bustx_thread");
bus_if->busrx_thread = kthread_run(usb_busrx_thread, (void *)bus_if->bus_priv.usb->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;
#ifdef AICWF_USB_SUPPORT
struct aic_usb_dev *usb;
#endif
#ifdef AICWF_SDIO_SUPPORT
struct aic_sdio_dev *sdiodev;
#endif
if (!dev) {
txrx_err("device not found\n");
return;
}
AICWFDBG(LOGINFO, "%s Enter\r\n", __func__);
bus_if = dev_get_drvdata(dev);
aicwf_bus_stop(bus_if);
#ifdef AICWF_USB_SUPPORT
usb = bus_if->bus_priv.usb;
if (g_rwnx_plat->enabled)
rwnx_platform_deinit(usb->rwnx_hw);
#endif
#ifdef AICWF_SDIO_SUPPORT
sdiodev = bus_if->bus_priv.sdio;
if (g_rwnx_plat && g_rwnx_plat->enabled) {
rwnx_platform_deinit(sdiodev->rwnx_hw);
}
#endif
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;
}
AICWFDBG(LOGINFO, "%s Exit\r\n", __func__);
}
void aicwf_frame_tx(void *dev, struct sk_buff *skb)
{
#ifdef AICWF_SDIO_SUPPORT
struct aic_sdio_dev *sdiodev = (struct aic_sdio_dev *)dev;
aicwf_bus_txdata(sdiodev->bus_if, skb);
#else
struct aic_usb_dev *usbdev = (struct aic_usb_dev *)dev;
if (!usbdev->state) {
txrx_err("down\n");
aicwf_usb_tx_flowctrl(usbdev->rwnx_hw, true);
dev_kfree_skb(skb);
return;
}
aicwf_bus_txdata(usbdev->bus_if, skb);
#endif
}
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;
#ifdef AICWF_SDIO_SUPPORT
tx_priv->sdiodev = (struct aic_sdio_dev *)arg;
#else
tx_priv->usbdev = (struct aic_usb_dev *)arg;
#endif
atomic_set(&tx_priv->aggr_count, 0);
#ifdef CONFIG_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);
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) {
#ifdef CONFIG_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);
}
}
#ifdef AICWF_SDIO_SUPPORT
#ifdef CONFIG_PREALLOC_RX_SKB
static bool aicwf_another_ptk_1(struct rx_buff *buffer)
{
u8 *read = buffer->read;
u16 aggr_len = 0;
BUG_ON((read - buffer->start)%4 != 0);
if(read == NULL || read >= buffer->end) {
return false;
}
aggr_len = (*read | (*(read + 1) << 8));
if(aggr_len == 0) {
return false;
}
return true;
}
#else
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;
}
#endif
#endif
int aicwf_process_rxframes(struct aicwf_rx_priv *rx_priv)
{
#ifdef AICWF_SDIO_SUPPORT
int ret = 0;
unsigned long flags = 0;
#ifndef CONFIG_PREALLOC_RX_SKB
struct sk_buff *skb = NULL;
#endif
u16 pkt_len = 0;
struct sk_buff *skb_inblock = NULL;
u16 aggr_len = 0, adjust_len = 0;
u8 *data = NULL;
u8_l *msg = NULL;
#ifdef CONFIG_PREALLOC_RX_SKB
struct rx_buff *buffer = NULL;
while (1) {
spin_lock_irqsave(&rx_priv->rxqlock, flags);
if (!rx_priv->rxq.qcnt) {
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
break;
}
buffer = rxbuff_dequeue(&rx_priv->rxq);
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
if (buffer == NULL) {
txrx_err("skb_error\r\n");
break;
}
while (aicwf_another_ptk_1(buffer)) {
data = buffer->read;
pkt_len = (*data | (*(data + 1) << 8));
if ((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);
if (skb_inblock == NULL) {
txrx_err("no more space! skip\n");
buffer->read = buffer->read + adjust_len;
continue;
}
skb_put(skb_inblock, aggr_len);
memcpy(skb_inblock->data, data, aggr_len);
rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv);
buffer->read = buffer->read + 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;
msg = kmalloc(aggr_len+4, GFP_KERNEL);
if (msg == NULL) {
txrx_err("no more space for msg!\n");
aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock);
return -EBADE;
}
memcpy(msg, data, aggr_len + 4);
if (((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP) && (rx_priv->sdiodev->bus_if->state != BUS_DOWN_ST))
rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4));
if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM)
aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4));
if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_PRINT)
rwnx_rx_handle_print(rx_priv->sdiodev->rwnx_hw, msg + 4, aggr_len);
buffer->read = buffer->read + (adjust_len + 4);
kfree(msg);
}
}
aicwf_prealloc_rxbuff_free(buffer, &rx_priv->rxbuff_lock);
atomic_dec(&rx_priv->rx_cnt);
}
#else
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);
if (skb_inblock == NULL) {
txrx_err("no more space! skip\n");
skb_pull(skb, adjust_len);
continue;
}
skb_put(skb_inblock, aggr_len);
memcpy(skb_inblock->data, data, aggr_len);
rwnx_rxdataind_aicwf(rx_priv->sdiodev->rwnx_hw, skb_inblock, (void *)rx_priv);
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;
msg = kmalloc(aggr_len+4, GFP_KERNEL);
if (msg == NULL) {
txrx_err("no more space for msg!\n");
aicwf_dev_skb_free(skb);
return -EBADE;
}
memcpy(msg, data, aggr_len + 4);
if (((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_CMD_RSP) && (rx_priv->sdiodev->bus_if->state != BUS_DOWN_ST))
rwnx_rx_handle_msg(rx_priv->sdiodev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4));
if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_DATA_CFM)
aicwf_sdio_host_tx_cfm_handler(&(rx_priv->sdiodev->rwnx_hw->sdio_env), (u32 *)(msg + 4));
if ((*(msg + 2) & 0x7f) == SDIO_TYPE_CFG_PRINT)
rwnx_rx_handle_print(rx_priv->sdiodev->rwnx_hw, msg + 4, aggr_len);
skb_pull(skb, adjust_len+4);
kfree(msg);
}
}
dev_kfree_skb(skb);
atomic_dec(&rx_priv->rx_cnt);
}
#endif
#if defined(CONFIG_SDIO_PWRCTRL)
aicwf_sdio_pwr_stctl(rx_priv->sdiodev, SDIO_ACTIVE_ST);
#endif
return ret;
#else //AICWF_USB_SUPPORT
int ret = 0;
unsigned long flags = 0;
struct sk_buff *skb = NULL; /* Packet for event or data frames */
u16 pkt_len = 0;
struct sk_buff *skb_inblock = NULL;
u16 aggr_len = 0, adjust_len = 0;
u8 *data = NULL;
u8_l *msg = NULL;
while (1) {
spin_lock_irqsave(&rx_priv->rxqlock, flags);
if (aicwf_is_framequeue_empty(&rx_priv->rxq)) {
usb_info("no more rxdata\n");
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
break;
}
skb = aicwf_frame_dequeue(&rx_priv->rxq);
spin_unlock_irqrestore(&rx_priv->rxqlock, flags);
if (skb == NULL) {
txrx_err("skb_error\r\n");
break;
}
data = skb->data;
pkt_len = (*skb->data | (*(skb->data + 1) << 8));
//printk("p:%d, s:%d , %x\n", pkt_len, skb->len, data[2]);
if (pkt_len > 1600) {
dev_kfree_skb(skb);
atomic_dec(&rx_priv->rx_cnt);
continue;
}
if ((skb->data[2] & USB_TYPE_CFG) != USB_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! skip!\n");
skb_pull(skb, adjust_len);
continue;
}
skb_put(skb_inblock, aggr_len);
memcpy(skb_inblock->data, data, aggr_len);
rwnx_rxdataind_aicwf(rx_priv->usbdev->rwnx_hw, skb_inblock, (void *)rx_priv);
///TODO: here need to add rx data process
skb_pull(skb, adjust_len);
} else { // type : config
aggr_len = pkt_len;
if (aggr_len & (RX_ALIGNMENT - 1))
adjust_len = roundup(aggr_len, RX_ALIGNMENT);
else
adjust_len = aggr_len;
msg = kmalloc(aggr_len+4, GFP_KERNEL);
if (msg == NULL) {
txrx_err("no more space for msg!\n");
aicwf_dev_skb_free(skb);
return -EBADE;
}
memcpy(msg, data, aggr_len + 4);
if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_CMD_RSP)
rwnx_rx_handle_msg(rx_priv->usbdev->rwnx_hw, (struct ipc_e2a_msg *)(msg + 4));
if ((*(msg + 2) & 0x7f) == USB_TYPE_CFG_DATA_CFM)
aicwf_usb_host_tx_cfm_handler(&(rx_priv->usbdev->rwnx_hw->usb_env), (u32 *)(msg + 4));
skb_pull(skb, adjust_len + 4);
kfree(msg);
}
dev_kfree_skb(skb);
atomic_dec(&rx_priv->rx_cnt);
}
return ret;
#endif //AICWF_SDIO_SUPPORT
}
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++;
}
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;
#ifdef AICWF_SDIO_SUPPORT
rx_priv->sdiodev = (struct aic_sdio_dev *)arg;
#else
rx_priv->usbdev = (struct aic_usb_dev *)arg;
#endif
#ifdef CONFIG_PREALLOC_RX_SKB
aicwf_rxframe_queue_init_2(&rx_priv->rxq, MAX_RXQLEN);
#else
aicwf_frame_queue_init(&rx_priv->rxq, 1, MAX_RXQLEN);
#endif
spin_lock_init(&rx_priv->rxqlock);
#ifdef CONFIG_PREALLOC_RX_SKB
spin_lock_init(&rx_priv->rxbuff_lock);
aicwf_prealloc_init();
#endif
atomic_set(&rx_priv->rx_cnt, 0);
#ifdef AICWF_RX_REORDER
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);
#endif
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)
{
#ifdef AICWF_RX_REORDER
struct reord_ctrl_info *reord_info, *tmp;
AICWFDBG(LOGINFO, "%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
AICWFDBG(LOGINFO, "sdio rx thread\n");
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;
}
#ifdef CONFIG_OOB
if(rx_priv->sdiodev->oob_enable){
//new oob feature
if (rx_priv->sdiodev->bus_if->busirq_thread) {
complete_all(&rx_priv->sdiodev->bus_if->busirq_trgg);
kthread_stop(rx_priv->sdiodev->bus_if->busirq_thread);
rx_priv->sdiodev->bus_if->busirq_thread = NULL;
}
}
#endif //CONFIG_OOB
#endif
#ifdef AICWF_USB_SUPPORT
if (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;
}
#endif
#ifdef CONFIG_PREALLOC_RX_SKB
rxbuff_queue_flush(rx_priv);
#else
aicwf_frame_queue_flush(&rx_priv->rxq);
#endif
#ifdef AICWF_RX_REORDER
aicwf_recvframe_queue_deinit(&rx_priv->rxframes_freequeue);
if (rx_priv->recv_frames)
vfree(rx_priv->recv_frames);
#endif
#ifdef CONFIG_PREALLOC_RX_SKB
aicwf_prealloc_exit();
#endif
kfree(rx_priv);
AICWFDBG(LOGINFO, "%s exit \n", __func__);
}
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;
}
#if 0
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;
}
#endif
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio)
{
#if 0
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
if (q->queuelist[prio].qlen < q->qmax && q->qcnt < q->qmax) {
aicwf_frame_queue_penq(q, prio, pkt);
return true;
} else
return false;
#endif
}
#ifdef CONFIG_PREALLOC_RX_SKB
void rxbuff_free(struct rx_buff *rxbuff)
{
kfree(rxbuff->data);
kfree(rxbuff);
}
struct rx_buff *rxbuff_queue_penq(struct rx_frame_queue *pq, struct rx_buff *p)
{
struct list_head *q;
if (pq->qcnt >= pq->qmax)
return NULL;
q = &pq->queuelist;
list_add_tail(&p->queue,q);
pq->qcnt++;
return p;
}
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq)
{
struct rx_buff *p = NULL;
if (pq->qcnt == 0) {
printk("%s %d, rxq is empty\n", __func__, __LINE__);
return NULL;
}
if(list_empty(&pq->queuelist)) {
printk("%s %d, rxq is empty\n", __func__, __LINE__);
return NULL;
} else {
p = list_first_entry(&pq->queuelist, struct rx_buff, queue);
list_del_init(&p->queue);
pq->qcnt--;
}
return p;
}
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt)
{
// struct rx_buff *p = NULL;
if ((rxq == NULL) || (pkt == NULL)) {
printk("%s %d, rxq or pkt is NULL\n", __func__, __LINE__);
return false;
}
if (rxq->qcnt < rxq->qmax) {
if (rxbuff_queue_penq(rxq, pkt)) {
return true;
} else {
printk("%s %d, rxbuff enqueue fail\n", __func__, __LINE__);
return false;
}
} else {
printk("%s %d, rxq or pkt is full\n", __func__, __LINE__);
return false;
}
}
#endif

View File

@ -0,0 +1,262 @@
/**
* 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 "ipc_shared.h"
#include "aicwf_rx_prealloc.h"
#ifdef AICWF_SDIO_SUPPORT
#include "aicwf_sdio.h"
#else
#include "aicwf_usb.h"
#endif
#define CMD_BUF_MAX 1536
#define TXPKT_BLOCKSIZE 512
#define MAX_AGGR_TXPKT_LEN (1536*64)
#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("txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define sdio_err(fmt, ...) pr_err("sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#define usb_err(fmt, ...) pr_err("usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL
#define txrx_dbg(fmt, ...) printk("txrx: " fmt, ##__VA_ARGS__)
#define sdio_dbg(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
#define usb_dbg(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__)
#else
#define txrx_dbg(fmt, ...)
#define sdio_dbg(fmt, ...)
#define usb_dbg(fmt, ...)
#endif
#if DBG_LEVEL >= DEBUG_INFO_LEVEL
#define txrx_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
#define sdio_info(fmt, ...) printk("aicsdio: " fmt, ##__VA_ARGS__)
#define usb_info(fmt, ...) printk("aicusb: " fmt, ##__VA_ARGS__)
#else
#define txrx_info(fmt, ...)
#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];
};
#ifdef CONFIG_PREALLOC_RX_SKB
struct rx_frame_queue {
u16 qmax; /* max number of queued frames */
u16 qcnt;
struct list_head queuelist;
};
#endif
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 completion busirq_trgg;//new oob feature
struct task_struct *bustx_thread;
struct task_struct *busrx_thread;
struct task_struct *busirq_thread;//new oob feature
};
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 DEFRAG_MAX_WAIT 40 //100
#ifdef AICWF_RX_REORDER
#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;
u8 forward;
//uint len;
u32 is_amsdu;
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;
};
#endif
struct aicwf_rx_priv {
#ifdef AICWF_SDIO_SUPPORT
struct aic_sdio_dev *sdiodev;
#endif
#ifdef AICWF_USB_SUPPORT
struct aic_usb_dev *usbdev;
#endif
void *rwnx_vif;
atomic_t rx_cnt;
u32 data_len;
spinlock_t rxqlock;
#ifdef CONFIG_PREALLOC_RX_SKB
struct rx_frame_queue rxq;
#else
struct frame_queue rxq;
#endif
#ifdef AICWF_RX_REORDER
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;
#endif
#ifdef CONFIG_PREALLOC_RX_SKB
spinlock_t rxbuff_lock;
#endif
};
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);
#ifdef CONFIG_PREALLOC_RX_SKB
void rxbuff_queue_flush(struct aicwf_rx_priv* rx_priv);
void aicwf_rxframe_queue_init_2(struct rx_frame_queue *pq, int max_len);
void rxbuff_free(struct rx_buff *rxbuff);
struct rx_buff *rxbuff_dequeue(struct rx_frame_queue *pq);
bool aicwf_rxbuff_enqueue(struct device *dev, struct rx_frame_queue *rxq, struct rx_buff *pkt);
extern struct aicwf_rx_buff_list aic_rx_buff_list;
#endif
#endif /* _AICWF_TXRXIF_H_ */

View File

@ -0,0 +1,957 @@
/**
* aicwf_usb.c
*
* USB function declarations
*
* Copyright (C) AICSemi 2018-2020
*/
#include <linux/usb.h>
#include <linux/kthread.h>
#include "aicwf_txrxif.h"
#include "aicwf_usb.h"
#include "rwnx_tx.h"
#include "rwnx_defs.h"
#include "usb_host.h"
#include "rwnx_platform.h"
void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state)
{
struct rwnx_vif *rwnx_vif;
list_for_each_entry(rwnx_vif, &rwnx_hw->vifs, list) {
if (!rwnx_vif->up)
continue;
if (!rwnx_vif->ndev)
continue;
if (state)
netif_stop_queue(rwnx_vif->ndev);
else
netif_wake_queue(rwnx_vif->ndev);
}
}
static struct aicwf_usb_buf *aicwf_usb_tx_dequeue(struct aic_usb_dev *usb_dev,
struct list_head *q, int *counter, spinlock_t *qlock)
{
unsigned long flags;
struct aicwf_usb_buf *usb_buf;
spin_lock_irqsave(qlock, flags);
if (list_empty(q)) {
usb_buf = NULL;
} else {
usb_buf = list_first_entry(q, struct aicwf_usb_buf, list);
list_del_init(&usb_buf->list);
if (counter)
(*counter)--;
}
spin_unlock_irqrestore(qlock, flags);
return usb_buf;
}
static void aicwf_usb_tx_queue(struct aic_usb_dev *usb_dev,
struct list_head *q, struct aicwf_usb_buf *usb_buf, int *counter,
spinlock_t *qlock)
{
unsigned long flags;
spin_lock_irqsave(qlock, flags);
list_add_tail(&usb_buf->list, q);
(*counter)++;
spin_unlock_irqrestore(qlock, flags);
}
static struct aicwf_usb_buf *aicwf_usb_rx_buf_get(struct aic_usb_dev *usb_dev)
{
unsigned long flags;
struct aicwf_usb_buf *usb_buf;
spin_lock_irqsave(&usb_dev->rx_free_lock, flags);
if (list_empty(&usb_dev->rx_free_list)) {
usb_buf = NULL;
} else {
usb_buf = list_first_entry(&usb_dev->rx_free_list, struct aicwf_usb_buf, list);
list_del_init(&usb_buf->list);
}
spin_unlock_irqrestore(&usb_dev->rx_free_lock, flags);
return usb_buf;
}
static void aicwf_usb_rx_buf_put(struct aic_usb_dev *usb_dev, struct aicwf_usb_buf *usb_buf)
{
unsigned long flags;
spin_lock_irqsave(&usb_dev->rx_free_lock, flags);
list_add_tail(&usb_buf->list, &usb_dev->rx_free_list);
spin_unlock_irqrestore(&usb_dev->rx_free_lock, flags);
}
static void aicwf_usb_tx_complete(struct urb *urb)
{
unsigned long flags;
struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context;
struct aic_usb_dev *usb_dev = usb_buf->usbdev;
struct sk_buff *skb;
u8 *buf;
if (usb_buf->cfm == false) {
skb = usb_buf->skb;
} else {
buf = (u8 *)usb_buf->skb;
}
if (usb_buf->cfm == false) {
dev_kfree_skb_any(skb);
} else {
kfree(buf);
}
usb_buf->skb = NULL;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
spin_lock_irqsave(&usb_dev->tx_flow_lock, flags);
if (usb_dev->tx_free_count > AICWF_USB_TX_HIGH_WATER) {
if (usb_dev->tbusy) {
usb_dev->tbusy = false;
aicwf_usb_tx_flowctrl(usb_dev->rwnx_hw, false);
}
}
spin_unlock_irqrestore(&usb_dev->tx_flow_lock, flags);
}
static void aicwf_usb_rx_complete(struct urb *urb)
{
struct aicwf_usb_buf *usb_buf = (struct aicwf_usb_buf *) urb->context;
struct aic_usb_dev *usb_dev = usb_buf->usbdev;
struct aicwf_rx_priv *rx_priv = usb_dev->rx_priv;
struct sk_buff *skb = NULL;
unsigned long flags = 0;
skb = usb_buf->skb;
usb_buf->skb = NULL;
if (urb->actual_length > urb->transfer_buffer_length) {
aicwf_dev_skb_free(skb);
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
schedule_work(&usb_dev->rx_urb_work);
return;
}
if (urb->status != 0 || !urb->actual_length) {
aicwf_dev_skb_free(skb);
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
schedule_work(&usb_dev->rx_urb_work);
return;
}
if (usb_dev->state == USB_UP_ST) {
skb_put(skb, urb->actual_length);
spin_lock_irqsave(&rx_priv->rxqlock, flags);
if (!aicwf_rxframe_enqueue(usb_dev->dev, &rx_priv->rxq, skb)) {
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);
atomic_inc(&rx_priv->rx_cnt);
complete(&rx_priv->usbdev->bus_if->busrx_trgg);
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
schedule_work(&usb_dev->rx_urb_work);
} else {
aicwf_dev_skb_free(skb);
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
}
}
static int aicwf_usb_submit_rx_urb(struct aic_usb_dev *usb_dev,
struct aicwf_usb_buf *usb_buf)
{
struct sk_buff *skb;
int ret;
if (!usb_buf || !usb_dev)
return -1;
if (usb_dev->state != USB_UP_ST) {
usb_err("usb state is not up!\n");
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
return -1;
}
skb = __dev_alloc_skb(AICWF_USB_MAX_PKT_SIZE, GFP_KERNEL);
if (!skb) {
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
return -1;
}
usb_buf->skb = skb;
usb_fill_bulk_urb(usb_buf->urb,
usb_dev->udev,
usb_dev->bulk_in_pipe,
skb->data, skb_tailroom(skb), aicwf_usb_rx_complete, usb_buf);
usb_buf->usbdev = usb_dev;
usb_anchor_urb(usb_buf->urb, &usb_dev->rx_submitted);
ret = usb_submit_urb(usb_buf->urb, GFP_ATOMIC);
if (ret) {
usb_err("usb submit rx urb fail:%d\n", ret);
usb_unanchor_urb(usb_buf->urb);
aicwf_dev_skb_free(usb_buf->skb);
usb_buf->skb = NULL;
aicwf_usb_rx_buf_put(usb_dev, usb_buf);
msleep(100);
}
return 0;
}
static void aicwf_usb_rx_submit_all_urb(struct aic_usb_dev *usb_dev)
{
struct aicwf_usb_buf *usb_buf;
if (usb_dev->state != USB_UP_ST) {
usb_err("bus is not up=%d\n", usb_dev->state);
return;
}
while ((usb_buf = aicwf_usb_rx_buf_get(usb_dev)) != NULL) {
if (aicwf_usb_submit_rx_urb(usb_dev, usb_buf)) {
usb_err("usb rx refill fail\n");
if (usb_dev->state != USB_UP_ST)
return;
}
}
}
static void aicwf_usb_rx_prepare(struct aic_usb_dev *usb_dev)
{
aicwf_usb_rx_submit_all_urb(usb_dev);
}
static void aicwf_usb_tx_prepare(struct aic_usb_dev *usb_dev)
{
struct aicwf_usb_buf *usb_buf;
while (!list_empty(&usb_dev->tx_post_list)) {
usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_post_list,
&usb_dev->tx_post_count, &usb_dev->tx_post_lock);
if (usb_buf->skb) {
dev_kfree_skb(usb_buf->skb);
usb_buf->skb = NULL;
}
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
}
}
static void aicwf_usb_tx_process(struct aic_usb_dev *usb_dev)
{
struct aicwf_usb_buf *usb_buf;
int ret = 0;
u8 *data = NULL;
while (!list_empty(&usb_dev->tx_post_list)) {
if (usb_dev->state != USB_UP_ST) {
usb_err("usb state is not up!\n");
return;
}
usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_post_list,
&usb_dev->tx_post_count, &usb_dev->tx_post_lock);
if (!usb_buf) {
usb_err("can not get usb_buf from tx_post_list!\n");
return;
}
data = usb_buf->skb->data;
ret = usb_submit_urb(usb_buf->urb, GFP_ATOMIC);
if (ret) {
usb_err("aicwf_usb_bus_tx usb_submit_urb FAILED\n");
goto fail;
}
continue;
fail:
dev_kfree_skb(usb_buf->skb);
usb_buf->skb = NULL;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_free_list, usb_buf,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
}
}
int usb_bustx_thread(void *data)
{
struct aicwf_bus *bus = (struct aicwf_bus *)data;
struct aic_usb_dev *usbdev = bus->bus_priv.usb;
while (1) {
if (kthread_should_stop()) {
usb_err("usb bustx thread stop\n");
break;
}
if (!wait_for_completion_interruptible(&bus->bustx_trgg)) {
if (usbdev->bus_if->state == BUS_DOWN_ST)
continue;
if (usbdev->tx_post_count > 0)
aicwf_usb_tx_process(usbdev);
}
}
return 0;
}
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;
while (1) {
if (kthread_should_stop()) {
usb_err("usb busrx thread stop\n");
break;
}
if (!wait_for_completion_interruptible(&bus_if->busrx_trgg)) {
if (bus_if->state == BUS_DOWN_ST)
continue;
aicwf_process_rxframes(rx_priv);
}
}
return 0;
}
static void aicwf_usb_send_msg_complete(struct urb *urb)
{
struct aic_usb_dev *usb_dev = (struct aic_usb_dev *) urb->context;
usb_dev->msg_finished = true;
if (waitqueue_active(&usb_dev->msg_wait))
wake_up(&usb_dev->msg_wait);
}
static int aicwf_usb_bus_txmsg(struct device *dev, u8 *buf, u32 len)
{
int ret = 0;
struct aicwf_bus *bus_if = dev_get_drvdata(dev);
struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb;
if (usb_dev->state != USB_UP_ST)
return -EIO;
if (buf == NULL || len == 0 || usb_dev->msg_out_urb == NULL)
return -EINVAL;
if (test_and_set_bit(0, &usb_dev->msg_busy)) {
usb_err("In a control frame option, can't tx!\n");
return -EIO;
}
usb_dev->msg_finished = false;
usb_fill_bulk_urb(usb_dev->msg_out_urb,
usb_dev->udev,
usb_dev->bulk_out_pipe,
buf, len, (usb_complete_t) aicwf_usb_send_msg_complete, usb_dev);
usb_dev->msg_out_urb->transfer_flags |= URB_ZERO_PACKET;
ret = usb_submit_urb(usb_dev->msg_out_urb, GFP_ATOMIC);
if (ret) {
usb_err("usb_submit_urb failed %d\n", ret);
goto exit;
}
ret = wait_event_timeout(usb_dev->msg_wait,
usb_dev->msg_finished, msecs_to_jiffies(CMD_TX_TIMEOUT));
if (!ret) {
if (usb_dev->msg_out_urb)
usb_kill_urb(usb_dev->msg_out_urb);
usb_err("Txmsg wait timed out\n");
ret = -EIO;
goto exit;
}
if (usb_dev->msg_finished == false) {
usb_err("Txmsg timed out\n");
ret = -ETIMEDOUT;
goto exit;
}
exit:
clear_bit(0, &usb_dev->msg_busy);
return ret;
}
static void aicwf_usb_free_urb(struct list_head *q, spinlock_t *qlock)
{
struct aicwf_usb_buf *usb_buf, *tmp;
unsigned long flags;
spin_lock_irqsave(qlock, flags);
list_for_each_entry_safe(usb_buf, tmp, q, list) {
spin_unlock_irqrestore(qlock, flags);
if (!usb_buf->urb) {
usb_err("bad usb_buf\n");
spin_lock_irqsave(qlock, flags);
break;
}
usb_free_urb(usb_buf->urb);
list_del_init(&usb_buf->list);
spin_lock_irqsave(qlock, flags);
}
spin_unlock_irqrestore(qlock, flags);
}
static int aicwf_usb_alloc_rx_urb(struct aic_usb_dev *usb_dev)
{
int i;
for (i = 0; i < AICWF_USB_RX_URBS; i++) {
struct aicwf_usb_buf *usb_buf = &usb_dev->usb_rx_buf[i];
usb_buf->usbdev = usb_dev;
usb_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!usb_buf->urb) {
usb_err("could not allocate rx data urb\n");
goto err;
}
list_add_tail(&usb_buf->list, &usb_dev->rx_free_list);
}
return 0;
err:
aicwf_usb_free_urb(&usb_dev->rx_free_list, &usb_dev->rx_free_lock);
return -ENOMEM;
}
static int aicwf_usb_alloc_tx_urb(struct aic_usb_dev *usb_dev)
{
int i;
for (i = 0; i < AICWF_USB_TX_URBS; i++) {
struct aicwf_usb_buf *usb_buf = &usb_dev->usb_tx_buf[i];
usb_buf->usbdev = usb_dev;
usb_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!usb_buf->urb) {
usb_err("could not allocate tx data urb\n");
goto err;
}
list_add_tail(&usb_buf->list, &usb_dev->tx_free_list);
(usb_dev->tx_free_count)++;
}
return 0;
err:
aicwf_usb_free_urb(&usb_dev->tx_free_list, &usb_dev->tx_free_lock);
return -ENOMEM;
}
static void aicwf_usb_state_change(struct aic_usb_dev *usb_dev, int state)
{
int old_state;
if (usb_dev->state == state)
return;
old_state = usb_dev->state;
usb_dev->state = state;
if (state == USB_DOWN_ST) {
usb_dev->bus_if->state = BUS_DOWN_ST;
}
if (state == USB_UP_ST) {
usb_dev->bus_if->state = BUS_UP_ST;
}
}
static int aicwf_usb_bus_txdata(struct device *dev, struct sk_buff *skb)
{
u8 *buf;
u16 buf_len = 0;
u16 adjust_len = 0;
struct aicwf_usb_buf *usb_buf;
int ret = 0;
unsigned long flags;
struct aicwf_bus *bus_if = dev_get_drvdata(dev);
struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb;
struct rwnx_txhdr *txhdr = (struct rwnx_txhdr *)skb->data;
struct rwnx_hw *rwnx_hw = usb_dev->rwnx_hw;
u8 usb_header[4];
u8 adj_buf[4] = {0};
u16 index = 0;
bool need_cfm = false;
if (usb_dev->state != USB_UP_ST) {
usb_err("usb state is not up!\n");
kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr);
dev_kfree_skb_any(skb);
return -EIO;
}
usb_buf = aicwf_usb_tx_dequeue(usb_dev, &usb_dev->tx_free_list,
&usb_dev->tx_free_count, &usb_dev->tx_free_lock);
if (!usb_buf) {
usb_err("free:%d, post:%d\n", usb_dev->tx_free_count, usb_dev->tx_post_count);
kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr);
dev_kfree_skb_any(skb);
ret = -ENOMEM;
goto flow_ctrl;
}
if (txhdr->sw_hdr->need_cfm) {
need_cfm = true;
buf = kmalloc(skb->len, GFP_KERNEL);
index += sizeof(usb_header);
memcpy(&buf[index], (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api));
index += sizeof(struct txdesc_api);
memcpy(&buf[index], &skb->data[txhdr->sw_hdr->headroom], skb->len - txhdr->sw_hdr->headroom);
index += skb->len - txhdr->sw_hdr->headroom;
buf_len = index;
if (buf_len & (TX_ALIGNMENT - 1)) {
adjust_len = roundup(buf_len, TX_ALIGNMENT)-buf_len;
memcpy(&buf[buf_len], adj_buf, adjust_len);
buf_len += adjust_len;
}
usb_header[0] = ((buf_len) & 0xff);
usb_header[1] = (((buf_len) >> 8)&0x0f);
usb_header[2] = 0x01; //data
usb_header[3] = 0; //reserved
memcpy(&buf[0], usb_header, sizeof(usb_header));
usb_buf->skb = (struct sk_buff *)buf;
} else {
skb_pull(skb, txhdr->sw_hdr->headroom);
skb_push(skb, sizeof(struct txdesc_api));
memcpy(&skb->data[0], (u8 *)(long)&txhdr->sw_hdr->desc, sizeof(struct txdesc_api));
kmem_cache_free(rwnx_hw->sw_txhdr_cache, txhdr->sw_hdr);
skb_push(skb, sizeof(usb_header));
usb_header[0] = ((skb->len) & 0xff);
usb_header[1] = (((skb->len) >> 8)&0x0f);
usb_header[2] = 0x01; //data
usb_header[3] = 0; //reserved
memcpy(&skb->data[0], usb_header, sizeof(usb_header));
buf = skb->data;
buf_len = skb->len;
usb_buf->skb = skb;
}
usb_buf->usbdev = usb_dev;
if (need_cfm)
usb_buf->cfm = true;
else
usb_buf->cfm = false;
usb_fill_bulk_urb(usb_buf->urb, usb_dev->udev, usb_dev->bulk_out_pipe,
buf, buf_len, aicwf_usb_tx_complete, usb_buf);
usb_buf->urb->transfer_flags |= URB_ZERO_PACKET;
aicwf_usb_tx_queue(usb_dev, &usb_dev->tx_post_list, usb_buf,
&usb_dev->tx_post_count, &usb_dev->tx_post_lock);
complete(&bus_if->bustx_trgg);
ret = 0;
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;
aicwf_usb_tx_flowctrl(usb_dev->rwnx_hw, true);
}
spin_unlock_irqrestore(&usb_dev->tx_flow_lock, flags);
return ret;
}
static int aicwf_usb_bus_start(struct device *dev)
{
struct aicwf_bus *bus_if = dev_get_drvdata(dev);
struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb;
if (usb_dev->state == USB_UP_ST)
return 0;
aicwf_usb_state_change(usb_dev, USB_UP_ST);
aicwf_usb_rx_prepare(usb_dev);
aicwf_usb_tx_prepare(usb_dev);
return 0;
}
static void aicwf_usb_cancel_all_urbs(struct aic_usb_dev *usb_dev)
{
struct aicwf_usb_buf *usb_buf, *tmp;
unsigned long flags;
if (usb_dev->msg_out_urb)
usb_kill_urb(usb_dev->msg_out_urb);
spin_lock_irqsave(&usb_dev->tx_post_lock, flags);
list_for_each_entry_safe(usb_buf, tmp, &usb_dev->tx_post_list, list) {
spin_unlock_irqrestore(&usb_dev->tx_post_lock, flags);
if (!usb_buf->urb) {
usb_err("bad usb_buf\n");
spin_lock_irqsave(&usb_dev->tx_post_lock, flags);
break;
}
usb_kill_urb(usb_buf->urb);
spin_lock_irqsave(&usb_dev->tx_post_lock, flags);
}
spin_unlock_irqrestore(&usb_dev->tx_post_lock, flags);
usb_kill_anchored_urbs(&usb_dev->rx_submitted);
}
static void aicwf_usb_bus_stop(struct device *dev)
{
struct aicwf_bus *bus_if = dev_get_drvdata(dev);
struct aic_usb_dev *usb_dev = bus_if->bus_priv.usb;
usb_dbg("%s\r\n", __func__);
if (usb_dev == NULL)
return;
if (usb_dev->state == USB_DOWN_ST)
return;
aicwf_usb_state_change(usb_dev, USB_DOWN_ST);
aicwf_usb_cancel_all_urbs(usb_dev);
}
static void aicwf_usb_deinit(struct aic_usb_dev *usbdev)
{
cancel_work_sync(&usbdev->rx_urb_work);
aicwf_usb_free_urb(&usbdev->rx_free_list, &usbdev->rx_free_lock);
aicwf_usb_free_urb(&usbdev->tx_free_list, &usbdev->tx_free_lock);
usb_free_urb(usbdev->msg_out_urb);
}
static void aicwf_usb_rx_urb_work(struct work_struct *work)
{
struct aic_usb_dev *usb_dev = container_of(work, struct aic_usb_dev, rx_urb_work);
aicwf_usb_rx_submit_all_urb(usb_dev);
}
static int aicwf_usb_init(struct aic_usb_dev *usb_dev)
{
int ret = 0;
usb_dev->tbusy = false;
usb_dev->state = USB_DOWN_ST;
init_waitqueue_head(&usb_dev->msg_wait);
init_usb_anchor(&usb_dev->rx_submitted);
spin_lock_init(&usb_dev->tx_free_lock);
spin_lock_init(&usb_dev->tx_post_lock);
spin_lock_init(&usb_dev->rx_free_lock);
spin_lock_init(&usb_dev->tx_flow_lock);
INIT_LIST_HEAD(&usb_dev->rx_free_list);
INIT_LIST_HEAD(&usb_dev->tx_free_list);
INIT_LIST_HEAD(&usb_dev->tx_post_list);
usb_dev->tx_free_count = 0;
usb_dev->tx_post_count = 0;
ret = aicwf_usb_alloc_rx_urb(usb_dev);
if (ret) {
goto error;
}
ret = aicwf_usb_alloc_tx_urb(usb_dev);
if (ret) {
goto error;
}
usb_dev->msg_out_urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!usb_dev->msg_out_urb) {
usb_err("usb_alloc_urb (msg out) failed\n");
ret = ENOMEM;
goto error;
}
INIT_WORK(&usb_dev->rx_urb_work, aicwf_usb_rx_urb_work);
return ret;
error:
usb_err("failed!\n");
aicwf_usb_deinit(usb_dev);
return ret;
}
static int aicwf_parse_usb(struct aic_usb_dev *usb_dev, struct usb_interface *interface)
{
struct usb_interface_descriptor *interface_desc;
struct usb_host_interface *host_interface;
struct usb_endpoint_descriptor *endpoint;
struct usb_device *usb = usb_dev->udev;
int i, endpoints;
u8 endpoint_num;
int ret = 0;
usb_dev->bulk_in_pipe = 0;
usb_dev->bulk_out_pipe = 0;
host_interface = &interface->altsetting[0];
interface_desc = &host_interface->desc;
endpoints = interface_desc->bNumEndpoints;
/* Check device configuration */
if (usb->descriptor.bNumConfigurations != 1) {
usb_err("Number of configurations: %d not supported\n",
usb->descriptor.bNumConfigurations);
ret = -ENODEV;
goto exit;
}
/* Check deviceclass */
#ifndef CONFIG_USB_BT
if (usb->descriptor.bDeviceClass != 0x00) {
usb_err("DeviceClass %d not supported\n",
usb->descriptor.bDeviceClass);
ret = -ENODEV;
goto exit;
}
#endif
/* Check interface number */
#ifdef CONFIG_USB_BT
if (usb->actconfig->desc.bNumInterfaces != 3) {
#else
if (usb->actconfig->desc.bNumInterfaces != 1) {
#endif
usb_err("Number of interfaces: %d not supported\n",
usb->actconfig->desc.bNumInterfaces);
ret = -ENODEV;
goto exit;
}
if ((interface_desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
(interface_desc->bInterfaceSubClass != 0xff) ||
(interface_desc->bInterfaceProtocol != 0xff)) {
usb_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n",
interface_desc->bInterfaceNumber, interface_desc->bInterfaceClass,
interface_desc->bInterfaceSubClass, interface_desc->bInterfaceProtocol);
ret = -ENODEV;
goto exit;
}
for (i = 0; i < endpoints; i++) {
endpoint = &host_interface->endpoint[i].desc;
endpoint_num = usb_endpoint_num(endpoint);
if (usb_endpoint_dir_in(endpoint) &&
usb_endpoint_xfer_bulk(endpoint)) {
if (!usb_dev->bulk_in_pipe) {
usb_dev->bulk_in_pipe = usb_rcvbulkpipe(usb, endpoint_num);
}
}
if (usb_endpoint_dir_out(endpoint) &&
usb_endpoint_xfer_bulk(endpoint)) {
if (!usb_dev->bulk_out_pipe) {
usb_dev->bulk_out_pipe = usb_sndbulkpipe(usb, endpoint_num);
}
}
}
if (usb_dev->bulk_in_pipe == 0) {
usb_err("No RX (in) Bulk EP found\n");
ret = -ENODEV;
goto exit;
}
if (usb_dev->bulk_out_pipe == 0) {
usb_err("No TX (out) Bulk EP found\n");
ret = -ENODEV;
goto exit;
}
if (usb->speed == USB_SPEED_HIGH)
printk("Aic high speed USB device detected\n");
else
printk("Aic full speed USB device detected\n");
exit:
return ret;
}
static struct aicwf_bus_ops aicwf_usb_bus_ops = {
.start = aicwf_usb_bus_start,
.stop = aicwf_usb_bus_stop,
.txdata = aicwf_usb_bus_txdata,
.txmsg = aicwf_usb_bus_txmsg,
};
static int aicwf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
int ret = 0;
struct usb_device *usb = interface_to_usbdev(intf);
struct aicwf_bus *bus_if ;
struct device *dev = NULL;
struct aicwf_rx_priv *rx_priv = NULL;
struct aic_usb_dev *usb_dev = NULL;
usb_dev = kzalloc(sizeof(struct aic_usb_dev), GFP_ATOMIC);
if (!usb_dev) {
return -ENOMEM;
}
usb_dev->udev = usb;
usb_dev->dev = &usb->dev;
usb_set_intfdata(intf, usb_dev);
ret = aicwf_parse_usb(usb_dev, intf);
if (ret) {
usb_err("aicwf_parse_usb err %d\n", ret);
goto out_free;
}
ret = aicwf_usb_init(usb_dev);
if (ret) {
usb_err("aicwf_usb_init err %d\n", ret);
goto out_free;
}
bus_if = kzalloc(sizeof(struct aicwf_bus), GFP_ATOMIC);
if (!bus_if) {
ret = -ENOMEM;
goto out_free_usb;
}
dev = usb_dev->dev;
bus_if->dev = dev;
usb_dev->bus_if = bus_if;
bus_if->bus_priv.usb = usb_dev;
dev_set_drvdata(dev, bus_if);
bus_if->ops = &aicwf_usb_bus_ops;
rx_priv = aicwf_rx_init(usb_dev);
if (!rx_priv) {
txrx_err("rx init failed\n");
ret = -1;
goto out_free_bus;
}
usb_dev->rx_priv = rx_priv;
ret = aicwf_bus_init(0, dev);
if (ret < 0) {
usb_err("aicwf_bus_init err %d\n", ret);
goto out_free_bus;
}
ret = aicwf_bus_start(bus_if);
if (ret < 0) {
usb_err("aicwf_bus_start err %d\n", ret);
goto out_free_bus;
}
aicwf_rwnx_usb_platform_init(usb_dev);
aicwf_hostif_ready();
return 0;
out_free_bus:
aicwf_bus_deinit(dev);
kfree(bus_if);
out_free_usb:
aicwf_usb_deinit(usb_dev);
out_free:
usb_err("failed with errno %d\n", ret);
kfree(usb_dev);
usb_set_intfdata(intf, NULL);
return ret;
}
static void aicwf_usb_disconnect(struct usb_interface *intf)
{
struct aic_usb_dev *usb_dev =
(struct aic_usb_dev *) usb_get_intfdata(intf);
if (!usb_dev)
return;
aicwf_bus_deinit(usb_dev->dev);
aicwf_usb_deinit(usb_dev);
rwnx_cmd_mgr_deinit(&usb_dev->cmd_mgr);
if (usb_dev->rx_priv)
aicwf_rx_deinit(usb_dev->rx_priv);
kfree(usb_dev->bus_if);
kfree(usb_dev);
}
static int aicwf_usb_suspend(struct usb_interface *intf, pm_message_t state)
{
struct aic_usb_dev *usb_dev =
(struct aic_usb_dev *) usb_get_intfdata(intf);
aicwf_usb_state_change(usb_dev, USB_SLEEP_ST);
aicwf_bus_stop(usb_dev->bus_if);
return 0;
}
static int aicwf_usb_resume(struct usb_interface *intf)
{
struct aic_usb_dev *usb_dev =
(struct aic_usb_dev *) usb_get_intfdata(intf);
if (usb_dev->state == USB_UP_ST)
return 0;
aicwf_bus_start(usb_dev->bus_if);
return 0;
}
static int aicwf_usb_reset_resume(struct usb_interface *intf)
{
return aicwf_usb_resume(intf);
}
static struct usb_device_id aicwf_usb_id_table[] = {
#ifndef CONFIG_USB_BT
{USB_DEVICE(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC)},
#else
{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_AIC, USB_PRODUCT_ID_AIC, 0xff, 0xff, 0xff)},
#endif
{}
};
MODULE_DEVICE_TABLE(usb, aicwf_usb_id_table);
static struct usb_driver aicwf_usbdrvr = {
.name = KBUILD_MODNAME,
.probe = aicwf_usb_probe,
.disconnect = aicwf_usb_disconnect,
.id_table = aicwf_usb_id_table,
.suspend = aicwf_usb_suspend,
.resume = aicwf_usb_resume,
.reset_resume = aicwf_usb_reset_resume,
.supports_autosuspend = 1,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)
.disable_hub_initiated_lpm = 1,
#endif
};
void aicwf_usb_register(void)
{
if (usb_register(&aicwf_usbdrvr) < 0) {
usb_err("usb_register failed\n");
}
}
void aicwf_usb_exit(void)
{
if (g_rwnx_plat && g_rwnx_plat->enabled)
rwnx_platform_deinit(g_rwnx_plat->usbdev->rwnx_hw);
usb_deregister(&aicwf_usbdrvr);
kfree(g_rwnx_plat);
}

View File

@ -0,0 +1,99 @@
/**
* aicwf_usb.h
*
* USB function declarations
*
* Copyright (C) AICSemi 2018-2020
*/
#ifndef _AICWF_USB_H_
#define _AICWF_USB_H_
#include <linux/usb.h>
#include "rwnx_cmds.h"
#ifdef AICWF_USB_SUPPORT
/* USB Device ID */
#define USB_VENDOR_ID_AIC 0xA69C
#ifndef CONFIG_USB_BT
#define USB_PRODUCT_ID_AIC 0x8800
#else
#define USB_PRODUCT_ID_AIC 0x8801
#endif
#define AICWF_USB_RX_URBS (200)
#define AICWF_USB_TX_URBS (100)
#define AICWF_USB_TX_LOW_WATER (AICWF_USB_TX_URBS/4)
#define AICWF_USB_TX_HIGH_WATER (AICWF_USB_TX_LOW_WATER*3)
#define AICWF_USB_MAX_PKT_SIZE (2048)
typedef enum {
USB_TYPE_DATA = 0X00,
USB_TYPE_CFG = 0X10,
USB_TYPE_CFG_CMD_RSP = 0X11,
USB_TYPE_CFG_DATA_CFM = 0X12
} usb_type;
enum aicwf_usb_state {
USB_DOWN_ST,
USB_UP_ST,
USB_SLEEP_ST
};
struct aicwf_usb_buf {
struct list_head list;
struct aic_usb_dev *usbdev;
struct urb *urb;
struct sk_buff *skb;
bool cfm;
};
struct aic_usb_dev {
struct rwnx_hw *rwnx_hw;
struct aicwf_bus *bus_if;
struct usb_device *udev;
struct device *dev;
struct aicwf_rx_priv *rx_priv;
enum aicwf_usb_state state;
struct rwnx_cmd_mgr cmd_mgr;
struct usb_anchor rx_submitted;
struct work_struct rx_urb_work;
spinlock_t rx_free_lock;
spinlock_t tx_free_lock;
spinlock_t tx_post_lock;
spinlock_t tx_flow_lock;
struct list_head rx_free_list;
struct list_head tx_free_list;
struct list_head tx_post_list;
uint bulk_in_pipe;
uint bulk_out_pipe;
int tx_free_count;
int tx_post_count;
struct aicwf_usb_buf usb_tx_buf[AICWF_USB_TX_URBS];
struct aicwf_usb_buf usb_rx_buf[AICWF_USB_RX_URBS];
int msg_finished;
wait_queue_head_t msg_wait;
ulong msg_busy;
struct urb *msg_out_urb;
bool tbusy;
};
extern void aicwf_usb_exit(void);
extern void aicwf_usb_register(void);
extern void aicwf_usb_tx_flowctrl(struct rwnx_hw *rwnx_hw, bool state);
int usb_bustx_thread(void *data);
int usb_busrx_thread(void *data);
extern void aicwf_hostif_ready(void);
#endif /* AICWF_USB_SUPPORT */
#endif /* _AICWF_USB_H_ */

View File

@ -0,0 +1,353 @@
/**
******************************************************************************
*
* @file hal_desc.h
*
* @brief File containing the definition of HW descriptors.
*
* Contains the definition and structures used by HW
*
* Copyright (C) RivieraWaves 2011-2019
*
******************************************************************************
*/
#ifndef _HAL_DESC_H_
#define _HAL_DESC_H_
#include "lmac_types.h"
/* Rate and policy table */
#define N_CCK 8
#define N_OFDM 8
#define N_HT (8 * 2 * 2 * 4)
#define N_VHT (10 * 4 * 2 * 8)
#define N_HE_SU (12 * 4 * 3 * 8)
#define N_HE_MU (12 * 6 * 3 * 8)
#define N_HE_ER (3 * 3 + 3) //RU242 + RU106
/* conversion table from NL80211 to MACHW enum */
extern const int chnl2bw[];
/* conversion table from MACHW to NL80211 enum */
extern const int bw2chnl[];
/* Values for formatModTx */
#define FORMATMOD_NON_HT 0
#define FORMATMOD_NON_HT_DUP_OFDM 1
#define FORMATMOD_HT_MF 2
#define FORMATMOD_HT_GF 3
#define FORMATMOD_VHT 4
#define FORMATMOD_HE_SU 5
#define FORMATMOD_HE_MU 6
#define FORMATMOD_HE_ER 7
#define FORMATMOD_HE_TB 8
/* Values for navProtFrmEx */
#define NAV_PROT_NO_PROT_BIT 0
#define NAV_PROT_SELF_CTS_BIT 1
#define NAV_PROT_RTS_CTS_BIT 2
#define NAV_PROT_RTS_CTS_WITH_QAP_BIT 3
#define NAV_PROT_STBC_BIT 4
/* THD MACCTRLINFO2 fields, used in struct umacdesc umac.flags */
/// WhichDescriptor definition - contains aMPDU bit and position value
/// Offset of WhichDescriptor field in the MAC CONTROL INFO 2 word
#define WHICHDESC_OFT 19
/// Mask of the WhichDescriptor field
#define WHICHDESC_MSK (0x07 << WHICHDESC_OFT)
/// Only 1 THD possible, describing an unfragmented MSDU
#define WHICHDESC_UNFRAGMENTED_MSDU (0x00 << WHICHDESC_OFT)
/// THD describing the first MPDU of a fragmented MSDU
#define WHICHDESC_FRAGMENTED_MSDU_FIRST (0x01 << WHICHDESC_OFT)
/// THD describing intermediate MPDUs of a fragmented MSDU
#define WHICHDESC_FRAGMENTED_MSDU_INT (0x02 << WHICHDESC_OFT)
/// THD describing the last MPDU of a fragmented MSDU
#define WHICHDESC_FRAGMENTED_MSDU_LAST (0x03 << WHICHDESC_OFT)
/// THD for extra descriptor starting an AMPDU
#define WHICHDESC_AMPDU_EXTRA (0x04 << WHICHDESC_OFT)
/// THD describing the first MPDU of an A-MPDU
#define WHICHDESC_AMPDU_FIRST (0x05 << WHICHDESC_OFT)
/// THD describing intermediate MPDUs of an A-MPDU
#define WHICHDESC_AMPDU_INT (0x06 << WHICHDESC_OFT)
/// THD describing the last MPDU of an A-MPDU
#define WHICHDESC_AMPDU_LAST (0x07 << WHICHDESC_OFT)
/// aMPDU bit offset
#define AMPDU_OFT 21
/// aMPDU bit
#define AMPDU_BIT CO_BIT(AMPDU_OFT)
union rwnx_mcs_index {
struct {
u32 mcs : 3;
u32 nss : 2;
} ht;
struct {
u32 mcs : 4;
u32 nss : 3;
} vht;
struct {
u32 mcs : 4;
u32 nss : 3;
} he;
u32 legacy : 7;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
union rwnx_rate_ctrl_info {
struct {
u32 mcsIndexTx : 7;
u32 bwTx : 2;
u32 giAndPreTypeTx : 2;
u32 formatModTx : 3;
u32 navProtFrmEx : 3;
u32 mcsIndexProtTx : 7;
u32 bwProtTx : 2;
u32 formatModProtTx : 3;
u32 nRetry : 3;
};
u32 value;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
struct rwnx_power_ctrl_info {
u32 txPwrLevelPT : 8;
u32 txPwrLevelProtPT : 8;
u32 reserved :16;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
union rwnx_pol_phy_ctrl_info_1 {
struct {
u32 rsvd1 : 3;
u32 bfFrmEx : 1;
u32 numExtnSS : 2;
u32 fecCoding : 1;
u32 stbc : 2;
u32 rsvd2 : 5;
u32 nTx : 3;
u32 nTxProt : 3;
};
u32 value;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
union rwnx_pol_phy_ctrl_info_2 {
struct {
u32 antennaSet : 8;
u32 smmIndex : 8;
u32 beamFormed : 1;
};
u32 value;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
union rwnx_pol_mac_ctrl_info_1 {
struct {
u32 keySRamIndex : 10;
u32 keySRamIndexRA : 10;
};
u32 value;
};
/* c.f RW-WLAN-nX-MAC-HW-UM */
union rwnx_pol_mac_ctrl_info_2 {
struct {
u32 longRetryLimit : 8;
u32 shortRetryLimit : 8;
u32 rtsThreshold : 12;
};
u32 value;
};
#define POLICY_TABLE_PATTERN 0xBADCAB1E
struct tx_policy_tbl {
/* Unique Pattern at the start of Policy Table */
u32 upatterntx;
/* PHY Control 1 Information used by MAC HW */
union rwnx_pol_phy_ctrl_info_1 phyctrlinfo_1;
/* PHY Control 2 Information used by MAC HW */
union rwnx_pol_phy_ctrl_info_2 phyctrlinfo_2;
/* MAC Control 1 Information used by MAC HW */
union rwnx_pol_mac_ctrl_info_1 macctrlinfo_1;
/* MAC Control 2 Information used by MAC HW */
union rwnx_pol_mac_ctrl_info_2 macctrlinfo_2;
union rwnx_rate_ctrl_info ratectrlinfos[NX_TX_MAX_RATES];
struct rwnx_power_ctrl_info powerctrlinfos[NX_TX_MAX_RATES];
};
#ifdef CONFIG_RWNX_FULLMAC
/**
* struct rwnx_hw_txstatus - Bitfield of confirmation status
*
* @tx_done: packet has been processed by the firmware.
* @retry_required: packet has been transmitted but not acknoledged.
* Driver must repush it.
* @sw_retry_required: packet has not been transmitted (FW wasn't able to push
* it when it received it: not active channel ...). Driver must repush it.
* @acknowledged: packet has been acknowledged by peer
*/
union rwnx_hw_txstatus {
struct {
u32 tx_done : 1;
u32 retry_required : 1;
u32 sw_retry_required : 1;
u32 acknowledged : 1;
u32 reserved :28;
};
u32 value;
};
/**
* struct tx_cfm_tag - Structure indicating the status and other
* information about the transmission
*
* @pn: PN that was used for the transmission
* @sn: Sequence number of the packet
* @timestamp: Timestamp of first transmission of this MPDU
* @credits: Number of credits to be reallocated for the txq that push this
* buffer (can be 0 or 1)
* @ampdu_size: Size of the ampdu in which the frame has been transmitted if
* this was the last frame of the a-mpdu, and 0 if the frame is not the last
* frame on a a-mdpu.
* 1 means that the frame has been transmitted as a singleton.
* @amsdu_size: Size, in bytes, allowed to create a-msdu.
* @status: transmission status
*/
struct tx_cfm_tag {
/*
u16_l pn[4];
u16_l sn;
u16_l timestamp;
*/
s8_l credits;
u8_l ampdu_size;
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
u16_l amsdu_size;
#endif
union rwnx_hw_txstatus status;
u32_l hostid;
};
/**
* struct rwnx_hw_txhdr - Hardware part of tx header
*
* @cfm: Information updated by fw/hardware after sending a frame
*/
struct rwnx_hw_txhdr {
struct tx_cfm_tag cfm;
};
#endif /* CONFIG_RWNX_FULLMAC */
/* Modem */
#define MDM_PHY_CONFIG_TRIDENT 0
#define MDM_PHY_CONFIG_ELMA 1
#define MDM_PHY_CONFIG_KARST 2
// MODEM features (from reg_mdm_stat.h)
/// MUMIMOTX field bit
#define MDM_MUMIMOTX_BIT ((u32)0x80000000)
/// MUMIMOTX field position
#define MDM_MUMIMOTX_POS 31
/// MUMIMORX field bit
#define MDM_MUMIMORX_BIT ((u32)0x40000000)
/// MUMIMORX field position
#define MDM_MUMIMORX_POS 30
/// BFMER field bit
#define MDM_BFMER_BIT ((u32)0x20000000)
/// BFMER field position
#define MDM_BFMER_POS 29
/// BFMEE field bit
#define MDM_BFMEE_BIT ((u32)0x10000000)
/// BFMEE field position
#define MDM_BFMEE_POS 28
/// LDPCDEC field bit
#define MDM_LDPCDEC_BIT ((u32)0x08000000)
/// LDPCDEC field position
#define MDM_LDPCDEC_POS 27
/// LDPCENC field bit
#define MDM_LDPCENC_BIT ((u32)0x04000000)
/// LDPCENC field position
#define MDM_LDPCENC_POS 26
/// CHBW field mask
#define MDM_CHBW_MASK ((u32)0x03000000)
/// CHBW field LSB position
#define MDM_CHBW_LSB 24
/// CHBW field width
#define MDM_CHBW_WIDTH ((u32)0x00000002)
/// DSSSCCK field bit
#define MDM_DSSSCCK_BIT ((u32)0x00800000)
/// DSSSCCK field position
#define MDM_DSSSCCK_POS 23
/// VHT field bit
#define MDM_VHT_BIT ((u32)0x00400000)
/// VHT field position
#define MDM_VHT_POS 22
/// HE field bit
#define MDM_HE_BIT ((u32)0x00200000)
/// HE field position
#define MDM_HE_POS 21
/// ESS field bit
#define MDM_ESS_BIT ((u32)0x00100000)
/// ESS field position
#define MDM_ESS_POS 20
/// RFMODE field mask
#define MDM_RFMODE_MASK ((u32)0x000F0000)
/// RFMODE field LSB position
#define MDM_RFMODE_LSB 16
/// RFMODE field width
#define MDM_RFMODE_WIDTH ((u32)0x00000004)
/// NSTS field mask
#define MDM_NSTS_MASK ((u32)0x0000F000)
/// NSTS field LSB position
#define MDM_NSTS_LSB 12
/// NSTS field width
#define MDM_NSTS_WIDTH ((u32)0x00000004)
/// NSS field mask
#define MDM_NSS_MASK ((u32)0x00000F00)
/// NSS field LSB position
#define MDM_NSS_LSB 8
/// NSS field width
#define MDM_NSS_WIDTH ((u32)0x00000004)
/// NTX field mask
#define MDM_NTX_MASK ((u32)0x000000F0)
/// NTX field LSB position
#define MDM_NTX_LSB 4
/// NTX field width
#define MDM_NTX_WIDTH ((u32)0x00000004)
/// NRX field mask
#define MDM_NRX_MASK ((u32)0x0000000F)
/// NRX field LSB position
#define MDM_NRX_LSB 0
/// NRX field width
#define MDM_NRX_WIDTH ((u32)0x00000004)
#define __MDM_PHYCFG_FROM_VERS(v) (((v) & MDM_RFMODE_MASK) >> MDM_RFMODE_LSB)
#define RIU_FCU_PRESENT_MASK ((u32)0xFF000000)
#define RIU_FCU_PRESENT_LSB 24
#define __RIU_FCU_PRESENT(v) (((v) & RIU_FCU_PRESENT_MASK) >> RIU_FCU_PRESENT_LSB == 5)
/// AGC load version field mask
#define RIU_AGC_LOAD_MASK ((u32)0x00C00000)
/// AGC load version field LSB position
#define RIU_AGC_LOAD_LSB 22
#define __RIU_AGCLOAD_FROM_VERS(v) (((v) & RIU_AGC_LOAD_MASK) >> RIU_AGC_LOAD_LSB)
#define __FPGA_TYPE(v) (((v) & 0xFFFF0000) >> 16)
#define __MDM_MAJOR_VERSION(v) (((v) & 0xFF000000) >> 24)
#define __MDM_MINOR_VERSION(v) (((v) & 0x00FF0000) >> 16)
#define __MDM_VERSION(v) ((__MDM_MAJOR_VERSION(v) + 2) * 10 + __MDM_MINOR_VERSION(v))
#endif // _HAL_DESC_H_

View File

@ -0,0 +1,25 @@
/**
****************************************************************************************
*
* @file ipc_compat.h
*
* Copyright (C) RivieraWaves 2011-2019
*
****************************************************************************************
*/
#ifndef _IPC_H_
#define _IPC_H_
#define __INLINE inline
#define __ALIGN4 __aligned(4)
#define ASSERT_ERR(condition) \
do { \
if (unlikely(!(condition))) { \
printk(KERN_ERR "%s:%d:ASSERT_ERR(" #condition ")\n", __FILE__, __LINE__); \
} \
} while (0)
#endif /* _IPC_H_ */

View File

@ -0,0 +1,52 @@
/**
******************************************************************************
*
* @file ipc_host.c
*
* @brief IPC module.
*
* Copyright (C) RivieraWaves 2011-2019
*
******************************************************************************
*/
/*
* INCLUDE FILES
******************************************************************************
*/
#ifndef __KERNEL__
#include <stdio.h>
#else
#include <linux/spinlock.h>
#include "rwnx_defs.h"
#include "rwnx_prof.h"
#endif
#include "ipc_host.h"
/*
* TYPES DEFINITION
******************************************************************************
*/
const int nx_txdesc_cnt[] = {
NX_TXDESC_CNT0,
NX_TXDESC_CNT1,
NX_TXDESC_CNT2,
NX_TXDESC_CNT3,
#if NX_TXQ_CNT == 5
NX_TXDESC_CNT4,
#endif
};
const int nx_txuser_cnt[] = {
CONFIG_USER_MAX,
CONFIG_USER_MAX,
CONFIG_USER_MAX,
CONFIG_USER_MAX,
#if NX_TXQ_CNT == 5
1,
#endif
};

View File

@ -0,0 +1,168 @@
/**
******************************************************************************
*
* @file ipc_host.h
*
* @brief IPC module.
*
* Copyright (C) RivieraWaves 2011-2019
*
******************************************************************************
*/
#ifndef _IPC_HOST_H_
#define _IPC_HOST_H_
/*
* INCLUDE FILES
******************************************************************************
*/
#include "ipc_shared.h"
#ifndef __KERNEL__
#include "arch.h"
#else
#include "ipc_compat.h"
#endif
/**
******************************************************************************
* @brief This structure is used to initialize the MAC SW
*
* The WLAN device driver provides functions call-back with this structure
******************************************************************************
*/
struct ipc_host_cb_tag {
/// WLAN driver call-back function: send_data_cfm
int (*send_data_cfm)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_data_ind
uint8_t (*recv_data_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_radar_ind
uint8_t (*recv_radar_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_unsup_rx_vec_ind
uint8_t (*recv_unsup_rx_vec_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_msg_ind
uint8_t (*recv_msg_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_msgack_ind
uint8_t (*recv_msgack_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: recv_dbg_ind
uint8_t (*recv_dbg_ind)(void *pthis, void *host_id);
/// WLAN driver call-back function: prim_tbtt_ind
void (*prim_tbtt_ind)(void *pthis);
/// WLAN driver call-back function: sec_tbtt_ind
void (*sec_tbtt_ind)(void *pthis);
};
/*
* Struct used to store information about host buffers (DMA Address and local pointer)
*/
struct ipc_hostbuf {
void *hostid; ///< ptr to hostbuf client (ipc_host client) structure
uint32_t dma_addr; ///< ptr to real hostbuf dma address
};
/// Definition of the IPC Host environment structure.
struct ipc_host_env_tag {
/// Structure containing the callback pointers
struct ipc_host_cb_tag cb;
/// Pointer to the shared environment
struct ipc_shared_env_tag *shared;
#ifdef CONFIG_RWNX_FULLMAC
// Array used to store the descriptor addresses
struct ipc_hostbuf ipc_host_rxdesc_array[IPC_RXDESC_CNT];
// Index of the host RX descriptor array (ipc_shared environment)
uint8_t ipc_host_rxdesc_idx;
/// Store the number of RX Descriptors
uint8_t rxdesc_nb;
#endif //(CONFIG_RWNX_FULLMAC)
/// Fields for Data Rx handling
// Index used for ipc_host_rxbuf_array to point to current buffer
uint8_t ipc_host_rxbuf_idx;
// Store the number of Rx Data buffers
uint32_t rx_bufnb;
// Store the size of the Rx Data buffers
uint32_t rx_bufsz;
/// Fields for Radar events handling
// Global array used to store the hostid and hostbuf addresses
struct ipc_hostbuf ipc_host_radarbuf_array[IPC_RADARBUF_CNT];
// Index used for ipc_host_rxbuf_array to point to current buffer
uint8_t ipc_host_radarbuf_idx;
// Store the number of radar event buffers
uint32_t radar_bufnb;
// Store the size of the radar event buffers
uint32_t radar_bufsz;
///Fields for Unsupported frame handling
// Global array used to store the hostid and hostbuf addresses
struct ipc_hostbuf ipc_host_unsuprxvecbuf_array[IPC_UNSUPRXVECBUF_CNT];
// Index used for ipc_host_unsuprxvecbuf_array to point to current buffer
uint8_t ipc_host_unsuprxvecbuf_idx;
// Store the number of unsupported rx vector buffers
uint32_t unsuprxvec_bufnb;
// Store the size of unsupported rx vector buffers
uint32_t unsuprxvec_bufsz;
// Index used that points to the first free TX desc
uint32_t txdesc_free_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
// Index used that points to the first used TX desc
uint32_t txdesc_used_idx[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
// Array storing the currently pushed host ids for the BK queue
void *tx_host_id0[CONFIG_USER_MAX][NX_TXDESC_CNT0];
// Array storing the currently pushed host ids for the BE queue
void *tx_host_id1[CONFIG_USER_MAX][NX_TXDESC_CNT1];
// Array storing the currently pushed host ids for the VI queue
void *tx_host_id2[CONFIG_USER_MAX][NX_TXDESC_CNT2];
// Array storing the currently pushed host ids for the VO queue
void *tx_host_id3[CONFIG_USER_MAX][NX_TXDESC_CNT3];
#if NX_TXQ_CNT == 5
// Array storing the currently pushed host ids for the BCN queue
void *tx_host_id4[1][NX_TXDESC_CNT4];
#endif
// Pointer to the different host ids arrays, per IPC queue
void **tx_host_id[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
// Pointer to the different TX descriptor arrays, per IPC queue
volatile struct txdesc_host *txdesc[IPC_TXQUEUE_CNT][CONFIG_USER_MAX];
/// Fields for Emb->App MSGs handling
// Global array used to store the hostid and hostbuf addresses for msg/ind
struct ipc_hostbuf ipc_host_msgbuf_array[IPC_MSGE2A_BUF_CNT];
// Index of the MSG E2A buffers array to point to current buffer
uint8_t ipc_host_msge2a_idx;
// Store the number of E2A MSG buffers
uint32_t ipc_e2amsg_bufnb;
// Store the size of the E2A MSG buffers
uint32_t ipc_e2amsg_bufsz;
/// E2A ACKs of A2E MSGs
uint8_t msga2e_cnt;
void *msga2e_hostid;
/// Fields for Debug MSGs handling
// Global array used to store the hostid and hostbuf addresses for Debug messages
struct ipc_hostbuf ipc_host_dbgbuf_array[IPC_DBGBUF_CNT];
// Index of the Debug messages buffers array to point to current buffer
uint8_t ipc_host_dbg_idx;
// Store the number of Debug messages buffers
uint32_t ipc_dbg_bufnb;
// Store the size of the Debug messages buffers
uint32_t ipc_dbg_bufsz;
/// Pointer to the attached object (used in callbacks and register accesses)
void *pthis;
};
extern const int nx_txdesc_cnt[];
extern const int nx_txuser_cnt[];
#endif // _IPC_HOST_H_

View File

@ -0,0 +1,785 @@
/**
****************************************************************************************
*
* @file ipc_shared.h
*
* @brief Shared data between both IPC modules.
*
* Copyright (C) RivieraWaves 2011-2019
*
****************************************************************************************
*/
#ifndef _IPC_SHARED_H_
#define _IPC_SHARED_H_
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "ipc_compat.h"
#include "lmac_mac.h"
/*
* DEFINES AND MACROS
****************************************************************************************
*/
#define CO_BIT(pos) (1U<<(pos))
#define IPC_TXQUEUE_CNT NX_TXQ_CNT
#define NX_TXDESC_CNT0 8
#define NX_TXDESC_CNT1 64
#define NX_TXDESC_CNT2 64
#define NX_TXDESC_CNT3 32
#if NX_TXQ_CNT == 5
#define NX_TXDESC_CNT4 8
#endif
/*
* Number of Host buffers available for Data Rx handling (through DMA)
*/
#define IPC_RXBUF_CNT 128
/*
* Number of shared descriptors available for Data RX handling
*/
#define IPC_RXDESC_CNT 128
/*
* Number of Host buffers available for Radar events handling (through DMA)
*/
#define IPC_RADARBUF_CNT 16
/*
* Number of Host buffers available for unsupported Rx vectors handling (through DMA)
*/
#define IPC_UNSUPRXVECBUF_CNT 8
/*
* Size of RxVector
*/
#define IPC_RXVEC_SIZE 16
/*
* Number of Host buffers available for Emb->App MSGs sending (through DMA)
*/
#ifdef CONFIG_RWNX_FULLMAC
#define IPC_MSGE2A_BUF_CNT 64
#endif
/*
* Number of Host buffers available for Debug Messages sending (through DMA)
*/
#define IPC_DBGBUF_CNT 32
/*
* Length used in MSGs structures
*/
#define IPC_A2E_MSG_BUF_SIZE 127 // size in 4-byte words
#ifdef CONFIG_RWNX_FULLMAC
#define IPC_E2A_MSG_SIZE_BASE 256 // size in 4-byte words
#endif
#ifdef CONFIG_RWNX_TL4
#define IPC_E2A_MSG_PARAM_SIZE (IPC_E2A_MSG_SIZE_BASE + (IPC_E2A_MSG_SIZE_BASE / 2))
#else
#define IPC_E2A_MSG_PARAM_SIZE IPC_E2A_MSG_SIZE_BASE
#endif
/*
* Debug messages buffers size (in bytes)
*/
#define IPC_DBG_PARAM_SIZE 256
/*
* Define used for Rx hostbuf validity.
* This value should appear only when hostbuf was used for a Reception.
*/
#define RX_DMA_OVER_PATTERN 0xAAAAAA00
/*
* Define used for MSG buffers validity.
* This value will be written only when a MSG buffer is used for sending from Emb to App.
*/
#define IPC_MSGE2A_VALID_PATTERN 0xADDEDE2A
/*
* Define used for Debug messages buffers validity.
* This value will be written only when a DBG buffer is used for sending from Emb to App.
*/
#define IPC_DBG_VALID_PATTERN 0x000CACA0
/*
* Length of the receive vectors, in bytes
*/
#define DMA_HDR_PHYVECT_LEN 36
/*
* Maximum number of payload addresses and lengths present in the descriptor
*/
#ifdef CONFIG_RWNX_SPLIT_TX_BUF
#define NX_TX_PAYLOAD_MAX 6
#else
#define NX_TX_PAYLOAD_MAX 1
#endif
/*
* Message struct/ID API version
*/
#define MSG_API_VER 33
/*
****************************************************************************************
*/
// c.f LMAC/src/tx/tx_swdesc.h
/// Descriptor filled by the Host
struct hostdesc {
/// Pointer to packet payload
//u32_l packet_addr;
/// Size of the payload
u16_l packet_len;
u16_l flags_ext;
u32_l hostid;
#ifdef CONFIG_RWNX_FULLMAC
/// Address of the status descriptor in host memory (used for confirmation upload)
//u32_l status_desc_addr;
/// Destination Address
struct mac_addr eth_dest_addr;
/// Source Address
struct mac_addr eth_src_addr;
/// Ethernet Type
u16_l ethertype;
#else /* ! CONFIG_RWNX_FULLMAC */
#ifdef CONFIG_RWNX_AGG_TX
///Sequence Number for AMPDU MPDUs - for quick check if it's allowed within window
u16_l sn;
#endif /* CONFIG_RWNX_AGG_TX */
/// 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
u8_l vif_idx;
/// Station Id (0xFF if station is unknown)
u8_l staid;
#ifdef CONFIG_RWNX_MUMIMO_TX
/// MU-MIMO information (GroupId and User Position in the group) - The GroupId
/// is located on bits 0-5 and the User Position on bits 6-7. The GroupId value is set
/// to 63 if MU-MIMO shall not be used
u8_l mumimo_info;
#endif /* CONFIG_RWNX_MUMIMO_TX */
#ifdef CONFIG_RWNX_FULLMAC
/// TX flags
u16_l flags;
#endif /* CONFIG_RWNX_FULLMAC */
};
/// Descriptor filled by the UMAC
struct umacdesc {
#ifdef CONFIG_RWNX_AGG_TX
///First Sequence Number of the BlockAck window
u16_l sn_win;
/// Flags from UMAC (match tx_hd.macctrlinfo2 format)
u32_l flags;
/// PHY related flags field - rate, GI type, BW type - filled by driver
u32_l phy_flags;
#endif //(CONFIG_RWNX_AGG_TX)
};
struct txdesc_api {
/// Information provided by Host
struct hostdesc host;
};
struct txdesc_host {
u32_l ready;
/// API of the embedded part
struct txdesc_api api;
};
/// Comes from ipc_dma.h
/// Element in the pool of TX DMA bridge descriptors.
struct dma_desc {
/** Application subsystem address which is used as source address for DMA payload
* transfer*/
u32_l src;
/** Points to the start of the embedded data buffer associated with this descriptor.
* This address acts as the destination address for the DMA payload transfer*/
u32_l dest;
/// Complete length of the buffer in memory
u16_l length;
/// Control word for the DMA engine (e.g. for interrupt generation)
u16_l ctrl;
/// Pointer to the next element of the chained list
u32_l next;
};
// Comes from la.h
/// Length of the configuration data of a logic analyzer
#define LA_CONF_LEN 10
/// Structure containing the configuration data of a logic analyzer
struct la_conf_tag {
u32_l conf[LA_CONF_LEN];
u32_l trace_len;
u32_l diag_conf;
};
/// Size of a logic analyzer memory
#define LA_MEM_LEN (1024 * 1024)
/// Type of errors
enum {
/// Recoverable error, not requiring any action from Upper MAC
DBG_ERROR_RECOVERABLE = 0,
/// Fatal error, requiring Upper MAC to reset Lower MAC and HW and restart operation
DBG_ERROR_FATAL
};
/// Maximum length of the SW diag trace
#define DBG_SW_DIAG_MAX_LEN 1024
/// Maximum length of the error trace
#define DBG_ERROR_TRACE_SIZE 256
/// Number of MAC diagnostic port banks
#define DBG_DIAGS_MAC_MAX 48
/// Number of PHY diagnostic port banks
#define DBG_DIAGS_PHY_MAX 32
/// Maximum size of the RX header descriptor information in the debug dump
#define DBG_RHD_MEM_LEN (5 * 1024)
/// Maximum size of the RX buffer descriptor information in the debug dump
#define DBG_RBD_MEM_LEN (5 * 1024)
/// Maximum size of the TX header descriptor information in the debug dump
#define DBG_THD_MEM_LEN (10 * 1024)
/// Structure containing the information about the PHY channel that is used
struct phy_channel_info {
/// PHY channel information 1
u32_l info1;
/// PHY channel information 2
u32_l info2;
};
/// Debug information forwarded to host when an error occurs
struct dbg_debug_info_tag {
/// Type of error (0: recoverable, 1: fatal)
u32_l error_type;
/// Pointer to the first RX Header Descriptor chained to the MAC HW
u32_l rhd;
/// Size of the RX header descriptor buffer
u32_l rhd_len;
/// Pointer to the first RX Buffer Descriptor chained to the MAC HW
u32_l rbd;
/// Size of the RX buffer descriptor buffer
u32_l rbd_len;
/// Pointer to the first TX Header Descriptors chained to the MAC HW
u32_l thd[NX_TXQ_CNT];
/// Size of the TX header descriptor buffer
u32_l thd_len[NX_TXQ_CNT];
/// MAC HW diag configuration
u32_l hw_diag;
/// Error message
u32_l error[DBG_ERROR_TRACE_SIZE/4];
/// SW diag configuration length
u32_l sw_diag_len;
/// SW diag configuration
u32_l sw_diag[DBG_SW_DIAG_MAX_LEN/4];
/// PHY channel information
struct phy_channel_info chan_info;
/// Embedded LA configuration
struct la_conf_tag la_conf;
/// MAC diagnostic port state
u16_l diags_mac[DBG_DIAGS_MAC_MAX];
/// PHY diagnostic port state
u16_l diags_phy[DBG_DIAGS_PHY_MAX];
/// MAC HW RX Header descriptor pointer
u32_l rhd_hw_ptr;
/// MAC HW RX Buffer descriptor pointer
u32_l rbd_hw_ptr;
};
/// Full debug dump that is forwarded to host in case of error
struct dbg_debug_dump_tag {
/// Debug information
struct dbg_debug_info_tag dbg_info;
/// RX header descriptor memory
u32_l rhd_mem[DBG_RHD_MEM_LEN/4];
/// RX buffer descriptor memory
u32_l rbd_mem[DBG_RBD_MEM_LEN/4];
/// TX header descriptor memory
u32_l thd_mem[NX_TXQ_CNT][DBG_THD_MEM_LEN/4];
/// Logic analyzer memory
u32_l la_mem[LA_MEM_LEN/4];
};
/// Number of pulses in a radar event structure
#define RADAR_PULSE_MAX 4
/// Definition of an array of radar pulses
struct radar_pulse_array_desc {
/// Buffer containing the radar pulses
u32_l pulse[RADAR_PULSE_MAX];
/// Index of the radar detection chain that detected those pulses
u32_l idx;
/// Number of valid pulses in the buffer
u32_l cnt;
};
/// Bit mapping inside a radar pulse element
struct radar_pulse {
s32_l freq:6; /** Freq (resolution is 2Mhz range is [-Fadc/4 .. Fadc/4]) */
u32_l fom:4; /** Figure of Merit */
u32_l len:6; /** Length of the current radar pulse (resolution is 2us) */
u32_l rep:16; /** Time interval between the previous radar event
and the current one (in us) */
};
/// Definition of a RX vector descriptor
struct rx_vector_desc {
/// PHY channel information
struct phy_channel_info phy_info;
/// RX vector 1
u32_l rx_vect1[IPC_RXVEC_SIZE/4];
/// Used to print a valid rx vector
u32_l pattern;
};
///
struct rxdesc_tag {
/// Host Buffer Address
u32_l host_id;
/// Length
u32_l frame_len;
/// Status
u16_l status;
};
/**
****************************************************************************************
* @defgroup IPC IPC
* @ingroup NXMAC
* @brief Inter Processor Communication module.
*
* The IPC module implements the protocol to communicate between the Host CPU
* and the Embedded CPU.
*
* @see http://en.wikipedia.org/wiki/Circular_buffer
* For more information about the ring buffer typical use and difficulties.
****************************************************************************************
*/
/**
****************************************************************************************
* @addtogroup IPC_TX IPC Tx path
* @ingroup IPC
* @brief IPC Tx path structures and functions
*
* A typical use case of the IPC Tx path API:
* @msc
* hscale = "2";
*
* a [label=Driver],
* b [label="IPC host"],
* c [label="IPC emb"],
* d [label=Firmware];
*
* --- [label="Tx descriptor queue example"];
* a=>a [label="Driver receives a Tx packet from OS"];
* a=>b [label="ipc_host_txdesc_get()"];
* a<<b [label="struct txdesc_host *"];
* a=>a [label="Driver fill the descriptor"];
* a=>b [label="ipc_host_txdesc_push()"];
* ... [label="(several Tx desc can be pushed)"];
* b:>c [label="Tx desc queue filled IRQ"];
* c=>>d [label="EDCA sub-scheduler callback"];
* c<<d [label="Tx desc queue to pop"];
* c=>>d [label="UMAC Tx desc callback"];
* ... [label="(several Tx desc can be popped)"];
* d=>d [label="Packets are sent or discarded"];
* --- [label="Tx confirm queue example"];
* c<=d [label="ipc_emb_txcfm_push()"];
* c>>d [label="Request accepted"];
* ... [label="(several Tx cfm can be pushed)"];
* b<:c [label="Tx cfm queue filled IRQ"];
* a<<=b [label="Driver's Tx Confirm callback"];
* a=>b [label="ipc_host_txcfm_pop()"];
* a<<b [label="struct ipc_txcfm"];
* a<=a [label="Packets are freed by the driver"];
* @endmsc
*
* @{
****************************************************************************************
*/
/// @} IPC_TX
/**
****************************************************************************************
* @defgroup IPC_RX IPC Rx path
* @ingroup IPC
* @brief IPC Rx path functions and structures
*
* A typical use case of the IPC Rx path API:
* @msc
* hscale = "2";
*
* a [label=Firmware],
* b [label="IPC emb"],
* c [label="IPC host"],
* d [label=Driver];
*
* --- [label="Rx buffer and desc queues usage example"];
* d=>c [label="ipc_host_rxbuf_push()"];
* d=>c [label="ipc_host_rxbuf_push()"];
* d=>c [label="ipc_host_rxbuf_push()"];
* ... [label="(several Rx buffer are pushed)"];
* a=>a [label=" Frame is received\n from the medium"];
* a<<b [label="struct ipc_rxbuf"];
* a=>a [label=" Firmware fill the buffer\n with received frame"];
* a<<b [label="Push accepted"];
* ... [label="(several Rx desc can be pushed)"];
* b:>c [label="Rx desc queue filled IRQ"];
* c=>>d [label="Driver Rx packet callback"];
* c<=d [label="ipc_host_rxdesc_pop()"];
* d=>d [label="Rx packet is handed \nover to the OS "];
* ... [label="(several Rx desc can be poped)"];
* --- [label="Rx buffer request exemple"];
* b:>c [label="Low Rx buffer count IRQ"];
* a<<b [label="struct ipc_rxbuf"];
* c=>>d [label="Driver Rx buffer callback"];
* d=>c [label="ipc_host_rxbuf_push()"];
* d=>c [label="ipc_host_rxbuf_push()"];
* d=>c [label="ipc_host_rxbuf_push()"];
* ... [label="(several Rx buffer are pushed)"];
* @endmsc
*
* @addtogroup IPC_RX
* @{
****************************************************************************************
*/
/// @} IPC_RX
/**
****************************************************************************************
* @defgroup IPC_MISC IPC Misc
* @ingroup IPC
* @brief IPC miscellaneous functions
****************************************************************************************
*/
/** IPC header structure. This structure is stored at the beginning of every IPC message.
* @warning This structure's size must NOT exceed 4 bytes in length.
*/
struct ipc_header {
/// IPC message type.
u16_l type;
/// IPC message size in number of bytes.
u16_l size;
};
struct ipc_msg_elt {
/// Message header (alignment forced on word size, see allocation in shared env).
struct ipc_header header __ALIGN4;
};
/// Message structure for MSGs from Emb to App
struct ipc_e2a_msg {
u16_l id; ///< Message id.
u16_l dummy_dest_id;
u16_l dummy_src_id;
u16_l param_len; ///< Parameter embedded struct length.
u32_l pattern; ///< Used to stamp a valid MSG buffer
u32_l param[IPC_E2A_MSG_PARAM_SIZE]; ///< Parameter embedded struct. Must be word-aligned.
};
/// Message structure for Debug messages from Emb to App
struct ipc_dbg_msg {
u32_l string[IPC_DBG_PARAM_SIZE/4]; ///< Debug string
u32_l pattern; ///< Used to stamp a valid buffer
};
/// Message structure for MSGs from App to Emb.
/// Actually a sub-structure will be used when filling the messages.
struct ipc_a2e_msg {
u32_l dummy_word; // used to cope with kernel message structure
u32_l msg[IPC_A2E_MSG_BUF_SIZE]; // body of the msg
};
struct ipc_shared_rx_buf {
/// < ptr to hostbuf client (ipc_host client) structure
u32_l hostid;
/// < ptr to real hostbuf dma address
u32_l dma_addr;
};
struct ipc_shared_rx_desc {
/// DMA Address
u32_l dma_addr;
};
/// Structure containing FW characteristics for compatibility checking
struct compatibility_tag {
/// Size of IPC shared memory
u16_l ipc_shared_size;
/// Message struct/ID API version
u16_l msg_api;
/// Version of IPC shared
u8_l ipc_shared_version;
/// Number of host buffers available for Emb->App MSGs sending
u8_l msge2a_buf_cnt;
/// Number of host buffers available for Debug Messages sending
u8_l dbgbuf_cnt;
/// Number of host buffers available for Radar events handling
u8_l radarbuf_cnt;
/// Number of host buffers available for unsupported Rx vectors handling
u8_l unsuprxvecbuf_cnt;
/// Number of shared descriptors available for Data RX handling
u8_l rxdesc_cnt;
/// Number of host buffers available for Data Rx handling
u8_l rxbuf_cnt;
/// Number of descriptors in BK TX queue (power of 2, min 4, max 64)
u8_l bk_txq;
/// Number of descriptors in BE TX queue (power of 2, min 4, max 64)
u8_l be_txq;
/// Number of descriptors in VI TX queue (power of 2, min 4, max 64)
u8_l vi_txq;
/// Number of descriptors in VO TX queue (power of 2, min 4, max 64)
u8_l vo_txq;
/// Number of descriptors in BCN TX queue (power of 2, min 4, max 64)
u8_l bcn_txq;
};
/*
* TYPE and STRUCT DEFINITIONS
****************************************************************************************
*/
// Indexes are defined in the MIB shared structure
struct ipc_shared_env_tag {
volatile struct compatibility_tag comp_info; //FW characteristics
volatile struct ipc_a2e_msg msg_a2e_buf; // room for MSG to be sent from App to Emb
// Fields for MSGs sending from Emb to App
volatile struct ipc_e2a_msg msg_e2a_buf; // room to build the MSG to be DMA Xferred
volatile struct dma_desc msg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers
volatile u32_l msg_e2a_hostbuf_addr[IPC_MSGE2A_BUF_CNT]; // buffers @ for DMA Xfers
// Fields for Debug MSGs sending from Emb to App
volatile struct ipc_dbg_msg dbg_buf; // room to build the MSG to be DMA Xferred
volatile struct dma_desc dbg_dma_desc; // DMA descriptor for Emb->App MSGs Xfers
volatile u32_l dbg_hostbuf_addr[IPC_DBGBUF_CNT]; // buffers @ for MSGs DMA Xfers
volatile u32_l la_dbginfo_addr; // Host buffer address for the debug information
volatile u32_l pattern_addr;
volatile u32_l radarbuf_hostbuf[IPC_RADARBUF_CNT]; // buffers @ for Radar Events
volatile u32_l unsuprxvecbuf_hostbuf[IPC_UNSUPRXVECBUF_CNT]; // buffers @ for unsupported Rx vectors
volatile struct txdesc_host txdesc0[CONFIG_USER_MAX][NX_TXDESC_CNT0];
volatile struct txdesc_host txdesc1[CONFIG_USER_MAX][NX_TXDESC_CNT1];
volatile struct txdesc_host txdesc2[CONFIG_USER_MAX][NX_TXDESC_CNT2];
volatile struct txdesc_host txdesc3[CONFIG_USER_MAX][NX_TXDESC_CNT3];
#if NX_TXQ_CNT == 5
volatile struct txdesc_host txdesc4[1][NX_TXDESC_CNT4];
#endif
#ifdef CONFIG_RWNX_FULLMAC
// RX Descriptors Array
volatile struct ipc_shared_rx_desc host_rxdesc[IPC_RXDESC_CNT];
// RX Buffers Array
volatile struct ipc_shared_rx_buf host_rxbuf[IPC_RXBUF_CNT];
#else
// buffers @ for Data Rx
volatile u32_l host_rxbuf[IPC_RXBUF_CNT];
#endif /* CONFIG_RWNX_FULLMAC */
u32_l buffered[NX_REMOTE_STA_MAX][TID_MAX];
volatile uint16_t trace_pattern;
volatile uint32_t trace_start;
volatile uint32_t trace_end;
volatile uint32_t trace_size;
volatile uint32_t trace_offset;
volatile uint32_t trace_nb_compo;
volatile uint32_t trace_offset_compo;
};
extern struct ipc_shared_env_tag ipc_shared_env;
/*
* TYPE and STRUCT DEFINITIONS
****************************************************************************************
*/
// IRQs from app to emb
/// Interrupts bits used for the TX descriptors of the AC queues
#ifdef CONFIG_RWNX_MUMIMO_TX
#ifdef CONFIG_RWNX_OLD_IPC
#error "MU-MIMO cannot be compiled for old IPC"
#endif
/// Interrupts bits used
#if CONFIG_USER_MAX > 3
#define IPC_IRQ_A2E_USER_MSK 0xF
#elif CONFIG_USER_MAX > 2
#define IPC_IRQ_A2E_USER_MSK 0x7
#else
#define IPC_IRQ_A2E_USER_MSK 0x3
#endif
/// Offset of the interrupts for AC0
#define IPC_IRQ_A2E_AC0_OFT 8
/// Mask of the interrupts for AC0
#define IPC_IRQ_A2E_AC0_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC0_OFT)
/// Offset of the interrupts for AC1
#define IPC_IRQ_A2E_AC1_OFT (IPC_IRQ_A2E_AC0_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC1
#define IPC_IRQ_A2E_AC1_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC1_OFT)
/// Offset of the interrupts for AC2
#define IPC_IRQ_A2E_AC2_OFT (IPC_IRQ_A2E_AC1_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC2
#define IPC_IRQ_A2E_AC2_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC2_OFT)
/// Offset of the interrupts for AC3
#define IPC_IRQ_A2E_AC3_OFT (IPC_IRQ_A2E_AC2_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC3
#define IPC_IRQ_A2E_AC3_MSK (IPC_IRQ_A2E_USER_MSK << IPC_IRQ_A2E_AC3_OFT)
/// Offset of the interrupts for BCN
#define IPC_IRQ_A2E_BCN_OFT (IPC_IRQ_A2E_AC3_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for BCN
#define IPC_IRQ_A2E_BCN_MSK CO_BIT(IPC_IRQ_A2E_BCN_OFT)
#define IPC_IRQ_A2E_AC_TXDESC (IPC_IRQ_A2E_AC0_MSK | IPC_IRQ_A2E_AC1_MSK | \
IPC_IRQ_A2E_AC2_MSK | IPC_IRQ_A2E_AC3_MSK)
/// Interrupts bits used for the TX descriptors of the BCN queue
#if NX_TXQ_CNT < 5
#define IPC_IRQ_A2E_BCN_TXDESC 0
#else
#define IPC_IRQ_A2E_BCN_TXDESC (0x01 << IPC_IRQ_A2E_BCN_OFT)
#endif
/// IPC TX descriptor interrupt mask
#define IPC_IRQ_A2E_TXDESC (IPC_IRQ_A2E_AC_TXDESC | IPC_IRQ_A2E_BCN_TXDESC)
#else
/// IPC TX descriptor interrupt mask
#define IPC_IRQ_A2E_TXDESC 0xFF00
#endif
#define IPC_IRQ_A2E_TXDESC_FIRSTBIT (8)
#define IPC_IRQ_A2E_RXBUF_BACK CO_BIT(5)
#define IPC_IRQ_A2E_RXDESC_BACK CO_BIT(4)
#define IPC_IRQ_A2E_MSG CO_BIT(1)
#define IPC_IRQ_A2E_DBG CO_BIT(0)
#define IPC_IRQ_A2E_ALL (IPC_IRQ_A2E_TXDESC|IPC_IRQ_A2E_MSG|IPC_IRQ_A2E_DBG)
// IRQs from emb to app
#define IPC_IRQ_E2A_TXCFM_POS 7
#ifdef CONFIG_RWNX_MUMIMO_TX
#ifdef CONFIG_RWNX_OLD_IPC
#error "MU-MIMO cannot be compiled for old IPC"
#endif
/// Interrupts bits used
#if CONFIG_USER_MAX > 3
#define IPC_IRQ_E2A_USER_MSK 0xF
#elif CONFIG_USER_MAX > 2
#define IPC_IRQ_E2A_USER_MSK 0x7
#else
#define IPC_IRQ_E2A_USER_MSK 0x3
#endif
/// Offset of the interrupts for AC0
#define IPC_IRQ_E2A_AC0_OFT IPC_IRQ_E2A_TXCFM_POS
/// Mask of the interrupts for AC0
#define IPC_IRQ_E2A_AC0_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC0_OFT)
/// Offset of the interrupts for AC1
#define IPC_IRQ_E2A_AC1_OFT (IPC_IRQ_E2A_AC0_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC1
#define IPC_IRQ_E2A_AC1_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC1_OFT)
/// Offset of the interrupts for AC2
#define IPC_IRQ_E2A_AC2_OFT (IPC_IRQ_E2A_AC1_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC2
#define IPC_IRQ_E2A_AC2_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC2_OFT)
/// Offset of the interrupts for AC3
#define IPC_IRQ_E2A_AC3_OFT (IPC_IRQ_E2A_AC2_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for AC3
#define IPC_IRQ_E2A_AC3_MSK (IPC_IRQ_E2A_USER_MSK << IPC_IRQ_E2A_AC3_OFT)
/// Offset of the interrupts for BCN
#define IPC_IRQ_E2A_BCN_OFT (IPC_IRQ_E2A_AC3_OFT + CONFIG_USER_MAX)
/// Mask of the interrupts for BCN
#define IPC_IRQ_E2A_BCN_MSK CO_BIT(IPC_IRQ_E2A_BCN_OFT)
#define IPC_IRQ_E2A_AC_TXCFM (IPC_IRQ_E2A_AC0_MSK | IPC_IRQ_E2A_AC1_MSK | \
IPC_IRQ_E2A_AC2_MSK | IPC_IRQ_E2A_AC3_MSK)
/// Interrupts bits used for the TX descriptors of the BCN queue
#if NX_TXQ_CNT < 5
#define IPC_IRQ_E2A_BCN_TXCFM 0
#else
#define IPC_IRQ_E2A_BCN_TXCFM (0x01 << IPC_IRQ_E2A_BCN_OFT)
#endif
/// IPC TX descriptor interrupt mask
#define IPC_IRQ_E2A_TXCFM (IPC_IRQ_E2A_AC_TXCFM | IPC_IRQ_E2A_BCN_TXCFM)
#else
#define IPC_IRQ_E2A_TXCFM (((1 << NX_TXQ_CNT) - 1) << IPC_IRQ_E2A_TXCFM_POS)
#endif /* CONFIG_RWNX_MUMIMO_TX */
#define IPC_IRQ_E2A_UNSUP_RX_VEC CO_BIT(7)
#define IPC_IRQ_E2A_RADAR CO_BIT(6)
#define IPC_IRQ_E2A_TBTT_SEC CO_BIT(5)
#define IPC_IRQ_E2A_TBTT_PRIM CO_BIT(4)
#define IPC_IRQ_E2A_RXDESC CO_BIT(3)
#define IPC_IRQ_E2A_MSG_ACK CO_BIT(2)
#define IPC_IRQ_E2A_MSG CO_BIT(1)
#define IPC_IRQ_E2A_DBG CO_BIT(0)
#define IPC_IRQ_E2A_ALL (IPC_IRQ_E2A_TXCFM \
| IPC_IRQ_E2A_RXDESC \
| IPC_IRQ_E2A_MSG_ACK \
| IPC_IRQ_E2A_MSG \
| IPC_IRQ_E2A_DBG \
| IPC_IRQ_E2A_TBTT_PRIM \
| IPC_IRQ_E2A_TBTT_SEC \
| IPC_IRQ_E2A_RADAR \
| IPC_IRQ_E2A_UNSUP_RX_VEC)
// FLAGS for RX desc
#define IPC_RX_FORWARD CO_BIT(1)
#define IPC_RX_INTRABSS CO_BIT(0)
// IPC message TYPE
enum {
IPC_MSG_NONE = 0,
IPC_MSG_WRAP,
IPC_MSG_KMSG,
IPC_DBG_STRING,
};
#endif // _IPC_SHARED_H_

View File

@ -0,0 +1,564 @@
/**
****************************************************************************************
*
* @file lmac_mac_types.h
*
* @brief MAC related definitions.
*
* Adapted from mac_types.h to used lmac_types.h instead of standard types
* eg: perl -pi -e '$_ =~ s/uint(\d{1,2})_t/u$1_l/g; \
* $_ =~ s/int(\d{1,2})_t/s$1_l/g; \
* $_ =~ s/CO_BIT/BIT/g;' lmac_mac.h
*
* Copyright (C) RivieraWaves 2011-2019
*
****************************************************************************************
*/
#ifndef LMAC_MAC_H_
#define LMAC_MAC_H_
#include "lmac_types.h"
/// Interface types
enum mac_vif_type {
/// ESS STA interface
VIF_STA,
/// IBSS STA interface
VIF_IBSS,
/// AP interface
VIF_AP,
/// Mesh Point interface
VIF_MESH_POINT,
/// Monitor interface
VIF_MONITOR,
/// Unknown type
VIF_UNKNOWN
};
/// MAC address length in bytes.
#define MAC_ADDR_LEN 6
/// MAC address structure.
struct mac_addr {
/// Array of 16-bit words that make up the MAC address.
u16_l array[MAC_ADDR_LEN/2];
};
/// SSID maximum length.
#define MAC_SSID_LEN 32
/// SSID.
struct mac_ssid {
/// Actual length of the SSID.
u8_l length;
/// Array containing the SSID name.
u8_l array[MAC_SSID_LEN];
};
/// BSS type
enum mac_bss_type {
INFRASTRUCTURE_MODE = 1,
INDEPENDENT_BSS_MODE,
ANY_BSS_MODE
};
/// Channel Band
enum mac_chan_band {
/// 2.4GHz Band
PHY_BAND_2G4,
/// 5GHz band
PHY_BAND_5G,
/// Number of bands
PHY_BAND_MAX,
};
/// Operating Channel Bandwidth
enum mac_chan_bandwidth {
/// 20MHz BW
PHY_CHNL_BW_20,
/// 40MHz BW
PHY_CHNL_BW_40,
/// 80MHz BW
PHY_CHNL_BW_80,
/// 160MHz BW
PHY_CHNL_BW_160,
/// 80+80MHz BW
PHY_CHNL_BW_80P80,
/// Reserved BW
PHY_CHNL_BW_OTHER,
};
/// max number of channels in the 2.4 GHZ band
#define MAC_DOMAINCHANNEL_24G_MAX 14
/// max number of channels in the 5 GHZ band
#define MAC_DOMAINCHANNEL_5G_MAX 28
/// Channel Flag
enum mac_chan_flags {
/// Cannot initiate radiation on this channel
CHAN_NO_IR = BIT(0),
/// Channel is not allowed
CHAN_DISABLED = BIT(1),
/// Radar detection required on this channel
CHAN_RADAR = BIT(2),
};
/// Primary Channel definition
struct mac_chan_def {
/// Frequency of the channel (in MHz)
u16_l freq;
/// RF band (@ref mac_chan_band)
u8_l band;
/// Additional information (@ref mac_chan_flags)
u8_l flags;
/// Max transmit power allowed on this channel (dBm)
s8_l tx_power;
};
/// Operating Channel
struct mac_chan_op {
/// Band (@ref mac_chan_band)
u8_l band;
/// Channel type (@ref mac_chan_bandwidth)
u8_l type;
/// Frequency for Primary 20MHz channel (in MHz)
u16_l prim20_freq;
/// Frequency center of the contiguous channel or center of Primary 80+80 (in MHz)
u16_l center1_freq;
/// Frequency center of the non-contiguous secondary 80+80 (in MHz)
u16_l center2_freq;
/// Max transmit power allowed on this channel (dBm)
s8_l tx_power;
/// Additional information (@ref mac_chan_flags)
u8_l flags;
};
/// Cipher suites (order is important as it is used by MACHW)
enum mac_cipher_suite {
/// 00-0F-AC 1
MAC_CIPHER_WEP40 = 0,
/// 00-0F-AC 2
MAC_CIPHER_TKIP = 1,
/// 00-0F-AC 4
MAC_CIPHER_CCMP = 2,
/// 00-0F-AC 5
MAC_CIPHER_WEP104 = 3,
/// 00-14-72 1
MAC_CIPHER_WPI_SMS4 = 4,
/// 00-0F-AC 6 (aka AES_CMAC)
MAC_CIPHER_BIP_CMAC_128 = 5,
// following cipher are not supported by MACHW
/// 00-0F-AC 08
MAC_CIPHER_GCMP_128,
/// 00-0F-AC 09
MAC_CIPHER_GCMP_256,
/// 00-0F-AC 10
MAC_CIPHER_CCMP_256,
/// 00-0F-AC 11
MAC_CIPHER_BIP_GMAC_128,
/// 00-0F-AC 12
MAC_CIPHER_BIP_GMAC_256,
/// 00-0F-AC 13
MAC_CIPHER_BIP_CMAC_256,
MAC_CIPHER_INVALID = 0xFF
};
/// Authentication and Key Management suite
enum mac_akm_suite {
/// No security
MAC_AKM_NONE,
/// Pre RSN (WEP or WPA)
MAC_AKM_PRE_RSN,
/// 00-0F-AC 1
MAC_AKM_8021X,
/// 00-0F-AC 2
MAC_AKM_PSK,
/// 00-0F-AC 3
MAC_AKM_FT_8021X,
/// 00-0F-AC 4
MAC_AKM_FT_PSK,
/// 00-0F-AC 5
MAC_AKM_8021X_SHA256,
/// 00-0F-AC 6
MAC_AKM_PSK_SHA256,
/// 00-0F-AC 7
MAC_AKM_TDLS,
/// 00-0F-AC 8
MAC_AKM_SAE,
/// 00-0F-AC 9
MAC_AKM_FT_OVER_SAE,
/// 00-0F-AC 11
MAC_AKM_8021X_SUITE_B,
/// 00-0F-AC 12
MAC_AKM_8021X_SUITE_B_192,
/// 00-0F-AC 14
MAC_AKM_FILS_SHA256,
/// 00-0F-AC 15
MAC_AKM_FILS_SHA384,
/// 00-0F-AC 16
MAC_AKM_FT_FILS_SHA256,
/// 00-0F-AC 17
MAC_AKM_FT_FILS_SHA384,
/// 00-0F-AC 18
MAC_AKM_OWE,
/// 00-14-72 1
MAC_AKM_WAPI_CERT,
/// 00-14-72 2
MAC_AKM_WAPI_PSK,
};
/// Scan result element, parsed from beacon or probe response frames.
struct mac_scan_result {
/// Scan result is valid
bool valid_flag;
/// Network BSSID.
struct mac_addr bssid;
/// Network name.
struct mac_ssid ssid;
/// Network type (@ref mac_bss_type).
u16_l bsstype;
/// Network channel.
struct mac_chan_def *chan;
/// Network beacon period (in TU).
u16_l beacon_period;
/// Capability information
u16_l cap_info;
/// Supported AKM (bit-field of @ref mac_akm_suite)
u32_l akm;
/// Group cipher (bit-field of @ref mac_cipher_suite)
u16_l group_cipher;
/// Group cipher (bit-field of @ref mac_cipher_suite)
u16_l pairwise_cipher;
/// RSSI of the scanned BSS (in dBm)
s8_l rssi;
};
/// Legacy rate 802.11 definitions
enum mac_legacy_rates {
/// DSSS/CCK 1Mbps
MAC_RATE_1MBPS = 2,
/// DSSS/CCK 2Mbps
MAC_RATE_2MBPS = 4,
/// DSSS/CCK 5.5Mbps
MAC_RATE_5_5MBPS = 11,
/// OFDM 6Mbps
MAC_RATE_6MBPS = 12,
/// OFDM 9Mbps
MAC_RATE_9MBPS = 18,
/// DSSS/CCK 11Mbps
MAC_RATE_11MBPS = 22,
/// OFDM 12Mbps
MAC_RATE_12MBPS = 24,
/// OFDM 18Mbps
MAC_RATE_18MBPS = 36,
/// OFDM 24Mbps
MAC_RATE_24MBPS = 48,
/// OFDM 36Mbps
MAC_RATE_36MBPS = 72,
/// OFDM 48Mbps
MAC_RATE_48MBPS = 96,
/// OFDM 54Mbps
MAC_RATE_54MBPS = 108
};
/// BSS Membership Selector definitions
enum mac_bss_membership {
/// HT PHY
MAC_BSS_MEMBERSHIP_HT_PHY = 127,
/// VHT PHY
MAC_BSS_MEMBERSHIP_VHT_PHY = 126,
};
/// MAC rateset maximum length
#define MAC_RATESET_LEN 12
/// Structure containing the legacy rateset of a station
struct mac_rateset {
/// Number of legacy rates supported
u8_l length;
/// Array of legacy rates
u8_l array[MAC_RATESET_LEN];
};
/// MAC Security Key maximum length
#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys
/// Structure defining a security key
struct mac_sec_key {
/// Key material length
u8_l length;
/// Key material
u32_l array[MAC_SEC_KEY_LEN/4];
};
/// Access Category enumeration
enum mac_ac {
/// Background
AC_BK = 0,
/// Best-effort
AC_BE,
/// Video
AC_VI,
/// Voice
AC_VO,
/// Number of access categories
AC_MAX
};
/// Traffic ID enumeration
enum mac_tid {
/// TID_0. Mapped to @ref AC_BE as per 802.11 standard.
TID_0,
/// TID_1. Mapped to @ref AC_BK as per 802.11 standard.
TID_1,
/// TID_2. Mapped to @ref AC_BK as per 802.11 standard.
TID_2,
/// TID_3. Mapped to @ref AC_BE as per 802.11 standard.
TID_3,
/// TID_4. Mapped to @ref AC_VI as per 802.11 standard.
TID_4,
/// TID_5. Mapped to @ref AC_VI as per 802.11 standard.
TID_5,
/// TID_6. Mapped to @ref AC_VO as per 802.11 standard.
TID_6,
/// TID_7. Mapped to @ref AC_VO as per 802.11 standard.
TID_7,
/// Non standard Management TID used internally
TID_MGT,
/// Number of TID supported
TID_MAX
};
/// MCS bitfield maximum size (in bytes)
#define MAX_MCS_LEN 16 // 16 * 8 = 128
/// MAC HT capability information element
struct mac_htcapability {
/// HT capability information
u16_l ht_capa_info;
/// A-MPDU parameters
u8_l a_mpdu_param;
/// Supported MCS
u8_l mcs_rate[MAX_MCS_LEN];
/// HT extended capability information
u16_l ht_extended_capa;
/// Beamforming capability information
u32_l tx_beamforming_capa;
/// Antenna selection capability information
u8_l asel_capa;
};
/// MAC VHT capability information element
struct mac_vhtcapability {
/// VHT capability information
u32_l vht_capa_info;
/// RX MCS map
u16_l rx_mcs_map;
/// RX highest data rate
u16_l rx_highest;
/// TX MCS map
u16_l tx_mcs_map;
/// TX highest data rate
u16_l tx_highest;
};
/// Length (in bytes) of the MAC HE capability field
#define MAC_HE_MAC_CAPA_LEN 6
/// Length (in bytes) of the PHY HE capability field
#define MAC_HE_PHY_CAPA_LEN 11
/// Maximum length (in bytes) of the PPE threshold data
#define MAC_HE_PPE_THRES_MAX_LEN 25
/// Structure listing the per-NSS, per-BW supported MCS combinations
struct mac_he_mcs_nss_supp {
/// per-NSS supported MCS in RX, for BW <= 80MHz
u16_l rx_mcs_80;
/// per-NSS supported MCS in TX, for BW <= 80MHz
u16_l tx_mcs_80;
/// per-NSS supported MCS in RX, for BW = 160MHz
u16_l rx_mcs_160;
/// per-NSS supported MCS in TX, for BW = 160MHz
u16_l tx_mcs_160;
/// per-NSS supported MCS in RX, for BW = 80+80MHz
u16_l rx_mcs_80p80;
/// per-NSS supported MCS in TX, for BW = 80+80MHz
u16_l tx_mcs_80p80;
};
/// MAC HE capability information element
struct mac_hecapability {
/// MAC HE capabilities
u8_l mac_cap_info[MAC_HE_MAC_CAPA_LEN];
/// PHY HE capabilities
u8_l phy_cap_info[MAC_HE_PHY_CAPA_LEN];
/// Supported MCS combinations
struct mac_he_mcs_nss_supp mcs_supp;
/// PPE Thresholds data
u8_l ppe_thres[MAC_HE_PPE_THRES_MAX_LEN];
};
/// Station flags
enum mac_sta_flags {
/// Bit indicating that a STA has QoS (WMM) capability
STA_QOS_CAPA = BIT(0),
/// Bit indicating that a STA has HT capability
STA_HT_CAPA = BIT(1),
/// Bit indicating that a STA has VHT capability
STA_VHT_CAPA = BIT(2),
/// Bit indicating that a STA has MFP capability
STA_MFP_CAPA = BIT(3),
/// Bit indicating that the STA included the Operation Notification IE
STA_OPMOD_NOTIF = BIT(4),
/// Bit indicating that a STA has HE capability
STA_HE_CAPA = BIT(5),
};
/// Connection flags
enum mac_connection_flags {
/// Flag indicating whether the control port is controlled by host or not
CONTROL_PORT_HOST = BIT(0),
/// Flag indicating whether the control port frame shall be sent unencrypted
CONTROL_PORT_NO_ENC = BIT(1),
/// Flag indicating whether HT and VHT shall be disabled or not
DISABLE_HT = BIT(2),
/// Flag indicating whether WPA or WPA2 authentication is in use
WPA_WPA2_IN_USE = BIT(3),
/// Flag indicating whether MFP is in use
MFP_IN_USE = BIT(4),
// Flag indicating Roam
REASSOCIATION = BIT(5),
};
#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
#define IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G 0x04
#define IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD 0x20
#define IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US 0x40
#define IEEE80211_HE_PHY_CAP1_MIDAMBLE_RX_TX_MAX_NSTS 0x80
#define IEEE80211_HE_PHY_CAP2_MIDAMBLE_RX_TX_MAX_NSTS 0x01
#define IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US 0x02
#define IEEE80211_HE_PHY_CAP2_DOPPLER_RX 0x20
#define IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ 0x08
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_16_QAM 0x18
#define IEEE80211_HE_PHY_CAP3_DCM_MAX_RX_NSS_1 0x00
#define IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA 0x40
#define IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE 0x01
#define IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 0x0c
#define IEEE80211_HE_PHY_CAP5_NG16_SU_FEEDBACK 0x40
#define IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK 0x80
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU 0x01
#define IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU 0x02
#define IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB 0x04
#define IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB 0x08
#define IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT 0x80
#define IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO 0x40
#define IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI 0x04
#define IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G 0x02
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB 0x10
#define IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB 0x20
#define IEEE80211_HE_PPE_THRES_MAX_LEN 25
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
#define WLAN_EID_EXTENSION 255
/* Element ID Extensions for Element ID 255 */
enum ieee80211_eid_ext {
WLAN_EID_EXT_ASSOC_DELAY_INFO = 1,
WLAN_EID_EXT_FILS_REQ_PARAMS = 2,
WLAN_EID_EXT_FILS_KEY_CONFIRM = 3,
WLAN_EID_EXT_FILS_SESSION = 4,
WLAN_EID_EXT_FILS_HLP_CONTAINER = 5,
WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN = 6,
WLAN_EID_EXT_KEY_DELIVERY = 7,
WLAN_EID_EXT_FILS_WRAPPED_DATA = 8,
WLAN_EID_EXT_FILS_PUBLIC_KEY = 12,
WLAN_EID_EXT_FILS_NONCE = 13,
WLAN_EID_EXT_FUTURE_CHAN_GUIDANCE = 14,
};
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
#define WLAN_EID_EXT_HE_CAPABILITY 35
#define WLAN_EID_EXT_HE_OPERATION 36
#define WLAN_EID_EXT_UORA 37
#define WLAN_EID_EXT_HE_MU_EDCA 38
#define WLAN_EID_EXT_HE_SPR 39
#define WLAN_EID_EXT_NDP_FEEDBACK_REPORT_PARAMSET 41
#define WLAN_EID_EXT_BSS_COLOR_CHG_ANN 42
#define WLAN_EID_EXT_QUIET_TIME_PERIOD_SETUP 43
#define WLAN_EID_EXT_ESS_REPORT 45
#define WLAN_EID_EXT_OPS 46
#define WLAN_EID_EXT_HE_BSS_LOAD 47
#define WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME 52
#define WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION 55
#define WLAN_EID_EXT_NON_INHERITANCE 56
#define WLAN_EID_EXT_KNOWN_BSSID 57
#define WLAN_EID_EXT_SHORT_SSID_LIST 58
#define WLAN_EID_EXT_HE_6GHZ_CAPA 59
#define WLAN_EID_EXT_UL_MU_POWER_CAPA 60
#define WLAN_EID_EXT_EHT_OPERATION 106
#define WLAN_EID_EXT_EHT_MULTI_LINK 107
#define WLAN_EID_EXT_EHT_CAPABILITY 108
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
#include <linux/ieee80211.h>
#else
struct ieee80211_he_cap_elem {
u8 mac_cap_info[6];
u8 phy_cap_info[11];
} __packed;
struct ieee80211_he_mcs_nss_supp {
__le16 rx_mcs_80;
__le16 tx_mcs_80;
__le16 rx_mcs_160;
__le16 tx_mcs_160;
__le16 rx_mcs_80p80;
__le16 tx_mcs_80p80;
} __packed;
struct ieee80211_sta_he_cap {
bool has_he;
struct ieee80211_he_cap_elem he_cap_elem;
struct ieee80211_he_mcs_nss_supp he_mcs_nss_supp;
u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN];
};
struct ieee80211_sband_iftype_data {
u16 types_mask;
struct ieee80211_sta_he_cap he_cap;
};
#endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) || defined(CONFIG_VHT_FOR_OLD_KERNEL)
struct ieee80211_vht_mcs_info {
__le16 rx_mcs_map;
__le16 rx_highest;
__le16 tx_mcs_map;
__le16 tx_highest;
} __packed;
struct ieee80211_vht_cap {
__le32 vht_cap_info;
struct ieee80211_vht_mcs_info supp_mcs;
};
#define WLAN_EID_VHT_CAPABILITY 191
struct ieee80211_sta_vht_cap {
bool vht_supported;
u32 cap; /* use IEEE80211_VHT_CAP_ */
struct ieee80211_vht_mcs_info vht_mcs;
};
#endif
#endif // LMAC_MAC_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/**
****************************************************************************************
*
* @file co_types.h
*
* @brief This file replaces the need to include stdint or stdbool typical headers,
* which may not be available in all toolchains, and adds new types
*
* Copyright (C) RivieraWaves 2009-2019
*
* $Rev: $
*
****************************************************************************************
*/
#ifndef _LMAC_INT_H_
#define _LMAC_INT_H_
/**
****************************************************************************************
* @addtogroup CO_INT
* @ingroup COMMON
* @brief Common integer standard types (removes use of stdint)
*
* @{
****************************************************************************************
*/
/*
* DEFINES
****************************************************************************************
*/
#include <linux/version.h>
#include <linux/types.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)
#include <linux/bits.h>
#else
#include <linux/bitops.h>
#endif
#ifdef CONFIG_RWNX_TL4
typedef uint16_t u8_l;
typedef int16_t s8_l;
typedef uint16_t bool_l;
#else
typedef uint8_t u8_l;
typedef int8_t s8_l;
typedef bool bool_l;
#endif
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;
/// @} CO_INT
#endif // _LMAC_INT_H_

View File

@ -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;
}

View File

@ -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

View File

@ -0,0 +1,148 @@
/**
******************************************************************************
*
* @file reg_access.h
*
* @brief Definitions and macros for MAC HW and platform register accesses
*
* Copyright (C) RivieraWaves 2011-2019
*
******************************************************************************
*/
#ifndef REG_ACCESS_H_
#define REG_ACCESS_H_
/*****************************************************************************
* Addresses within RWNX_ADDR_SYSTEM
*****************************************************************************/
/* Shard RAM */
#define SHARED_RAM_START_ADDR 0x00000000
/* IPC registers */
#define IPC_REG_BASE_ADDR 0x00800000
/* System Controller Registers */
#define SYSCTRL_SIGNATURE_ADDR 0x00900000
// old diag register name
#define SYSCTRL_DIAG_CONF_ADDR 0x00900068
#define SYSCTRL_PHYDIAG_CONF_ADDR 0x00900074
#define SYSCTRL_RIUDIAG_CONF_ADDR 0x00900078
// new diag register name
#define SYSCTRL_DIAG_CONF0 0x00900064
#define SYSCTRL_DIAG_CONF1 0x00900068
#define SYSCTRL_DIAG_CONF2 0x00900074
#define SYSCTRL_DIAG_CONF3 0x00900078
#define SYSCTRL_MISC_CNTL_ADDR 0x009000E0
#define BOOTROM_ENABLE BIT(4)
#define FPGA_B_RESET BIT(1)
#define SOFT_RESET BIT(0)
/* MAC platform */
#define NXMAC_VERSION_1_ADDR 0x00B00004
#define NXMAC_MU_MIMO_TX_BIT BIT(19)
#define NXMAC_BFMER_BIT BIT(18)
#define NXMAC_BFMEE_BIT BIT(17)
#define NXMAC_MAC_80211MH_FORMAT_BIT BIT(16)
#define NXMAC_COEX_BIT BIT(14)
#define NXMAC_WAPI_BIT BIT(13)
#define NXMAC_TPC_BIT BIT(12)
#define NXMAC_VHT_BIT BIT(11)
#define NXMAC_HT_BIT BIT(10)
#define NXMAC_RCE_BIT BIT(8)
#define NXMAC_CCMP_BIT BIT(7)
#define NXMAC_TKIP_BIT BIT(6)
#define NXMAC_WEP_BIT BIT(5)
#define NXMAC_SECURITY_BIT BIT(4)
#define NXMAC_SME_BIT BIT(3)
#define NXMAC_HCCA_BIT BIT(2)
#define NXMAC_EDCA_BIT BIT(1)
#define NXMAC_QOS_BIT BIT(0)
#define NXMAC_RX_CNTRL_ADDR 0x00B00060
#define NXMAC_EN_DUPLICATE_DETECTION_BIT BIT(31)
#define NXMAC_ACCEPT_UNKNOWN_BIT BIT(30)
#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT BIT(29)
#define NXMAC_ACCEPT_QO_S_NULL_BIT BIT(28)
#define NXMAC_ACCEPT_QCFWO_DATA_BIT BIT(27)
#define NXMAC_ACCEPT_Q_DATA_BIT BIT(26)
#define NXMAC_ACCEPT_CFWO_DATA_BIT BIT(25)
#define NXMAC_ACCEPT_DATA_BIT BIT(24)
#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_BIT BIT(23)
#define NXMAC_ACCEPT_CF_END_BIT BIT(22)
#define NXMAC_ACCEPT_ACK_BIT BIT(21)
#define NXMAC_ACCEPT_CTS_BIT BIT(20)
#define NXMAC_ACCEPT_RTS_BIT BIT(19)
#define NXMAC_ACCEPT_PS_POLL_BIT BIT(18)
#define NXMAC_ACCEPT_BA_BIT BIT(17)
#define NXMAC_ACCEPT_BAR_BIT BIT(16)
#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT BIT(15)
#define NXMAC_ACCEPT_BFMEE_FRAMES_BIT BIT(14)
#define NXMAC_ACCEPT_ALL_BEACON_BIT BIT(13)
#define NXMAC_ACCEPT_NOT_EXPECTED_BA_BIT BIT(12)
#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_BIT BIT(11)
#define NXMAC_ACCEPT_BEACON_BIT BIT(10)
#define NXMAC_ACCEPT_PROBE_RESP_BIT BIT(9)
#define NXMAC_ACCEPT_PROBE_REQ_BIT BIT(8)
#define NXMAC_ACCEPT_MY_UNICAST_BIT BIT(7)
#define NXMAC_ACCEPT_UNICAST_BIT BIT(6)
#define NXMAC_ACCEPT_ERROR_FRAMES_BIT BIT(5)
#define NXMAC_ACCEPT_OTHER_BSSID_BIT BIT(4)
#define NXMAC_ACCEPT_BROADCAST_BIT BIT(3)
#define NXMAC_ACCEPT_MULTICAST_BIT BIT(2)
#define NXMAC_DONT_DECRYPT_BIT BIT(1)
#define NXMAC_EXC_UNENCRYPTED_BIT BIT(0)
#define NXMAC_DEBUG_PORT_SEL_ADDR 0x00B00510
#define NXMAC_SW_SET_PROFILING_ADDR 0x00B08564
#define NXMAC_SW_CLEAR_PROFILING_ADDR 0x00B08568
/* Modem Status */
#define MDM_HDMCONFIG_ADDR 0x00C00000
/* Clock gating configuration */
#define MDM_MEMCLKCTRL0_ADDR 0x00C00848
#define MDM_CLKGATEFCTRL0_ADDR 0x00C00874
#define CRM_CLKGATEFCTRL0_ADDR 0x00940010
/* AGC (trident) */
#define AGC_RWNXAGCCNTL_ADDR 0x00C02060
/* LDPC RAM*/
#define PHY_LDPC_RAM_ADDR 0x00C09000
/* FCU (elma )*/
#define FCU_RWNXFCAGCCNTL_ADDR 0x00C09034
/* AGC RAM */
#define PHY_AGC_UCODE_ADDR 0x00C0A000
/* RIU */
#define RIU_RWNXVERSION_ADDR 0x00C0B000
#define RIU_RWNXDYNAMICCONFIG_ADDR 0x00C0B008
#define RIU_AGCMEMBISTSTAT_ADDR 0x00C0B238
#define RIU_AGCMEMSIGNATURESTAT_ADDR 0x00C0B23C
#define RIU_RWNXAGCCNTL_ADDR 0x00C0B390
/* FCU RAM */
#define PHY_FCU_UCODE_ADDR 0x00C0E000
/* RF ITF */
#define FPGAB_MPIF_SEL_ADDR 0x00C10030
#define RF_V6_DIAGPORT_CONF1_ADDR 0x00C10010
#define RF_v6_PHYDIAG_CONF1_ADDR 0x00C10018
#define RF_V7_DIAGPORT_CONF1_ADDR 0x00F10010
#define RF_v7_PHYDIAG_CONF1_ADDR 0x00F10018
/*****************************************************************************
* Macros for generated register files
*****************************************************************************/
/* Macros for IPC registers access (used in reg_ipc_app.h) */
#define REG_IPC_APP_RD(env, INDEX) \
(*(volatile u32 *)((u8 *)env + IPC_REG_BASE_ADDR + 4 * (INDEX)))
#define REG_IPC_APP_WR(env, INDEX, value) \
(*(volatile u32 *)((u8 *)env + IPC_REG_BASE_ADDR + 4 * (INDEX)) = value)
#endif /* REG_ACCESS_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,105 @@
/**
******************************************************************************
*
* @file rwnx_bfmer.c
*
* @brief VHT Beamformer function definitions
*
* Copyright (C) RivieraWaves 2016-2019
*
******************************************************************************
*/
/**
* INCLUDE FILES
******************************************************************************
*/
#include <linux/slab.h>
#include "rwnx_bfmer.h"
/**
* FUNCTION DEFINITIONS
******************************************************************************
*/
int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta,
unsigned int length)
{
gfp_t flags;
struct rwnx_bfmer_report *bfm_report ;
if (in_softirq())
flags = GFP_ATOMIC;
else
flags = GFP_KERNEL;
/* Allocate a structure that will contain the beamforming report */
bfm_report = kmalloc(sizeof(*bfm_report) + length, flags);
/* Check report allocation */
if (!bfm_report) {
/* Do not use beamforming */
return -1;
}
/* Store report length */
bfm_report->length = length;
/*
* Need to provide a Virtual Address to the MAC so that it can
* upload the received Beamforming Report in driver memory
*/
bfm_report->dma_addr = dma_map_single(rwnx_hw->dev, &bfm_report->report[0],
length, DMA_FROM_DEVICE);
/* Check DMA mapping result */
if (dma_mapping_error(rwnx_hw->dev, bfm_report->dma_addr)) {
/* Free allocated report */
kfree(bfm_report);
/* And leave */
return -1;
}
/* Store report structure */
rwnx_sta->bfm_report = bfm_report;
return 0;
}
void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta)
{
/* Verify if a report has been allocated */
if (rwnx_sta->bfm_report) {
struct rwnx_bfmer_report *bfm_report = rwnx_sta->bfm_report;
/* Unmap DMA region */
dma_unmap_single(rwnx_hw->dev, bfm_report->dma_addr,
bfm_report->length, DMA_BIDIRECTIONAL);
/* Free allocated report structure and clean the pointer */
kfree(bfm_report);
rwnx_sta->bfm_report = NULL;
}
}
#ifdef CONFIG_RWNX_FULLMAC
u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa)
{
int i;
u8 rx_nss = 0;
u16 rx_mcs_map = le16_to_cpu(vht_capa->supp_mcs.rx_mcs_map);
for (i = 7; i >= 0; i--) {
u8 mcs = (rx_mcs_map >> (2 * i)) & 3;
if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
rx_nss = i + 1;
break;
}
}
return rx_nss;
}
#endif /* CONFIG_RWNX_FULLMAC */

View File

@ -0,0 +1,100 @@
/**
******************************************************************************
*
* @file rwnx_bfmer.h
*
* @brief VHT Beamformer function declarations
*
* Copyright (C) RivieraWaves 2016-2019
*
******************************************************************************
*/
#ifndef _RWNX_BFMER_H_
#define _RWNX_BFMER_H_
/**
* INCLUDE FILES
******************************************************************************
*/
#include "rwnx_defs.h"
/**
* DEFINES
******************************************************************************
*/
/// Maximal supported report length (in bytes)
#define RWNX_BFMER_REPORT_MAX_LEN 2048
/// Size of the allocated report space (twice the maximum report length)
#define RWNX_BFMER_REPORT_SPACE_SIZE (RWNX_BFMER_REPORT_MAX_LEN * 2)
/**
* TYPE DEFINITIONS
******************************************************************************
*/
/*
* Structure used to store a beamforming report.
*/
struct rwnx_bfmer_report {
dma_addr_t dma_addr; /* Virtual address provided to MAC for
DMA transfer of the Beamforming Report */
unsigned int length; /* Report Length */
u8 report[1]; /* Report to be used for VHT TX Beamforming */
};
/**
* FUNCTION DECLARATIONS
******************************************************************************
*/
/**
******************************************************************************
* @brief Allocate memory aiming to contains the Beamforming Report received
* from a Beamformee capable capable.
* The providing length shall be large enough to contain the VHT Compressed
* Beaforming Report and the MU Exclusive part.
* It also perform a DMA Mapping providing an address to be provided to the HW
* responsible for the DMA transfer of the report.
* If successful a struct rwnx_bfmer_report object is allocated, it's address
* is stored in rwnx_sta->bfm_report.
*
* @param[in] rwnx_hw PHY Information
* @param[in] rwnx_sta Peer STA Information
* @param[in] length Memory size to be allocated
*
* @return 0 if operation is successful, else -1.
******************************************************************************
*/
int rwnx_bfmer_report_add(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta,
unsigned int length);
/**
******************************************************************************
* @brief Free a previously allocated memory intended to be used for
* Beamforming Reports.
*
* @param[in] rwnx_hw PHY Information
* @param[in] rwnx_sta Peer STA Information
*
******************************************************************************
*/
void rwnx_bfmer_report_del(struct rwnx_hw *rwnx_hw, struct rwnx_sta *rwnx_sta);
#ifdef CONFIG_RWNX_FULLMAC
/**
******************************************************************************
* @brief Parse a Rx VHT-MCS map in order to deduce the maximum number of
* Spatial Streams supported by a beamformee.
*
* @param[in] vht_capa Received VHT Capability field.
*
******************************************************************************
*/
u8 rwnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa);
#endif /* CONFIG_RWNX_FULLMAC */
#endif /* _RWNX_BFMER_H_ */

Some files were not shown because too many files have changed in this diff Show More