diff --git a/.github/workflows/action-libbl602_wifi.yml b/.github/workflows/action-libbl602_wifi.yml new file mode 100644 index 0000000..f5d80ef --- /dev/null +++ b/.github/workflows/action-libbl602_wifi.yml @@ -0,0 +1,20 @@ +name: Compile libbl602_wifi +on: [push] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Clang + uses: egor-tensin/setup-clang@v1 + with: + version: latest + platform: x64 + - name: Build libbl602_wifi + run: mkdir build && cd build && cmake -DUSE_CLANG=ON .. && make -j && cd .. + - name: Archive artifacts + uses: actions/upload-artifact@v2 + with: + name: libbl602_wifi + path: build/src/bl602_wifi/libbl602_wifi.a + \ No newline at end of file diff --git a/.gitignore b/.gitignore index c518cf3..66dc929 100644 --- a/.gitignore +++ b/.gitignore @@ -305,3 +305,6 @@ tags [._]*.un~ # End of https://www.toptal.com/developers/gitignore/api/emacs,vim,pycharm+all,python +/build* +.vscode/ +*.cache \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2bab807 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.14.0) +set(CMAKE_SYSTEM_NAME Generic) + +set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_extension.cmake) +set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1) # This is critical to producing the correct object files name for bl602 linker script + +set(CMAKE_SYSTEM_PROCESSOR riscv) +SET(CMAKE_CROSSCOMPILING 1) +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + +option(USE_CLANG "build application with clang" OFF) +if(USE_CLANG) + set(CMAKE_C_COMPILER clang) + set(CMAKE_C_COMPILER_TARGET "riscv32-unknown-elf") + set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_CXX_COMPILER_TARGET "riscv32-unknown-elf") + set(CMAKE_TOOLCHAIN_PREFIX llvm-) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcommon ") # generate correct section for uninitialized data +else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstrict-volatile-bitfields") + # this makes GCC access peripherals memory with respect to word align + # rather than byte align (e.g. sb/lb) +endif() + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -march=rv32imfc -mabi=ilp32f -DARCH_RISCV") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -march=rv32imfc -mabi=ilp32f -DARCH_RISCV") + +project(bl602_re VERSION 0.1.0) + +include_directories(./src/include) +include(cmake/add_module.cmake) + +option(FREERTOS_RAM "build with freertos ram" ON) +if (FREERTOS_RAM) + include_directories(./components/bl602/freertos_riscv_ram/config) + include_directories(./components/bl602/freertos_riscv_ram/portable/GCC/RISC-V) + include_directories(./components/bl602/freertos_riscv_ram/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions) +else() + include_directories(./components/bl602/freertos_riscv/config) + include_directories(./components/bl602/freertos_riscv/portable/GCC/RISC-V) + include_directories(./components/bl602/freertos_riscv/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions) +endif() + +add_subdirectory(./src/bl602_wifi) diff --git a/README.adoc b/README.adoc index ddf4a9b..11fa68c 100644 --- a/README.adoc +++ b/README.adoc @@ -45,6 +45,17 @@ Whatever you do, do not insert proprietary `Copyright (C) RivieraWaves` code in RivieraWaves code is known to be easily available on GitHub with simple searches, but avoid looking at it, unless you wish to forfeit your right to directly contribute code here. ==== +== BL602 wifi +I'm working on the reverse engineering of the bl602 wifi. + +The source code is located in `src/` instead of `components/**`. + +Using `cmake` to build the wifi module and it will automatically add other components +from the original `libbl602_wifi.a` and create a new one. + +This should generate a usable `libbl602_wifi.a` to link against other bl602 components. +But, I'm still working on this and it hasn't been tested yet. + == Resources * https://github.com/pine64/bl602-docs[Pine64 SDK fork's documentation], if you figure something out that's documentation-worthy, please update that documentation. diff --git a/alios/reg_intc.h b/alios/reg_intc.h new file mode 100644 index 0000000..f4d4fc9 --- /dev/null +++ b/alios/reg_intc.h @@ -0,0 +1,237 @@ +/** + * @file reg_intc.h + * @brief Definitions of the INTC HW block registers and register access functions. + * + * @defgroup REG_INTC REG_INTC + * @ingroup REG + * @{ + * + * @brief Definitions of the INTC HW block registers and register access functions. + */ +#ifndef _REG_INTC_H_ +#define _REG_INTC_H_ + +#include "co_int.h" +#include "_reg_intc.h" +#include "compiler.h" +#include "arch.h" +#include "reg_access.h" + +/** @brief Number of registers in the REG_INTC peripheral. + */ +#define REG_INTC_COUNT 17 + +/** @brief Decoding mask of the REG_INTC peripheral registers from the CPU point of view. + */ +#define REG_INTC_DECODING_MASK 0x0000007F + +/** + * @name IRQ_STATUS register definitions + * + * @{ + */ + +/// Address of the IRQ_STATUS register +#define INTC_IRQ_STATUS_ADDR 0x10910000 +/// Offset of the IRQ_STATUS register from the base address +#define INTC_IRQ_STATUS_OFFSET 0x00000000 +/// Index of the IRQ_STATUS register +#define INTC_IRQ_STATUS_INDEX 0x00000000 +/// Reset value of the IRQ_STATUS register +#define INTC_IRQ_STATUS_RESET 0x00000000 +/// Number of elements of the IRQ_STATUS register array +#define INTC_IRQ_STATUS_COUNT 2 + +/** + * @brief Returns the current value of the IRQ_STATUS register. + * The IRQ_STATUS register will be read and its value returned. + * @param[in] reg_idx Index of the register + * @return The current value of the IRQ_STATUS register. + */ +__INLINE uint32_t intc_irq_status_get(int reg_idx) +{ + ASSERT_ERR(reg_idx <= 1); + return REG_PL_RD(INTC_IRQ_STATUS_ADDR + reg_idx * 4); +} + +/// @} + +/** + * @name IRQ_RAW_STATUS register definitions + * + * @{ + */ + +/// Address of the IRQ_RAW_STATUS register +#define INTC_IRQ_RAW_STATUS_ADDR 0x10910008 +/// Offset of the IRQ_RAW_STATUS register from the base address +#define INTC_IRQ_RAW_STATUS_OFFSET 0x00000008 +/// Index of the IRQ_RAW_STATUS register +#define INTC_IRQ_RAW_STATUS_INDEX 0x00000002 +/// Reset value of the IRQ_RAW_STATUS register +#define INTC_IRQ_RAW_STATUS_RESET 0x00000000 +/// Number of elements of the IRQ_RAW_STATUS register array +#define INTC_IRQ_RAW_STATUS_COUNT 2 + +/** + * @brief Returns the current value of the IRQ_RAW_STATUS register. + * The IRQ_RAW_STATUS register will be read and its value returned. + * @param[in] reg_idx Index of the register + * @return The current value of the IRQ_RAW_STATUS register. + */ +__INLINE uint32_t intc_irq_raw_status_get(int reg_idx) +{ + ASSERT_ERR(reg_idx <= 1); + return REG_PL_RD(INTC_IRQ_RAW_STATUS_ADDR + reg_idx * 4); +} + +/// @} + +/** + * @name IRQ_UNMASK_SET register definitions + * + * @{ + */ + +/// Address of the IRQ_UNMASK_SET register +#define INTC_IRQ_UNMASK_SET_ADDR 0x10910010 +/// Offset of the IRQ_UNMASK_SET register from the base address +#define INTC_IRQ_UNMASK_SET_OFFSET 0x00000010 +/// Index of the IRQ_UNMASK_SET register +#define INTC_IRQ_UNMASK_SET_INDEX 0x00000004 +/// Reset value of the IRQ_UNMASK_SET register +#define INTC_IRQ_UNMASK_SET_RESET 0x00000000 +/// Number of elements of the IRQ_UNMASK_SET register array +#define INTC_IRQ_UNMASK_SET_COUNT 2 + +/** + * @brief Returns the current value of the IRQ_UNMASK_SET register. + * The IRQ_UNMASK_SET register will be read and its value returned. + * @param[in] reg_idx Index of the register + * @return The current value of the IRQ_UNMASK_SET register. + */ +__INLINE uint32_t intc_irq_unmask_get(int reg_idx) +{ + ASSERT_ERR(reg_idx <= 1); + return REG_PL_RD(INTC_IRQ_UNMASK_SET_ADDR + reg_idx * 4); +} + +/** + * @brief Sets the IRQ_UNMASK_SET register to a value. + * The IRQ_UNMASK_SET register will be written. + * @param[in] reg_idx Index of the register + * @param value - The value to write. + */ +__INLINE void intc_irq_unmask_set(int reg_idx, uint32_t value) +{ + ASSERT_ERR(reg_idx <= 1); + REG_PL_WR(INTC_IRQ_UNMASK_SET_ADDR + reg_idx * 4, value); +} + +/// @} + +/** + * @name IRQ_UNMASK_CLEAR register definitions + * + * @{ + */ + +/// Address of the IRQ_UNMASK_CLEAR register +#define INTC_IRQ_UNMASK_CLEAR_ADDR 0x10910018 +/// Offset of the IRQ_UNMASK_CLEAR register from the base address +#define INTC_IRQ_UNMASK_CLEAR_OFFSET 0x00000018 +/// Index of the IRQ_UNMASK_CLEAR register +#define INTC_IRQ_UNMASK_CLEAR_INDEX 0x00000006 +/// Reset value of the IRQ_UNMASK_CLEAR register +#define INTC_IRQ_UNMASK_CLEAR_RESET 0x00000000 +/// Number of elements of the IRQ_UNMASK_CLEAR register array +#define INTC_IRQ_UNMASK_CLEAR_COUNT 2 + +/** + * @brief Sets the IRQ_UNMASK_CLEAR register to a value. + * The IRQ_UNMASK_CLEAR register will be written. + * @param[in] reg_idx Index of the register + * @param value - The value to write. + */ +__INLINE void intc_irq_unmask_clear(int reg_idx, uint32_t value) +{ + ASSERT_ERR(reg_idx <= 1); + REG_PL_WR(INTC_IRQ_UNMASK_CLEAR_ADDR + reg_idx * 4, value); +} + +/// @} + +/** + * @name IRQ_POLARITY register definitions + * + * @{ + */ + +/// Address of the IRQ_POLARITY register +#define INTC_IRQ_POLARITY_ADDR 0x10910020 +/// Offset of the IRQ_POLARITY register from the base address +#define INTC_IRQ_POLARITY_OFFSET 0x00000020 +/// Index of the IRQ_POLARITY register +#define INTC_IRQ_POLARITY_INDEX 0x00000008 +/// Reset value of the IRQ_POLARITY register +#define INTC_IRQ_POLARITY_RESET 0x00000000 +/// Number of elements of the IRQ_POLARITY register array +#define INTC_IRQ_POLARITY_COUNT 2 + +/** + * @brief Returns the current value of the IRQ_POLARITY register. + * The IRQ_POLARITY register will be read and its value returned. + * @param[in] reg_idx Index of the register + * @return The current value of the IRQ_POLARITY register. + */ +__INLINE uint32_t intc_irq_polarity_get(int reg_idx) +{ + ASSERT_ERR(reg_idx <= 1); + return REG_PL_RD(INTC_IRQ_POLARITY_ADDR + reg_idx * 4); +} + +/** + * @brief Sets the IRQ_POLARITY register to a value. + * The IRQ_POLARITY register will be written. + * @param[in] reg_idx Index of the register + * @param value - The value to write. + */ +__INLINE void intc_irq_polarity_set(int reg_idx, uint32_t value) +{ + ASSERT_ERR(reg_idx <= 1); + REG_PL_WR(INTC_IRQ_POLARITY_ADDR + reg_idx * 4, value); +} + +/// @} + +/** + * @name IRQ_INDEX register definitions + * + * @{ + */ + +/// Address of the IRQ_INDEX register +#define INTC_IRQ_INDEX_ADDR 0x10910040 +/// Offset of the IRQ_INDEX register from the base address +#define INTC_IRQ_INDEX_OFFSET 0x00000040 +/// Index of the IRQ_INDEX register +#define INTC_IRQ_INDEX_INDEX 0x00000010 +/// Reset value of the IRQ_INDEX register +#define INTC_IRQ_INDEX_RESET 0x00000000 + +/** + * @brief Returns the current value of the IRQ_INDEX register. + * The IRQ_INDEX register will be read and its value returned. + * @return The current value of the IRQ_INDEX register. + */ +__INLINE uint32_t intc_irq_index_get(void) +{ + return REG_PL_RD(INTC_IRQ_INDEX_ADDR); +} + +/// @} + + +#endif // _REG_INTC_H_ + +/// @} diff --git a/blobs/bl602_demo_wifi.elf b/blobs/bl602_demo_wifi.elf old mode 100755 new mode 100644 index 332ecd5..8b13481 Binary files a/blobs/bl602_demo_wifi.elf and b/blobs/bl602_demo_wifi.elf differ diff --git a/blobs/bz_phy.c b/blobs/bz_phy.c index 97c9944..3eee85e 100644 --- a/blobs/bz_phy.c +++ b/blobs/bz_phy.c @@ -25,7 +25,5 @@ void bz_phy_reset(void) write_volatile_4(0x40002810,uVar1 & 0xfffffffe); uVar1 = read_volatile_4(0x40002810); write_volatile_4(0x40002810,uVar1 | 0x2); - uVar1 = read_volatile_4(0x40002cac); - write_volatile_4(0x40002cac,uVar1 & 0xffffffe0 | 0x4); return; } \ No newline at end of file diff --git a/blobs/reg_riu.h b/blobs/reg_riu.h new file mode 100644 index 0000000..36c326b --- /dev/null +++ b/blobs/reg_riu.h @@ -0,0 +1,902 @@ +/* SPDX-License-Identifier: MIT */ +/* Copyright(c) 2019-2021, Celeno Communications Ltd. */ + +#ifndef CL_REG_RIU_H +#define CL_REG_RIU_H + +#include +#include "reg/reg_access.h" +#include "hw.h" + +#define RIU_RSF_FILE_SIZE 0x60C + +/* + * @brief CCA_CNT_CS register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_CS                0x0
+ * 
+ */ +#define RIU_CCA_CNT_CS_ADDR (REG_RIU_BASE_ADDR + 0x00000058) +#define RIU_CCA_CNT_CS_OFFSET 0x00000058 +#define RIU_CCA_CNT_CS_INDEX 0x00000016 +#define RIU_CCA_CNT_CS_RESET 0x00000000 + +static inline u32 riu_cca_cnt_cs_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_CS_ADDR); +} + +/* + * @brief RSF_CONTROL register definition + * resampling filter operation mode register description + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    rsf_init_en               1
+ *    07    rsf_tx_bypass_type        0
+ *    06    rsf_tx_bypass_mode        1
+ *    05    rsf_rx_bypass_type        0
+ *    04    rsf_rx_bypass_mode        1
+ *    01    rsf_rx_ctl_from_reg       1
+ * 
+ */ +#define RIU_RSF_CONTROL_ADDR (REG_RIU_BASE_ADDR + 0x000001A8) +#define RIU_RSF_CONTROL_OFFSET 0x000001A8 +#define RIU_RSF_CONTROL_INDEX 0x0000006A +#define RIU_RSF_CONTROL_RESET 0x80000053 + +static inline void riu_rsf_control_rsf_init_en_setf(struct cl_hw *cl_hw, u8 rsfiniten) +{ + cl_reg_write(cl_hw, RIU_RSF_CONTROL_ADDR, + (cl_reg_read(cl_hw, RIU_RSF_CONTROL_ADDR) & ~((u32)0x80000000)) | ((u32)rsfiniten << 31)); +} + +/* + * @brief RSF_INIT register definition + * resampling filter initialization data register description + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 RSF_INIT_DATA             0x0
+ * 
+ */ +#define RIU_RSF_INIT_ADDR (REG_RIU_BASE_ADDR + 0x000001AC) +#define RIU_RSF_INIT_OFFSET 0x000001AC +#define RIU_RSF_INIT_INDEX 0x0000006B +#define RIU_RSF_INIT_RESET 0x00000000 + +static inline void riu_rsf_init_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, RIU_RSF_INIT_ADDR, value); +} + +/* + * @brief AGCFSM_RAM_INIT_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    AGC_FSM_RAM_INIT_EN       0
+ *    29    AGC_FSM_RAM_INIT_AINC2    0
+ *    28    AGC_FSM_RAM_INIT_AINC1    0
+ *    12    AGC_FSM_RAM_INIT_WPTR_SET 0
+ *    10:00 AGC_FSM_RAM_INIT_WPTR     0x0
+ * 
+ */ +#define RIU_AGCFSM_RAM_INIT_1_ADDR (REG_RIU_BASE_ADDR + 0x000001B0) +#define RIU_AGCFSM_RAM_INIT_1_OFFSET 0x000001B0 +#define RIU_AGCFSM_RAM_INIT_1_INDEX 0x0000006C +#define RIU_AGCFSM_RAM_INIT_1_RESET 0x00000000 + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_setf(struct cl_hw *cl_hw, + u16 agcfsmraminitwptr) +{ + ASSERT_ERR((((u32)agcfsmraminitwptr << 0) & ~((u32)0x000007FF)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x000007FF)) | ((u32)agcfsmraminitwptr << 0)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_wptr_set_setf(struct cl_hw *cl_hw, u8 agcfsmraminitwptrset) +{ + ASSERT_ERR((((u32)agcfsmraminitwptrset << 12) & ~((u32)0x00001000)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x00001000)) | ((u32)agcfsmraminitwptrset << 12)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_ainc_1_setf(struct cl_hw *cl_hw, + u8 agcfsmraminitainc1) +{ + ASSERT_ERR((((u32)agcfsmraminitainc1 << 28) & ~((u32)0x10000000)) == 0); + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x10000000)) | ((u32)agcfsmraminitainc1 << 28)); +} + +static inline void riu_agcfsm_ram_init_1_agc_fsm_ram_init_en_setf(struct cl_hw *cl_hw, + u8 agcfsmraminiten) +{ + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR, + (cl_reg_read(cl_hw, RIU_AGCFSM_RAM_INIT_1_ADDR) & ~((u32)0x80000000)) | ((u32)agcfsmraminiten << 31)); +} + +/* + * @brief AGCFSM_RAM_INIT_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 AGC_FSM_RAM_INIT_WDATA    0x0
+ * 
+ */ +#define RIU_AGCFSM_RAM_INIT_2_ADDR (REG_RIU_BASE_ADDR + 0x000001B4) +#define RIU_AGCFSM_RAM_INIT_2_OFFSET 0x000001B4 +#define RIU_AGCFSM_RAM_INIT_2_INDEX 0x0000006D +#define RIU_AGCFSM_RAM_INIT_2_RESET 0x00000000 + +static inline void riu_agcfsm_ram_init_2_set(struct cl_hw *cl_hw, u32 value) +{ + cl_reg_write(cl_hw, RIU_AGCFSM_RAM_INIT_2_ADDR, value); +} + +/* + * @brief AGCINBDPOW_20_STAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PDBM3           0x0
+ *    23:16 INBDPOW20_PDBM2           0x0
+ *    15:08 INBDPOW20_PDBM1           0x0
+ *    07:00 INBDPOW20_PDBM0           0x0
+ * 
+ */ +#define RIU_AGCINBDPOW_20_STAT_ADDR (REG_RIU_BASE_ADDR + 0x0000020C) +#define RIU_AGCINBDPOW_20_STAT_OFFSET 0x0000020C +#define RIU_AGCINBDPOW_20_STAT_INDEX 0x00000083 +#define RIU_AGCINBDPOW_20_STAT_RESET 0x00000000 + +static inline void riu_agcinbdpow_20_stat_unpack(struct cl_hw *cl_hw, + u8 *inbdpow20pdbm3, u8 *inbdpow20pdbm2, + u8 *inbdpow20pdbm1, u8 *inbdpow20pdbm0) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_AGCINBDPOW_20_STAT_ADDR); + + *inbdpow20pdbm3 = (local_val & ((u32)0xFF000000)) >> 24; + *inbdpow20pdbm2 = (local_val & ((u32)0x00FF0000)) >> 16; + *inbdpow20pdbm1 = (local_val & ((u32)0x0000FF00)) >> 8; + *inbdpow20pdbm0 = (local_val & ((u32)0x000000FF)) >> 0; +} + +/* + * @brief AGCINBDPOW_20_PNOISESTAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PNOISEDBM3      0x0
+ *    23:16 INBDPOW20_PNOISEDBM2      0x0
+ *    15:08 INBDPOW20_PNOISEDBM1      0x0
+ *    07:00 INBDPOW20_PNOISEDBM0      0x0
+ * 
+ */ +#define RIU_AGCINBDPOW_20_PNOISESTAT_ADDR (REG_RIU_BASE_ADDR + 0x00000228) +#define RIU_AGCINBDPOW_20_PNOISESTAT_OFFSET 0x00000228 +#define RIU_AGCINBDPOW_20_PNOISESTAT_INDEX 0x0000008A +#define RIU_AGCINBDPOW_20_PNOISESTAT_RESET 0x00000000 + +static inline u32 riu_agcinbdpow_20_pnoisestat_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOW_20_PNOISESTAT_ADDR); +} + +/* + * @brief AGCINBDPOWSECNOISESTAT register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:16 INBDPOW80_SNOISEDBM       0x0
+ *    15:08 INBDPOW40_SNOISEDBM       0x0
+ *    07:00 INBDPOW20_SNOISEDBM       0x0
+ * 
+ */ +#define RIU_AGCINBDPOWSECNOISESTAT_ADDR (REG_RIU_BASE_ADDR + 0x00000230) +#define RIU_AGCINBDPOWSECNOISESTAT_OFFSET 0x00000230 +#define RIU_AGCINBDPOWSECNOISESTAT_INDEX 0x0000008C +#define RIU_AGCINBDPOWSECNOISESTAT_RESET 0x00000000 + +static inline u32 riu_agcinbdpowsecnoisestat_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWSECNOISESTAT_ADDR); +} + +/* + * @brief CCA_CNT_MODEM_STATE_P register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_MODEM_STATE_P     0x0
+ * 
+ */ +#define RIU_CCA_CNT_MODEM_STATE_P_ADDR (REG_RIU_BASE_ADDR + 0x000002DC) +#define RIU_CCA_CNT_MODEM_STATE_P_OFFSET 0x000002DC +#define RIU_CCA_CNT_MODEM_STATE_P_INDEX 0x000000B7 +#define RIU_CCA_CNT_MODEM_STATE_P_RESET 0x00000000 + +static inline u32 riu_cca_cnt_modem_state_p_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_MODEM_STATE_P_ADDR); +} + +/* + * @brief CCA_CNT_MODEM_STATE_20_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_MODEM_STATE_20_S  0x0
+ * 
+ */ +#define RIU_CCA_CNT_MODEM_STATE_20_S_ADDR (REG_RIU_BASE_ADDR + 0x000002E0) +#define RIU_CCA_CNT_MODEM_STATE_20_S_OFFSET 0x000002E0 +#define RIU_CCA_CNT_MODEM_STATE_20_S_INDEX 0x000000B8 +#define RIU_CCA_CNT_MODEM_STATE_20_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_modem_state_20_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_MODEM_STATE_20_S_ADDR); +} + +/* + * @brief CCA_CNT_MODEM_STATE_40_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_MODEM_STATE_40_S  0x0
+ * 
+ */ +#define RIU_CCA_CNT_MODEM_STATE_40_S_ADDR (REG_RIU_BASE_ADDR + 0x000002E4) +#define RIU_CCA_CNT_MODEM_STATE_40_S_OFFSET 0x000002E4 +#define RIU_CCA_CNT_MODEM_STATE_40_S_INDEX 0x000000B9 +#define RIU_CCA_CNT_MODEM_STATE_40_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_modem_state_40_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_MODEM_STATE_40_S_ADDR); +} + +/* + * @brief CCA_CNT_MODEM_STATE_80_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_MODEM_STATE_80_S  0x0
+ * 
+ */ +#define RIU_CCA_CNT_MODEM_STATE_80_S_ADDR (REG_RIU_BASE_ADDR + 0x000002E8) +#define RIU_CCA_CNT_MODEM_STATE_80_S_OFFSET 0x000002E8 +#define RIU_CCA_CNT_MODEM_STATE_80_S_INDEX 0x000000BA +#define RIU_CCA_CNT_MODEM_STATE_80_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_modem_state_80_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_MODEM_STATE_80_S_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_P register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_P      0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_P_ADDR (REG_RIU_BASE_ADDR + 0x000002F4) +#define RIU_CCA_CNT_ENERGY_THR_P_OFFSET 0x000002F4 +#define RIU_CCA_CNT_ENERGY_THR_P_INDEX 0x000000BD +#define RIU_CCA_CNT_ENERGY_THR_P_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_p_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_P_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_S   0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_S_ADDR (REG_RIU_BASE_ADDR + 0x000002F8) +#define RIU_CCA_CNT_ENERGY_THR_20_S_OFFSET 0x000002F8 +#define RIU_CCA_CNT_ENERGY_THR_20_S_INDEX 0x000000BE +#define RIU_CCA_CNT_ENERGY_THR_20_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_S_ADDR); +} + +/* + * @brief CCA_CNT_GI_20_P register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_GI_20_P           0x0
+ * 
+ */ +#define RIU_CCA_CNT_GI_20_P_ADDR (REG_RIU_BASE_ADDR + 0x000002FC) +#define RIU_CCA_CNT_GI_20_P_OFFSET 0x000002FC +#define RIU_CCA_CNT_GI_20_P_INDEX 0x000000BF +#define RIU_CCA_CNT_GI_20_P_RESET 0x00000000 + +static inline u32 riu_cca_cnt_gi_20_p_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_GI_20_P_ADDR); +} + +/* + * @brief RWNXAGCRAMP register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    26:24 RAMPDNNDLINDEX            0x5
+ *    23:16 RAMPDNGAPQDB              0x20
+ *    10:08 RAMPUPNDLINDEX            0x7
+ *    07:00 RAMPUPGAPQDB              0x10
+ * 
+ */ +#define RIU_RWNXAGCRAMP_ADDR (REG_RIU_BASE_ADDR + 0x0000036C) +#define RIU_RWNXAGCRAMP_OFFSET 0x0000036C +#define RIU_RWNXAGCRAMP_INDEX 0x000000DB +#define RIU_RWNXAGCRAMP_RESET 0x05200710 + +static inline u8 riu_rwnxagcramp_rampupgapqdb_getf(struct cl_hw *cl_hw) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_RWNXAGCRAMP_ADDR); + + return ((local_val & ((u32)0x000000FF)) >> 0); +} + +static inline void riu_rwnxagcramp_rampupgapqdb_setf(struct cl_hw *cl_hw, u8 rampupgapqdb) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCRAMP_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCRAMP_ADDR) & ~((u32)0x000000FF)) | ((u32)rampupgapqdb << 0)); +} + +/* + * @brief RWNXAGCCNTL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:26 COMBPATHSEL               0x3F
+ *    25:20 GAINKEEP                  0x0
+ *    16    HTSTFGAINEN               1
+ *    15    NOISE_CAPTURE_DELAY_MODE  0
+ *    14    EST_PATH_SEL_2            0
+ *    13    CCA_MDM_ST_CLEAR          0
+ *    12    AGCFSMRESET               0
+ *    11    RADARDETEN                0
+ *    10    RIFSDETEN                 1
+ *    09    DSSSONLY                  0
+ *    08    OFDMONLY                  0
+ *    07:04 GPSTATUS                  0x0
+ *    03    EST_PATH_SEL              0
+ *    01    ADC_SEL_RADAR_DETECTOR    0
+ *    00    ADC_SEL_COMP_MODULE       0
+ * 
+ */ +#define RIU_RWNXAGCCNTL_ADDR (REG_RIU_BASE_ADDR + 0x00000390) +#define RIU_RWNXAGCCNTL_OFFSET 0x00000390 +#define RIU_RWNXAGCCNTL_INDEX 0x000000E4 +#define RIU_RWNXAGCCNTL_RESET 0xFC010400 + +static inline void riu_rwnxagccntl_agcfsmreset_setf(struct cl_hw *cl_hw, u8 agcfsmreset) +{ + ASSERT_ERR((((u32)agcfsmreset << 12) & ~((u32)0x00001000)) == 0); + cl_reg_write(cl_hw, RIU_RWNXAGCCNTL_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCNTL_ADDR) & ~((u32)0x00001000)) | ((u32)agcfsmreset << 12)); +} + +/* + * @brief RWNXAGCCCA_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31    CCA_CNT_CLEAR             0
+ *    30:29 CCA_CNT_RATE              0x0
+ *    28:20 INBDCCAPOWMINDBM          0x1B5
+ *    19:12 CCAFALLTHRDBM             0xBF
+ *    10    CCAEnergy_Reset_Type      0
+ *    09    DISCCAEN                  1
+ *    08    SATCCAEN                  1
+ *    07:00 CCARISETHRDBM             0xC2
+ * 
+ */ +#define RIU_RWNXAGCCCA_1_ADDR (REG_RIU_BASE_ADDR + 0x000003AC) +#define RIU_RWNXAGCCCA_1_OFFSET 0x000003AC +#define RIU_RWNXAGCCCA_1_INDEX 0x000000EB +#define RIU_RWNXAGCCCA_1_RESET 0x1B5BF3C2 + +static inline void riu_rwnxagccca_1_cca_cnt_clear_setf(struct cl_hw *cl_hw, u8 ccacntclear) +{ + cl_reg_write(cl_hw, RIU_RWNXAGCCCA_1_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCCA_1_ADDR) & ~((u32)0x80000000)) | ((u32)ccacntclear << 31)); +} + +/* + * @brief RWNXAGCCCACTRL register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:28 CCAFLAG3_CTRL             0xA
+ *    27:24 CCAFLAG2_CTRL             0x2
+ *    23:20 CCAFLAG1_CTRL             0x8
+ *    19:16 CCAFLAG0_CTRL             0x0
+ *    14:12 CCA_SECOND_ANT_SEL        0x1
+ *    10:08 CCA_MAIN_ANT_SEL          0x0
+ *    07:04 CCADEMOD                  0xF
+ *    00    CCACSEN                   1
+ * 
+ */ +#define RIU_RWNXAGCCCACTRL_ADDR (REG_RIU_BASE_ADDR + 0x000003B0) +#define RIU_RWNXAGCCCACTRL_OFFSET 0x000003B0 +#define RIU_RWNXAGCCCACTRL_INDEX 0x000000EC +#define RIU_RWNXAGCCCACTRL_RESET 0xA28010F1 + +static inline void riu_rwnxagcccactrl_cca_main_ant_sel_setf(struct cl_hw *cl_hw, u8 ccamainantsel) +{ + ASSERT_ERR((((u32)ccamainantsel << 8) & ~((u32)0x00000700)) == 0); + cl_reg_write(cl_hw, RIU_RWNXAGCCCACTRL_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCCACTRL_ADDR) & ~((u32)0x00000700)) | ((u32)ccamainantsel << 8)); +} + +/* + * @brief RWNXAGCCCASTATE_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    28    CCAMDMSTFORCEEN           0
+ *    27:24 CCAMDMSTFORCE             0x0
+ *    23:12 RXSTATECCA20_SSEL         0x380
+ *    11:00 RXSTATECCA20_PSEL         0x3F8
+ * 
+ */ +#define RIU_RWNXAGCCCASTATE_0_ADDR (REG_RIU_BASE_ADDR + 0x000003B4) +#define RIU_RWNXAGCCCASTATE_0_OFFSET 0x000003B4 +#define RIU_RWNXAGCCCASTATE_0_INDEX 0x000000ED +#define RIU_RWNXAGCCCASTATE_0_RESET 0x003803F8 + +static inline void riu_rwnxagcccastate_0_rxstatecca_20_psel_setf(struct cl_hw *cl_hw, + u16 rxstatecca20psel) +{ + ASSERT_ERR((((u32)rxstatecca20psel << 0) & ~((u32)0x00000FFF)) == 0); + cl_reg_write(cl_hw, RIU_RWNXAGCCCASTATE_0_ADDR, + (cl_reg_read(cl_hw, RIU_RWNXAGCCCASTATE_0_ADDR) & ~((u32)0x00000FFF)) | ((u32)rxstatecca20psel << 0)); +} + +/* + * @brief AGCINBDPOWNOISEPER_20_STAT_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWNOISEDBMPER20_3    0x0
+ *    23:16 INBDPOWNOISEDBMPER20_2    0x0
+ *    15:08 INBDPOWNOISEDBMPER20_1    0x0
+ *    07:00 INBDPOWNOISEDBMPER20_0    0x0
+ * 
+ */ +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_ADDR (REG_RIU_BASE_ADDR + 0x00000478) +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_OFFSET 0x00000478 +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_INDEX 0x0000011E +#define RIU_AGCINBDPOWNOISEPER_20_STAT_0_RESET 0x00000000 + +static inline u32 riu_agcinbdpownoiseper_20_stat_0_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWNOISEPER_20_STAT_0_ADDR); +} + +/* + * @brief AGCINBDPOWNOISEPER_20_STAT_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWNOISEDBMPER20_7    0x0
+ *    23:16 INBDPOWNOISEDBMPER20_6    0x0
+ *    15:08 INBDPOWNOISEDBMPER20_5    0x0
+ *    07:00 INBDPOWNOISEDBMPER20_4    0x0
+ * 
+ */ +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_ADDR (REG_RIU_BASE_ADDR + 0x0000047C) +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_OFFSET 0x0000047C +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_INDEX 0x0000011F +#define RIU_AGCINBDPOWNOISEPER_20_STAT_1_RESET 0x00000000 + +static inline u32 riu_agcinbdpownoiseper_20_stat_1_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOWNOISEPER_20_STAT_1_ADDR); +} + +/* + * @brief INBDPOWFORMAC_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PDBMA3_MAC      0x0
+ *    23:16 INBDPOW20_PDBMA2_MAC      0x0
+ *    15:08 INBDPOW20_PDBMA1_MAC      0x0
+ *    07:00 INBDPOW20_PDBMA0_MAC      0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_0_ADDR (REG_RIU_BASE_ADDR + 0x00000480) +#define RIU_INBDPOWFORMAC_0_OFFSET 0x00000480 +#define RIU_INBDPOWFORMAC_0_INDEX 0x00000120 +#define RIU_INBDPOWFORMAC_0_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_0_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_0_ADDR); +} + +/* + * @brief INBDPOWFORMAC_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    15:08 INBDPOW20_PDBMA5_MAC      0x0
+ *    07:00 INBDPOW20_PDBMA4_MAC      0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_1_ADDR (REG_RIU_BASE_ADDR + 0x00000484) +#define RIU_INBDPOWFORMAC_1_OFFSET 0x00000484 +#define RIU_INBDPOWFORMAC_1_INDEX 0x00000121 +#define RIU_INBDPOWFORMAC_1_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_1_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_1_ADDR); +} + +/* + * @brief INBDPOWFORMAC_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    23:16 INBDPOW80_SDBM_MAC        0x0
+ *    15:08 INBDPOW40_SDBM_MAC        0x0
+ *    07:00 INBDPOW20_SDBM_MAC        0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_2_ADDR (REG_RIU_BASE_ADDR + 0x00000488) +#define RIU_INBDPOWFORMAC_2_OFFSET 0x00000488 +#define RIU_INBDPOWFORMAC_2_INDEX 0x00000122 +#define RIU_INBDPOWFORMAC_2_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_2_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_2_ADDR); +} + +/* + * @brief INBDPOWFORMAC_3 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWPER20_PDBM_3_MAC   0x0
+ *    23:16 INBDPOWPER20_PDBM_2_MAC   0x0
+ *    15:08 INBDPOWPER20_PDBM_1_MAC   0x0
+ *    07:00 INBDPOWPER20_PDBM_0_MAC   0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_3_ADDR (REG_RIU_BASE_ADDR + 0x0000048C) +#define RIU_INBDPOWFORMAC_3_OFFSET 0x0000048C +#define RIU_INBDPOWFORMAC_3_INDEX 0x00000123 +#define RIU_INBDPOWFORMAC_3_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_3_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_3_ADDR); +} + +/* + * @brief INBDPOWFORMAC_4 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOWPER20_PDBM_7_MAC   0x0
+ *    23:16 INBDPOWPER20_PDBM_6_MAC   0x0
+ *    15:08 INBDPOWPER20_PDBM_5_MAC   0x0
+ *    07:00 INBDPOWPER20_PDBM_4_MAC   0x0
+ * 
+ */ +#define RIU_INBDPOWFORMAC_4_ADDR (REG_RIU_BASE_ADDR + 0x00000490) +#define RIU_INBDPOWFORMAC_4_OFFSET 0x00000490 +#define RIU_INBDPOWFORMAC_4_INDEX 0x00000124 +#define RIU_INBDPOWFORMAC_4_RESET 0x00000000 + +static inline u32 riu_inbdpowformac_4_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_INBDPOWFORMAC_4_ADDR); +} + +/* + * @brief CCA_CNT_GI_20_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_GI_20_S           0x0
+ * 
+ */ +#define RIU_CCA_CNT_GI_20_S_ADDR (REG_RIU_BASE_ADDR + 0x00000494) +#define RIU_CCA_CNT_GI_20_S_OFFSET 0x00000494 +#define RIU_CCA_CNT_GI_20_S_INDEX 0x00000125 +#define RIU_CCA_CNT_GI_20_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_gi_20_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_GI_20_S_ADDR); +} + +/* + * @brief CCA_CNT_GI_40_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_GI_40_S           0x0
+ * 
+ */ +#define RIU_CCA_CNT_GI_40_S_ADDR (REG_RIU_BASE_ADDR + 0x00000498) +#define RIU_CCA_CNT_GI_40_S_OFFSET 0x00000498 +#define RIU_CCA_CNT_GI_40_S_INDEX 0x00000126 +#define RIU_CCA_CNT_GI_40_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_gi_40_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_GI_40_S_ADDR); +} + +/* + * @brief CCA_CNT_GI_80_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_GI_80_S           0x0
+ * 
+ */ +#define RIU_CCA_CNT_GI_80_S_ADDR (REG_RIU_BASE_ADDR + 0x0000049C) +#define RIU_CCA_CNT_GI_80_S_OFFSET 0x0000049C +#define RIU_CCA_CNT_GI_80_S_INDEX 0x00000127 +#define RIU_CCA_CNT_GI_80_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_gi_80_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_GI_80_S_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_40_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_40_S   0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_40_S_ADDR (REG_RIU_BASE_ADDR + 0x000004A0) +#define RIU_CCA_CNT_ENERGY_THR_40_S_OFFSET 0x000004A0 +#define RIU_CCA_CNT_ENERGY_THR_40_S_INDEX 0x00000128 +#define RIU_CCA_CNT_ENERGY_THR_40_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_40_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_40_S_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_80_S register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_80_S   0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_80_S_ADDR (REG_RIU_BASE_ADDR + 0x000004A4) +#define RIU_CCA_CNT_ENERGY_THR_80_S_OFFSET 0x000004A4 +#define RIU_CCA_CNT_ENERGY_THR_80_S_INDEX 0x00000129 +#define RIU_CCA_CNT_ENERGY_THR_80_S_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_80_s_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_80_S_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_0 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_0 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_0_ADDR (REG_RIU_BASE_ADDR + 0x000004A8) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_0_OFFSET 0x000004A8 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_0_INDEX 0x0000012A +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_0_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_0_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_0_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_1 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_1 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_1_ADDR (REG_RIU_BASE_ADDR + 0x000004AC) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_1_OFFSET 0x000004AC +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_1_INDEX 0x0000012B +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_1_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_1_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_1_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_2 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_2_ADDR (REG_RIU_BASE_ADDR + 0x000004B0) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_2_OFFSET 0x000004B0 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_2_INDEX 0x0000012C +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_2_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_2_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_2_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_3 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_3 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_3_ADDR (REG_RIU_BASE_ADDR + 0x000004B4) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_3_OFFSET 0x000004B4 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_3_INDEX 0x0000012D +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_3_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_3_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_3_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_4 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_4 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_4_ADDR (REG_RIU_BASE_ADDR + 0x000004B8) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_4_OFFSET 0x000004B8 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_4_INDEX 0x0000012E +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_4_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_4_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_4_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_5 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_5 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_5_ADDR (REG_RIU_BASE_ADDR + 0x000004BC) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_5_OFFSET 0x000004BC +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_5_INDEX 0x0000012F +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_5_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_5_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_5_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_6 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_6 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_6_ADDR (REG_RIU_BASE_ADDR + 0x000004C0) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_6_OFFSET 0x000004C0 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_6_INDEX 0x00000130 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_6_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_6_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_6_ADDR); +} + +/* + * @brief CCA_CNT_ENERGY_THR_20_BAND_7 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:00 CCA_CNT_ENERGY_THR_20_BAND_7 0x0
+ * 
+ */ +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_7_ADDR (REG_RIU_BASE_ADDR + 0x000004C4) +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_7_OFFSET 0x000004C4 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_7_INDEX 0x00000131 +#define RIU_CCA_CNT_ENERGY_THR_20_BAND_7_RESET 0x00000000 + +static inline u32 riu_cca_cnt_energy_thr_20_band_7_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_CCA_CNT_ENERGY_THR_20_BAND_7_ADDR); +} + +/* + * @brief AGCADCPOWSTAT_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PDBM5           0x0
+ *    23:16 INBDPOW20_PDBM4           0x0
+ *    14:08 ADCPOWDBV5                0x0
+ *    06:00 ADCPOWDBV4                0x0
+ * 
+ */ +#define RIU_AGCADCPOWSTAT_2_ADDR (REG_RIU_BASE_ADDR + 0x00000670) +#define RIU_AGCADCPOWSTAT_2_OFFSET 0x00000670 +#define RIU_AGCADCPOWSTAT_2_INDEX 0x0000019C +#define RIU_AGCADCPOWSTAT_2_RESET 0x00000000 + +static inline void riu_agcadcpowstat_2_unpack(struct cl_hw *cl_hw, + u8 *inbdpow20pdbm5, u8 *inbdpow20pdbm4, + u8 *adcpowdbv5, u8 *adcpowdbv4) +{ + u32 local_val = cl_reg_read(cl_hw, RIU_AGCADCPOWSTAT_2_ADDR); + + *inbdpow20pdbm5 = (local_val & ((u32)0xFF000000)) >> 24; + *inbdpow20pdbm4 = (local_val & ((u32)0x00FF0000)) >> 16; + *adcpowdbv5 = (local_val & ((u32)0x00007F00)) >> 8; + *adcpowdbv4 = (local_val & ((u32)0x0000007F)) >> 0; +} + +/* + * @brief AGCINBDPOW_20_PNOISESTAT_2 register definition + *
+ *   Bits           Field Name   Reset Value
+ *  -----   ------------------   -----------
+ *    31:24 INBDPOW20_PNOISEDBM5      0x0
+ *    23:16 INBDPOW20_PNOISEDBM4      0x0
+ *    15:08 ADCPOWDBM5                0x0
+ *    07:00 ADCPOWDBM4                0x0
+ * 
+ */ +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_ADDR (REG_RIU_BASE_ADDR + 0x0000067C) +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_OFFSET 0x0000067C +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_INDEX 0x0000019F +#define RIU_AGCINBDPOW_20_PNOISESTAT_2_RESET 0x00000000 + +static inline u32 riu_agcinbdpow_20_pnoisestat_2_get(struct cl_hw *cl_hw) +{ + return cl_reg_read(cl_hw, RIU_AGCINBDPOW_20_PNOISESTAT_2_ADDR); +} + +#endif /*_REG_RIU_H_ */ \ No newline at end of file diff --git a/blobs/regdump_44C0B000-44C0CFFF.bin b/blobs/regdump_44C0B000-44C0CFFF.bin new file mode 100644 index 0000000..b82bd36 Binary files /dev/null and b/blobs/regdump_44C0B000-44C0CFFF.bin differ diff --git a/cmake/add_module.cmake b/cmake/add_module.cmake new file mode 100644 index 0000000..1b53c9f --- /dev/null +++ b/cmake/add_module.cmake @@ -0,0 +1,49 @@ + +function (init_bl602module libname) + set(libname "${libname}" PARENT_SCOPE) + add_library(${libname} STATIC) + target_include_directories(${libname} PRIVATE ${CMAKE_SOURCE_DIR}/src/include/${libname}) +endfunction() + +function (add_bl602module module_name) + file(GLOB lSRCs + "${CMAKE_CURRENT_LIST_DIR}/${module_name}/*.c" + ) + get_property(gSrcs GLOBAL PROPERTY ${libname}_SRCs) + list(APPEND gSrcs ${lSRCs}) + set_property(GLOBAL PROPERTY ${libname}_SRCs "${gSrcs}") + + get_property(NEEDREMOVE GLOBAL PROPERTY ${libname}_NEEDREMOVE) + foreach(blsrc ${lSRCs}) + get_filename_component(wle ${blsrc} NAME_WLE) + list(APPEND NEEDREMOVE ${wle}) + endforeach() + + set_property(GLOBAL PROPERTY ${libname}_NEEDREMOVE "${NEEDREMOVE}") +endfunction() + +function (end_bl602module) + file(GLOB original_OBJs + "${PROJECT_SOURCE_DIR}/lib${libname}/*.o" + ) + + foreach(blobj ${original_OBJs}) + get_filename_component(wle ${blobj} NAME_WLE) + list(APPEND OBJs ${wle}) + endforeach() + + get_property(NEEDREMOVE GLOBAL PROPERTY ${libname}_NEEDREMOVE) + list(REMOVE_ITEM OBJs ${NEEDREMOVE}) + list(TRANSFORM OBJs PREPEND "${PROJECT_SOURCE_DIR}/lib${libname}/") + list(TRANSFORM OBJs APPEND ".o") + set_property(GLOBAL PROPERTY ${libname}_OBJs "${OBJs}") + + get_property(gSrcs GLOBAL PROPERTY ${libname}_SRCs) + target_sources(${libname} PRIVATE ${gSrcs} ${OBJs}) + + message(STATUS "Library info: ${libname}") + message(STATUS "Using Srcs") + message(STATUS "${gSrcs}") + message(STATUS "Using Objs") + message(STATUS "${OBJs}") +endfunction() \ No newline at end of file diff --git a/cmake/c_extension.cmake b/cmake/c_extension.cmake new file mode 100644 index 0000000..8eadc94 --- /dev/null +++ b/cmake/c_extension.cmake @@ -0,0 +1 @@ +set(CMAKE_C_OUTPUT_EXTENSION .o) \ No newline at end of file diff --git a/components/bl602/bl602_std/bl602_std/Device/Bouffalo/BL602/Peripherals/soc602_reg.svd b/components/bl602/bl602_std/bl602_std/Device/Bouffalo/BL602/Peripherals/soc602_reg.svd index 3cfdbb3..a04a85a 100644 --- a/components/bl602/bl602_std/bl602_std/Device/Bouffalo/BL602/Peripherals/soc602_reg.svd +++ b/components/bl602/bl602_std/bl602_std/Device/Bouffalo/BL602/Peripherals/soc602_reg.svd @@ -19918,4 +19918,4 @@ - \ No newline at end of file + diff --git a/script/inline_annotate.py b/script/inline_annotate.py index e3be69f..84c8bc7 100644 --- a/script/inline_annotate.py +++ b/script/inline_annotate.py @@ -57,8 +57,8 @@ def peek_line(f): root = CU.get_top_DIE() is_ble = 'components/network/ble/blecontroller' in root.get_full_path() is_wifi = 'bl602/bl602_wifi/' in root.get_full_path() - if ('ble' in path and not is_ble) or ('wifi' in path and not is_wifi): - continue + #if ('ble' in path and not is_ble) or ('wifi' in path and not is_wifi): + # continue proprietary.append(root) subroutines = [] diff --git a/script/manualext.py b/script/manualext.py index 65e4e96..cee7a9c 100755 --- a/script/manualext.py +++ b/script/manualext.py @@ -104,7 +104,6 @@ ############# AGC peris['agc'] = Peripheral(peripheral('agc', 0x44c0b000, 0x2000)) - Reg('r000', 0x44c0b000) FieldBit('iqcomp', 31-10) @@ -183,7 +182,7 @@ def scan_write(code, dat="dat"): name_r = f'r{hex(addr&0xffff)}' gid = gid + 1 r = Reg(name_r, addr) - yield r, Field(name_f, mask) + yield r, Field(name_f, mask), value agc_attr = [ @@ -252,12 +251,13 @@ def scan_write(code, dat="dat"): ] i = 0 -for r, f in scan_write(open('../blobs/agc_config.c').readlines()): +for r, f, val in scan_write(open('../blobs/agc_config.c').readlines()): if r.offset == agc_attr[i][0] - 0x44c0b000: f.name = agc_attr[i][1] else: print(f"mismatched {i} {agc_attr[i][1]} {hex(r.offset + 0x44c0b000)} {hex(agc_attr[i][0])}") i = i + 1 + #print(f"AGC->{r.name}.{f.name} = {hex(val)};") extra_regs = [ "rc_paoff_delay", @@ -270,7 +270,7 @@ def scan_write(code, dat="dat"): ] i = 0 -for _, f in scan_write([ +for _, f, _ in scan_write([ "write_volatile_4(DAT_44c0c020,uVar4 & 0xfc00ffff | 0x140000);", "write_volatile_4(DAT_44c0b390,uVar1 & 0xfffffeff);", "write_volatile_4(DAT_44c0b500,uVar4 & 0xffffcfff | 0x2000);", @@ -332,8 +332,25 @@ def getregs(fname, pattern='name'): peris['mac_core'] = Peripheral(peripheral('mac_core', 0x44b00000, 0x1000)) +Buf('ABS_TIMER', 0x44b00128, 0x44b00128 + 4 * 9) + +Reg('encr_ram_config', 0x44b000d8) +Field('start', 0xffffff00) +Field('end', 0xffff00ff) +Field('nVAP', 0xff00ffff) +Field('max', 0x00ffffff) + + for code, offset in getregs("../components/bl602/bl602_wifidrv/bl60x_wifi_driver/reg_mac_core.h", pattern='brief'): RegFromComment(offset + 0x44b00000, code) +Reg('coex_stat', 0x44b00408) +Goto(0x44b00400) +Field('coexForceEnable', 0xffffffef) +Field('coexForceWlanPti', 0x0FFFFFFF) +Field('coexForceWlanChanBw', 0xfbffffff) +Field('coexAutoPTIAdjEnable', 0xffffffdf) +FieldBit('coexForceWlanPtiToggle', 31 - 4) + #open('../src/include/phy/mac_core.h', 'w').write('\n'.join(GenHeader())) #print('\n'.join(GenHeader())) @@ -405,6 +422,7 @@ def getregs(fname, pattern='name'): FieldBit('time_greater_on_bit12', 0) Reg("diag_conf", 0x44900068) # set to 0x8000000c for init Field("diag_sel", 0xffff0000) +Reg("diag_trigger", 0x44900070) # used in force_trigger Reg("misc_cntl", 0x449000e0) # or with 0x1ff00 Field("set1", (~0x1ff00) & 0xffffffff) @@ -432,7 +450,26 @@ def getregs(fname, pattern='name'): peris['ipc'] = Peripheral(peripheral('ipc', 0x44800000, 0x1000)) for code, offset in getregs("../components/bl602/bl602_wifidrv/bl60x_wifi_driver/reg_ipc_app.h", pattern='brief'): - RegFromComment(offset + 0x44800000, code) + RegFromComment(offset + 0x44800000, code.lower()) +Reg('emb2app_line_sel_low', 0x44800000 + 0x14) +for i in range(0,16): + FieldBit(f'emb2app{i}_sel', i*2, 2) +Reg('emb2app_line_sel_high', 0x44800000 + 0x18) +ipc_names = [] +def flipname(name): + name = name.replace('app', 'XXXXX') + name = name.replace('emb', 'YYYYY') + name = name.replace('XXXXX', 'emb') + name = name.replace('YYYYY', 'app') + return name +for reg in peris['ipc'].regs: + if (len(reg.fields) == 1): + reg.fields = [] + ipc_names.append((flipname(reg.name), reg.offset + 0x100, reg.fields)) +for name, offset, f in ipc_names: + Reg(name, offset + 0x44800000) + for i in f: + FieldBit(flipname(i.name), i.lsb, i.len) #open('../src/include/phy/ipc.h', 'w').write('\n'.join(GenHeader())) #print('\n'.join(GenHeader())) @@ -458,7 +495,7 @@ def getregs(fname, pattern='name'): ] i = 0 -for r, f in scan_write(open('../blobs/bz_phy.c').readlines(), '0x'): +for r, f, _ in scan_write(open('../blobs/bz_phy.c').readlines(), '0x'): if r.offset == extra_bz_phy[i][0] - bz_phy_base: f.name = extra_bz_phy[i][1] else: @@ -479,6 +516,15 @@ def getregs(fname, pattern='name'): f = Field(field_name, mask) pass +intc_base = 0x44910000 +peris['intc'] = Peripheral(peripheral('intc', intc_base, 0x1000)) +def intc_handle(name, addr): + if name != 'irq_index': + Buf(name, addr, addr + 4) + else: + Reg(name, addr) +for code, offset in getregs("../alios/reg_intc.h"): + RegFromComment(offset + intc_base - 0x10000, code.lower(), intc_handle) if __name__ == '__main__': import sys diff --git a/script/reg.py b/script/reg.py new file mode 100755 index 0000000..ebf1e86 --- /dev/null +++ b/script/reg.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +def RegFromComment2(comment:str): + import re + field_pattern = r'\*\s+(\d\d)(:(\d\d))*\s*([^\s]+)\s+(.*)' + + field_matches = re.finditer(field_pattern, comment) + + for g in field_matches: + fname = g.group(4) + msb = int(g.group(1)) + lsb = g.group(3) + val = g.group(5) + if val.startswith("0x"): + val = int(val, 16) + else: + val = int(val) + if not lsb: + lsb = msb + else: + lsb = int(lsb) + yield fname, msb, lsb, val + + +def getregs(fname, pattern='name'): + import re + state = "idle" + regs = [] + if pattern == 'name': + name_pattern = r'\* @(name) ([^\s]+)' + else: + name_pattern = r'\* @(brief) ([^\s]+)' + addr_pattern = r'#define .*_OFFSET\s+0x([0-9A-F]+)' + name = '' + for i in open(fname).readlines(): + if state == "idle": + g = re.search(name_pattern, i) + if g: + name = g.group(2) + regs.append(i) + state = "find_reg" + elif state == "find_reg": + g = re.search(addr_pattern, i) + if g: + yield name, "".join(regs), int(g.group(1), 16) & 0xFFFFF + regs.clear() + state = "idle" + else: + regs.append(i) + + +binfile = open("../blobs/regdump_44C0B000-44C0CFFF.bin", "rb").read(0x2000) + + +import struct +for rname, r, offset in getregs('../blobs/reg_riu.h', pattern='brief'): + regdefault = binfile[offset:offset+4] + print(regdefault) + regdefault = int.from_bytes(regdefault, byteorder='little') + matched = True + print(f"Reg {rname}, val {regdefault} offset {hex(offset)}") + for name, msb, lsb, val in RegFromComment2(r): + vreset = (regdefault >> lsb) & ((2**(msb - lsb+1) - 1)) + print(f"\t{name}, expected {hex(val)}, get {hex(vreset)}") + if vreset != val: + matched = False diff --git a/script/reglib.py b/script/reglib.py index 7db82d2..4e503b3 100755 --- a/script/reglib.py +++ b/script/reglib.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -from typing import List, Union, Optional +from typing import Callable, List, Union, Optional def ident(l, n=1, ch=" "): si = ch * n @@ -63,6 +63,9 @@ def hasField(self, mask): return i return None + def size(self) -> int: + return 4 + def __gt__(self, reg2): return self.offset > reg2.offset def __str__(self): @@ -122,6 +125,8 @@ def __init__(self, name, offset, dim, nbytes=4): self.dim = dim self.nbytes = nbytes self.typename = TPNAME[nbytes] + def size(self) -> int: + return self.dim * self.nbytes def __gt__(self, reg2): return self.offset > reg2.offset def __str__(self): @@ -208,6 +213,7 @@ def genSVD(self): def genHeader(self): self.regs.sort() s = [ + f'#ifndef {self.name.upper()}_BASE', f'typedef union ' + "{", f'\tuint32_t regs[{hex(self.size//4)}];', f'\tuint8_t pad[{hex(self.size)}];', @@ -221,12 +227,13 @@ def genHeader(self): s.append(f'\t\tuint8_t pad{padId}[{hex(distance)}];') padId = padId + 1 s.extend(ident(i.genHeader(), 2, '\t')) - currentOffset = i.offset + 4 + currentOffset = i.offset + i.size() s.extend([ '\t};', "}" + f' {self.name}_regs;', f'#define {self.name.upper()}_BASE {hex(self.base)}', - f'#define {self.name.upper()} (({self.name}_regs* volatile)({self.name.upper()}_BASE))' + f'#define {self.name.upper()} ((volatile {self.name}_regs*)({self.name.upper()}_BASE))', + "#endif" ]) return s @@ -322,7 +329,7 @@ def CAccess(peris, addr, mask): return f"{p_name.upper()}->{r.name}" -def RegFromComment(addr, comment:str): +def RegFromComment(addr, comment:str, yd:Optional[Callable[[str, int], None]]=None): name = "" import re name_pattern = r'\* @(name|brief) ([^\s]+)' @@ -334,17 +341,21 @@ def RegFromComment(addr, comment:str): else: print("Cannot find group.") return - r = Reg(name, addr) - field_matches = re.finditer(field_pattern, comment) - - for g in field_matches: - msb = int(g.group(1)) - lsb = g.group(3) - if not lsb: - lsb = msb - else: - lsb = int(lsb) - FieldBit(g.group(4), lsb, msb-lsb+1) + if yd: + yd(name, addr) + else: + r = Reg(name, addr) + if isinstance(r, reg): + field_matches = re.finditer(field_pattern, comment) + + for g in field_matches: + msb = int(g.group(1)) + lsb = g.group(3) + if not lsb: + lsb = msb + else: + lsb = int(lsb) + FieldBit(g.group(4), lsb, msb-lsb+1) if __name__ == '__main__': diff --git a/src/bl602_wifi/CMakeLists.txt b/src/bl602_wifi/CMakeLists.txt new file mode 100644 index 0000000..4a198d2 --- /dev/null +++ b/src/bl602_wifi/CMakeLists.txt @@ -0,0 +1,25 @@ +init_bl602module("bl602_wifi") +add_bl602module("driver/phy/phy_rf") +add_bl602module("driver/phyif") +add_bl602module("driver/sysctrl") +add_bl602module("driver/ipc") +add_bl602module("driver/intc") +add_bl602module("hal") +add_bl602module("arch/rv32i") +add_bl602module("modules/common") +add_bl602module("modules/ke") +add_bl602module("modules/mac") +add_bl602module("modules/dbg") +add_bl602module("ip/lmac/bl") +add_bl602module("ip/lmac/chan") +add_bl602module("ip/lmac/mm") +add_bl602module("ip/lmac/ps") +add_bl602module("ip/lmac/rx") +add_bl602module("ip/lmac/rx/rxl") +add_bl602module("ip/lmac/scan") +add_bl602module("ip/lmac/sta") +add_bl602module("ip/lmac/td") +add_bl602module("ip/lmac/tpc") +add_bl602module("ip/lmac/tx/txl") +add_bl602module("ip/lmac/vif") +end_bl602module() \ No newline at end of file diff --git a/src/bl602_wifi/arch/rv32i/arch_main.c b/src/bl602_wifi/arch/rv32i/arch_main.c new file mode 100644 index 0000000..5d624d2 --- /dev/null +++ b/src/bl602_wifi/arch/rv32i/arch_main.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +int dbg_assert_block = 1; // :54:5 +extern uint8_t mac_hw_reset; + +void assert_rec(const char *condition, const char *file, int line) { + #ifdef PRINT_ASSERT + printf("[Assertion failed] [%s:%d] %s\r\n". file, line, condition); + #endif + if (mac_hw_reset != 1) + return ; + if (((int)ke_env.evt_field) < 0) + return ; + hal_machw_disable_int(); + ke_evt_set(KE_EVT_RESET_BIT); + return ; +} + +void assert_err(const char *condition, const char *file, int line) { + #ifdef PRINT_ASSERT + printf("[Assertion failed] [%s:%d] %s\r\n". file, line, condition); + #endif + for (;;); + __builtin_unreachable(); +} + +void assert_warn(const char *condition, const char *file, int line) { + #ifdef PRINT_ASSERT + printf("[Assertion failed] [%s:%d] %s\r\n". file, line, condition); + #endif +} + +void force_trigger(const char *msg) { + __disable_irq(); + SYSCTRL->diag_trigger = 1; + SYSCTRL->diag_trigger = 0; + __enable_irq(); +} + +static uint32_t packets_num; + +static void _check_chip_status(void) { + if (packets_num & 0xf) { + uint32_t ef_wifi_mac_high = EF_DATA_0->ef_wifi_mac_high.value; + uint32_t val = (ef_wifi_mac_high >> 0x18) & 7; + if (val != 0) { + if (val != 3) { + GLB->swrst_cfg1.swrst_s1a2 = 1; // _ir_check? + + PACK(GPIP->gpdac_config, gpdac_config) { + gpdac_config.gpdac_en = 0; + gpdac_config.gpdac_en2 = 0; + } + GPIP->gpdac_dma_config.gpdac_dma_tx_en = 0; + } + } + if ((ef_wifi_mac_high >> 0x18) & 4) { + // _reset_all_except_uart_gpio + GLB->swrst_cfg1.value = 0b00000000010111000010000000000000; + PACK(AON->gpadc_reg_cmd, gpadc_reg_cmd) { + gpadc_reg_cmd.gpadc_global_en = 0; + gpadc_reg_cmd.gpadc_soft_rst = 1; + } + } + } + packets_num = packets_num + 1; +} + +void coex_wifi_pta_forece_enable(int enable); + +void wifi_main(void *param) { + rfc_init(40000000); + MAC_CORE->COEX_CONTROL.coexEnable = 1; + mpif_clk_init(); + sysctrl_init(); + intc_init(); + ipc_emb_init(); + bl_init(); + PACK(MAC_CORE->COEX_PTI, pti) { + pti.coexPTIAck = 0x7; + pti.coexPTICntl = 0x3; + pti.coexPTIMgt = 0x0; + pti.coexPTIVOData = 0xf; + pti.coexPTIVIData = 0x4; + pti.coexPTIBEData = 0x2; + pti.coexPTIBKData = 0x0; + pti.coexPTIBcnData = 0x0; + } + MAC_CORE->COEX_CONTROL.value = 0x1; + MAC_CORE->COEX_CONTROL.value = 0; + MAC_CORE->COEX_CONTROL.value = 0x69; + MAC_CORE->COEX_CONTROL.coexAutoPTIAdjEnable = 0; + SYSCTRL92->ptr_config = 0x5010001f; + for (;;) { + int32_t counter = MAC_CORE->MONOTONIC_COUNTER_2_LO.monotonicCounterLow2; + if ((counter << 12) < 0) { + // or gpio_out? seems to be a selector? + SYSCTRL->time.time_greater_on_bit12 = 1; + } else { + SYSCTRL->time.time_greater_on_bit12 = 0; + } + if (ke_env.evt_field == 0) { + ipc_emb_wait(); + } + _check_chip_status(); + ke_evt_schedule(); + int res = bl_sleep(); + coex_wifi_pta_forece_enable(res == 0); + } +} + +void coex_dump_pta(void) { + #ifdef PRINT_ASSERT + printf("%d\r\n", SYSCTRL92->ptr_config); + #endif +} + +#define dump_print(var, field) printf(#field" = %u, ", (uint32_t)var.field); +#define DUMP(var, ...) APPLYarg(dump_print, var, __VA_ARGS__); + +void coex_dump_wifi(void) { + #ifdef PRINT_ASSERT + DUMP(MAC_CORE->COEX_CONTROL, coexEnable, coexForceEnable, coexWlanChanOffset, coexWlanChanFreq, coexForceWlanChanNw, coexForceWlanPtiToggle, coexForceWlanPti); + DUMP(MAC_CORE->COEX_PTI, coexPTIAck, coexPTICntl, coexPTIMgt, coexPTIVOData, coexPTIVIData, coexPTIBEData, coexPTIBKData, coexPTIBcnData); + printf("MAC_CORE->coex_stat = %u\r\n", MAC_CORE->coex_stat); + #endif +} + +void coex_wifi_rf_forece_enable(int enable) { + if (enable != 0) + enable = 1; + rfc_coex_force_to(enable, 0); +} + +void coex_wifi_pti_forece_enable(int enable) { + if (enable == 0) { + MAC_CORE->COEX_CONTROL.coexForceEnable = 0; + } else { + MAC_CORE->COEX_CONTROL.coexForceWlanPti = 0xf; + MAC_CORE->COEX_CONTROL.coexForceEnable = 1; + } + if (MAC_CORE->COEX_CONTROL.coexForceWlanPtiToggle) { + MAC_CORE->COEX_CONTROL.coexForceWlanChanBw = 0; + } else { + MAC_CORE->COEX_CONTROL.coexForceWlanChanBw = 1; + } +} + +uint32_t pds_slept_time; +uint32_t pds_woken_time; + +typedef enum { + SUCCESS = 0, + ERROR = 1, + TIMEOUT = 2, +} BL_Err_Type; +extern BL_Err_Type AON_LowPower_Enter_PDS0(void); +extern BL_Err_Type AON_LowPower_Exit_PDS0(void); + +void coex_wifi_pta_forece_enable(int enable) { + static int pta_status = 0xffffffff; + static TickType_t time_sleep; + if (pta_status != enable) { + if (pta_status == 0) { + TickType_t now = xTaskGetTickCount(); + pds_slept_time = pds_slept_time + (now - time_sleep); + } else { + if (pta_status == 1) { + TickType_t now = xTaskGetTickCount(); + pds_woken_time = pds_woken_time + (now - time_sleep); + __disable_irq(); + uint32_t bl_nap = bl_nap_calculate(); + __enable_irq(); + if (bl_nap > 1000) { + AON_LowPower_Enter_PDS0(); + vTaskDelay(bl_nap / 1000); + AON_LowPower_Exit_PDS0(); + + } + } + } + pta_status = enable; + time_sleep = xTaskGetTickCount(); + } +} diff --git a/src/bl602_wifi/driver/intc/intc.c b/src/bl602_wifi/driver/intc/intc.c new file mode 100644 index 0000000..70a6731 --- /dev/null +++ b/src/bl602_wifi/driver/intc/intc.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void intc_spurious(void) { + ASSERT_ERR(0); +} + +typedef void (*void_fn)(void); +static const void_fn intc_irq_handlers[64] = { + [10] = phy_mdm_isr, + [11] = phy_rc_isr, + [24 ... 28] = txl_payload_handle, + [29] = rxl_dma_int_handler, + [30] = ipc_emb_msg_dma_int_handler, + [31] = ipc_emb_dbg_dma_int_handler, + [34] = intc_spurious, + [36 ... 39] = intc_spurious, + [50] = rxl_timer_int_handler, + [51] = intc_spurious, + [52] = rxl_timer_int_handler, + [53] = txl_transmit_trigger, + [54] = hal_machw_gen_handler, + [55] = intc_spurious, + [60] = intc_spurious, + [61] = ipc_emb_msg_irq, + [62] = ipc_emb_cfmback_irq, + [63] = ipc_emb_tx_irq, +}; + +static void intc_enable_irq(int index) { + INTC->irq_unmask_set[index >> 5] = 1 << (index & 0x1F); +} + +void intc_init(void) { + intc_enable_irq(63); + intc_enable_irq(62); + intc_enable_irq(61); + intc_enable_irq(24); + intc_enable_irq(25); + intc_enable_irq(26); + intc_enable_irq(27); + intc_enable_irq(28); + intc_enable_irq(29); + intc_enable_irq(30); + intc_enable_irq(31); + intc_enable_irq(32); + intc_enable_irq(33); + intc_enable_irq(35); + intc_enable_irq(55); + intc_enable_irq(53); + intc_enable_irq(50); + intc_enable_irq(52); + intc_enable_irq(54); + intc_enable_irq(10); + intc_enable_irq(11); +} + +void mac_irq(void) { + if (INTC->irq_status[0] == 0 && INTC->irq_status[1] == 0) { + return ; + } + ASSERT_ERR(intc_irq_handlers[INTC->irq_index] != 0); + intc_irq_handlers[INTC->irq_index](); + ipc_emb_notify(); +} + +// this is actually defined in bl60x_wifi_driver/ipc_host.c +void ipc_host_disable_irq_e2a(void); + +void bl_irq_handler(void) { + ipc_host_disable_irq_e2a(); + ke_evt_set(KE_EVT_MAIN_BIT); + ipc_emb_notify(); +} diff --git a/src/bl602_wifi/driver/ipc/ipc_emb.c b/src/bl602_wifi/driver/ipc/ipc_emb.c new file mode 100644 index 0000000..36ba653 --- /dev/null +++ b/src/bl602_wifi/driver/ipc/ipc_emb.c @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IPC_EMB_SIGNATURE_RESET 0x49504332 + +int internel_cal_size_tx_desc; // :59:5 +static TaskHandle_t xTaskToNotify; // :91:21 +uint32_t ipc_emb_counter; // :92:10 +const uint32_t ipc_emb_evt_bit[5] = { + KE_EVT_IPC_EMB_TXDESC_AC0_BIT, + KE_EVT_IPC_EMB_TXDESC_AC1_BIT, + KE_EVT_IPC_EMB_TXDESC_AC2_BIT, + KE_EVT_IPC_EMB_TXDESC_AC3_BIT, + KE_EVT_IPC_EMB_TXDESC_BCN_BIT +}; + +struct ipc_emb_env_tag ipc_emb_env; // :110:24 +const int nx_txdesc_cnt_msk[1] = {3}; // :113:11 + +void ipc_emb_msg_dma_int_handler(void) { + // empty function + return ; +} + +void ipc_emb_dbg_dma_int_handler(void) { + DMA->int_ack.b7 = 1; + IPC->emb2app_trigger = 1; +} + +void ipc_emb_dump(void) { + // empty function + return ; +} + +uint32_t ipc_emb_tx_evt_field(uint32_t stat) { + // can't find impl + return 0; +} + +void ipc_emb_txcfm_ind(uint32_t queue_bits) { + IPC->emb2app_trigger = queue_bits << 7; +} + +void ipc_emb_init(void) { + xTaskToNotify = xTaskGetCurrentTaskHandle(); + memset(&ipc_emb_env, 0, 0x20); + ipc_emb_env.txdesc = ipc_shared_env.txdesc0; + ASSERT_ERR(IPC->emb_signature == IPC_EMB_SIGNATURE_RESET); + IPC->app2emb_line_sel_low.value = 0; + IPC->app2emb_line_sel_high = 0; + IPC->app2emb_line_sel_low.app2emb0_sel = 0; + IPC->app2emb_line_sel_low.app2emb1_sel = 1; + IPC->app2emb_line_sel_low.app2emb4_sel = 2; + IPC->app2emb_line_sel_low.app2emb5_sel = 2; + IPC->app2emb_line_sel_low.app2emb6_sel = 2; + IPC->app2emb_line_sel_low.app2emb8_sel = 3; + IPC->app2emb_line_sel_low.app2emb9_sel = 3; + IPC->app2emb_line_sel_low.app2emb10_sel = 3; + IPC->app2emb_line_sel_low.app2emb11_sel = 3; + IPC->app2emb_line_sel_low.app2emb12_sel = 3; + IPC->app2emb_unmask_set = 0x1f03; +} + +void ipc_emb_notify(void) { + ASSERT_ERR(xTaskToNotify != NULL); + if (TrapNetCounter == 0) { + xTaskGenericNotify(xTaskToNotify,0,eIncrement,(uint32_t *)0x0); + } else { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + vTaskNotifyGiveFromISR(xTaskToNotify, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken != 0) { + vTaskSwitchContext(); + } + } +} + +void ipc_emb_wait(void) { + ulTaskNotifyTake(1, portMAX_DELAY); +} + +void ipc_emb_tx_flow_off(void) { + IPC->app2emb_unmask_clear = 0x1f00; + ke_evt_clear(KE_EVT_IPC_EMB_TXDESC_MASK); + STATIC_ASSERT(KE_EVT_IPC_EMB_TXDESC_MASK == 0xf80, ipc_mask); +} + +void ipc_emb_tx_flow_on(void) { + IPC->app2emb_unmask_set = 0x1f00; +} + +void ipc_emb_tx_irq(void) { + uint32_t status = IPC->app2emb_status; + status &= 0x1f00; + if (status) { + // 21-25: IPC_EMB_TXDESC_XXX + ke_evt_set(status >> 1); + IPC->app2emb_unmask_clear = status; + IPC->app2emb_ack = status; + } +} + +void ipc_emb_txdesc_copy(struct txdesc *dst_local, volatile struct txdesc_host *src_shared) { + for (int i = 0; i < sizeof(struct hostdesc); i += 4) { + *(((uint32_t*)&dst_local->host) + i/4) = *(((uint32_t*)&src_shared->host) + i/4); + } +} + +void ipc_emb_tx_evt(int queue_idx) { + uint32_t event = ipc_emb_evt_bit[queue_idx]; + ke_evt_clear(event); + while (true) { + volatile struct txdesc_host* txdesc_hx = ipc_emb_env.txdesc + (ipc_emb_env.txdesc_idx & 3); + if (txdesc_hx->ready != 0xffffffff) { + IPC->app2emb_unmask_set = 0x100; + return ; + } + // delay event for some reason? + #define PRIORITY_EVENT (KE_EVT_PRIMARY_TBTT_BIT | KE_EVT_RXLREADY_BIT | KE_EVT_IPC_EMB_TXDESC_BCN_BIT) + if (((event & KE_EVT_IPC_EMB_TXDESC_BCN_BIT) == 0) && ((ke_evt_get() & PRIORITY_EVENT) != 0)) break; + IPC->app2emb_ack = 0x100; + struct txdesc* txdesc = (struct txdesc*)txdesc_hx->pad_txdesc; + memset(txdesc, 0, sizeof(struct txdesc)); + txdesc->hw_desc.cfm_ptr = &txdesc->hw_cfm; + txdesc->lmac.hw_desc = &txdesc->hw_desc; + ipc_emb_txdesc_copy(txdesc, txdesc_hx); + txdesc->lmac.agg_desc = 0; + txdesc->hw_desc.thd.nextmpdudesc_ptr = 0; + txdesc->hw_desc.thd.optlen[0] = 0; + txdesc->hw_desc.thd.optlen[1] = 0; + txdesc->hw_desc.thd.optlen[2] = 0; + txdesc->umac.buf_control = 0; + txu_cntrl_push(txdesc, 0); + txdesc_hx->ready = 1; + ipc_emb_env.txdesc_idx = ipc_emb_env.txdesc_idx + 1; + } + ke_evt_set(event); +} + +void ipc_emb_cfmback_irq(void) { + if (IPC->app2emb_status & 0x20) { + IPC->app2emb_unmask_clear = 0x20; + IPC->app2emb_ack = 0x20; + ke_evt_set(KE_EVT_RXLREADY_BIT); + } + if (IPC->app2emb_status & 0x10) { + IPC->app2emb_unmask_clear = 0x10; + IPC->app2emb_ack = 0x10; + ke_evt_set(KE_EVT_RXUREADY_BIT); + } +} + +bool ipc_emb_hostrxdesc_check(void) { + return 1; +} + +void ipc_emb_radar_event_ind(void) { + IPC->emb2app_trigger = 0x40; +} + +void ipc_emb_prim_tbtt_ind(void) { + IPC->emb2app_trigger = 0x10; +} + +void ipc_emb_sec_tbtt_ind(void) { + IPC->emb2app_trigger = 0x20; +} + +void ipc_emb_kmsg_hdlr(struct ke_msg *kmsg_ipc) { + struct ke_msg* kmsg_dst = ke_malloc(kmsg_ipc->param_len + sizeof(struct ke_msg)); + ASSERT_ERR(kmsg_dst != NULL); + kmsg_dst->hdr.next = NULL; + kmsg_dst->id = kmsg_ipc->id; + kmsg_dst->dest_id = kmsg_ipc->dest_id; + kmsg_dst->src_id = 13; + kmsg_dst->param_len = kmsg_ipc->param_len; + memcpy(kmsg_dst->param, kmsg_ipc->param, kmsg_dst->param_len); + kmsg_ipc->src_id = ipc_emb_env.ipc_msgacke2a_cnt++; + ipc_emb_env.ipc_msgacke2a_cnt = ipc_emb_env.ipc_msgacke2a_cnt; + ASSERT_ERR(ke_task_local(kmsg_dst->dest_id)); + IPC->emb2app_trigger = 4; + ke_msg_send(kmsg_dst + 1); +} + +void ipc_emb_msg_irq(void) { + if (IPC->app2emb_status & 2) { + ke_evt_set(KE_EVT_IPC_EMB_MSG_BIT); + IPC->app2emb_unmask_clear = 2; + } +} + +void ipc_emb_msg_evt(int dummy) { + for (uint32_t rawstatus = IPC->app2emb_rawstatus; rawstatus & 2; rawstatus = IPC->app2emb_rawstatus) { + IPC->app2emb_ack = 2; + ipc_emb_kmsg_hdlr((struct ke_msg *)&ipc_shared_env.msg_a2e_buf); + } + ke_evt_clear(KE_EVT_IPC_EMB_MSG_BIT); + IPC->app2emb_unmask_set = 2; +} diff --git a/src/bl602_wifi/driver/ipc/ipc_shared.c b/src/bl602_wifi/driver/ipc/ipc_shared.c new file mode 100644 index 0000000..5949185 --- /dev/null +++ b/src/bl602_wifi/driver/ipc/ipc_shared.c @@ -0,0 +1,3 @@ +#include + +struct ipc_shared_env_tag ipc_shared_env; // :24:27 \ No newline at end of file diff --git a/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_calib_data.c b/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_calib_data.c new file mode 100644 index 0000000..db68925 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_calib_data.c @@ -0,0 +1,10 @@ +#include + +#if 0 +#define RF_CALIB_DATA_ADDR (0x40020000) + +rf_calib_data_tag* rf_calib_data = (rf_calib_data_tag *)RF_CALIB_DATA_ADDR; +#else +static rf_calib_data_tag data = {0}; +rf_calib_data_tag* rf_calib_data = &data; +#endif \ No newline at end of file diff --git a/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_private.c b/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_private.c new file mode 100644 index 0000000..381def7 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/bl602_rf_private.c @@ -0,0 +1,1727 @@ +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#define kHz *1000 +#define MHz *1000*1000 +#define NUM_CHANNELS (21) +#define NUM_WIFI_CHANNELS (14) + +static uint32_t channel_div_table[21] = { + 0x14088889, 0x14111111, 0x1419999A, 0x14222222, + 0x142AAAAB, 0x14333333, 0x143BBBBC, 0x14444444, + 0x144CCCCD, 0x14555555, 0x145DDDDE, 0x14666666, + 0x146EEEEF, 0x14777777, 0x14800000, 0x14888889, + 0x14911111, 0x1499999A, 0x14A22222, 0x14AAAAAB, + 0x14B33333 +}; + +static uint16_t channel_cnt_table[21] = { + 0xA6EB, 0xA732, 0xA779, 0xA7C0, + 0xA808, 0xA84F, 0xA896, 0xA8DD, + 0xA924, 0xA96B, 0xA9B2, 0xA9F9, + 0xAA40, 0xAA87, 0xAACF, 0xAB16, + 0xAB5D, 0xABA4, 0xABEB, 0xAC32, + 0xAC79 +}; + +static uint16_t fcal_div = 0x855; + +static tx_pwr_index data; +tx_pwr_index* tp_index = &data; + +void rf_pri_config_bandwidth(uint32_t bw) { + RF->rbb3.rbb_bw = bw; +} + +static uint16_t channel_cnt_range[3] = { + 0xA6A0, 0xA6E0, 0xACE0 +}; + +static uint16_t channel_cw_table[21]; +static uint16_t channel_cnt_opt_table[40]; + +// meas = measure? +uint16_t rf_pri_fcal_meas(uint32_t cw) { + RF->vco1.lo_vco_freq_cw = cw; + BL602_Delay_US(100); + RF->vco4.fcal_cnt_start = 1; + do { + if (RF->vco4.fcal_cnt_rdy) break; + } while (1); + uint16_t fcal_meas = RF->vco3.fcal_cnt_op; + RF->vco4.fcal_cnt_start = 0; + return fcal_meas; +} + +typedef struct { +#define RF_PRI_SAVE(field) uint32_t field; +#include "rf_private_save.h" +} rf_state_save_t; + +static rf_state_save_t rf_state; + +static void rf_pri_save_state_for_cal() { +#define RF_PRI_SAVE(field) rf_state.field = RF->field.value; +#include "rf_private_save.h" +} + + +static void rf_pri_restore_state_for_cal() { +#define RF_PRI_SAVE(field) RF->field.value = rf_state.field; +#include "rf_private_save.h" +} + +#include +#define mapper0(x) new_pucr1.x = 0; +#define mapper1(x) new_pucr1.x = 1; +#define P_CLR(...) APPLY(mapper0, __VA_ARGS__) +#define P_SET(...) APPLY(mapper1, __VA_ARGS__) + +static void rf_pri_manu_pu(uint32_t mode) { + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 0; + RF->rfctrl_hw_en.value = 0; + + __typeof__ (((rf_regs* )(RF_BASE))->pucr1) new_pucr1 = RF->pucr1; + + switch (mode) { + case E_RF_MODE_RCCAL: + P_CLR(pu_lna, pu_rmxgm, pu_rmx, pu_pkdet, + pu_pwrmx, pu_pa, pu_tmx, pu_tbb, + pu_rxbuf, pu_txbuf, pu_tosdac); + P_SET(pu_osmx, pu_pfd, pu_fbdv, pu_vco, + pu_rbb, pu_adc, adc_clk_en, pu_rosdac, + pu_dac, trsw_en); + break; + case E_RF_MODE_TXCAL: + P_CLR(pu_lna, pu_rmxgm, pu_rmx, pu_pkdet, pu_rosdac, pu_rxbuf); + P_SET(pu_txbuf, trsw_en, pu_tosdac, pu_osmx, + pu_pfd, pu_fbdv, pu_vco, pu_rbb, + pu_adc, adc_clk_en, pu_pwrmx, pu_pa, + pu_tmx, pu_tbb, pu_dac); + break; + + case E_RF_MODE_LO_ACAL: + case E_RF_MODE_LO_FCAL: + P_CLR(pu_lna, pu_rmxgm, pu_rmx, pu_tosdac, + pu_rbb, pu_adc, adc_clk_en, pu_pkdet, + pu_rosdac ,pu_pwrmx, pu_pa, pu_tmx, + pu_tbb,pu_dac,pu_rxbuf,pu_txbuf, + trsw_en); + P_SET(pu_osmx, pu_pfd, pu_fbdv, pu_vco); + break; + // in the leak code, this function treat + // 0...2 + default cases with the same code as 6...7 code + // however, in the binary, it uses the same logic + // as case 3 for 0...2 + default cases + // this branch should never touched unless mode == 3 + // so the 0...2 and default should never be used. + // that is why an error is added here. + default: + case E_RF_MODE_IDLE ... E_RF_MODE_RX: + printf("unexpected values for rf_pri_manu_pu\r\n"); + case E_RF_MODE_ROSCAL: + P_CLR(pu_lna, pu_pkdet, pu_pwrmx, pu_pa, + pu_tmx, pu_tbb, pu_dac, pu_txbuf, + pu_tosdac); + P_SET(pu_osmx, pu_pfd, pu_fbdv, pu_vco, + pu_rmxgm, pu_rmx, pu_rbb, pu_adc, + adc_clk_en, pu_rxbuf, trsw_en, pu_rosdac); + break; + } + RF->pucr1 = new_pucr1; +} + +static void rf_pri_config_mode(uint32_t mode) { + rf_pri_manu_pu(mode); +} + +#undef P_SET +#undef P_CLR +#undef mapper0 +#undef mapper1 + + +void rf_pri_fcal(void) { + RF->rfcal_status.fcal_status = 0x1; + + rf_pri_save_state_for_cal(); // TBI + rf_pri_config_mode(E_RF_MODE_LO_FCAL); // TBI + + RF->rfcal_ctrlen.fcal_en = 1; + + RF->vco1.lo_vco_freq_cw = 0x80; + RF->fbdv.lo_fbdv_sel_fb_clk = 0; + RF->vco3.fcal_div = fcal_div; + // frequency counter counts # RF periods within a counter + // clock cycle fcal_div is a divider for the counter clock. + + RF->sdm2.value = 0x1000000; + RF->sdm1.lo_sdm_bypass = 1; + + RF->sdm1.lo_sdm_rstb = 0; + RF->fbdv.lo_fbdv_rst = 1; + + BL602_Delay_US(10); + + RF->sdm1.lo_sdm_rstb = 1; + RF->fbdv.lo_fbdv_rst = 0; + + BL602_Delay_US(50); + + RF->vco2.lo_vco_vbias_cw = 2; + + BL602_Delay_US(50); + + uint16_t c0 = (uint16_t)channel_cnt_range[0]; + uint16_t c1 = (uint32_t)channel_cnt_range[1]; + uint16_t c2 = (uint16_t)channel_cnt_range[2]; + + uint16_t cw = 0x80; + while (1) { + for (int j = 6; j >= 0; j--) { + int cnt = rf_pri_fcal_meas(cw); + if (cnt < c0) { + cw -= (1 << j); + } else { + if (cnt > c1) { + cw += (1 << j); + } else break; + } + } + + if (cw >= 15) + break; + + printf("Unexpected cw %ld\r\n", cw); + cw = 0x80; + /// reset + RF->sdm1.lo_sdm_rstb = 0; + RF->fbdv.lo_fbdv_rst = 1; + BL602_Delay_US(0x32); + RF->sdm1.lo_sdm_rstb = 1; + RF->fbdv.lo_fbdv_rst = 0; + BL602_Delay_US(0x32); + } + cw++; + channel_cnt_opt_table[0] = rf_pri_fcal_meas(cw); + for (int i = 1; i < 40; i++) { + uint16_t cnt = rf_pri_fcal_meas(cw-i); + channel_cnt_opt_table[i] = cnt; + if (cnt > c2) break; + } + + for (int i = 0, j = 0; i < 21; i++) { + while (channel_cnt_opt_table[j] < channel_cnt_table[i]) j++; + channel_cw_table[i] = cw - (j - 1); /// hmmm what if j = 0? + /// or it can't because cw was + 1.. + if (j > 0) j--; + } + + rf_pri_restore_state_for_cal(); + + for (int i = 0; i < 21; i++) { + rf_calib_data->lo[i].fcal = channel_cw_table[i]; + printf("%ldth channel,lo_vco_freq_cw=%ld\r\n", i + 1, (uint32_t)(channel_cw_table[i])); + } + + RF->rfcal_status.fcal_status = 3; // 0b11 +} + +void rf_pri_start_rxdfe() { + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.rx_dfe_en_4s_en = 0; + rfif_dfe_ctrl0.rx_dfe_en_4s = 0; + } + + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.rfckg_rxclk_4s_on = 1; + rfif_dfe_ctrl0.rx_dfe_en_4s = 1; + rfif_dfe_ctrl0.rx_dfe_en_4s_en = 1; + } +} + +// TODO: verify me +void rf_pri_start_txdfe() { + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.tx_dfe_en_4s_en = 0; + rfif_dfe_ctrl0.tx_dfe_en_4s = 0; + } + + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.rfckg_txclk_4s_on = 1; + rfif_dfe_ctrl0.tx_test_sel = 2; + rfif_dfe_ctrl0.tx_dfe_en_4s = 1; + } + + RF->rfif_dfe_ctrl0.tx_dfe_en_4s_en = 1; +} + +static void rf_pri_config_channel(uint32_t channel_index) { + // sdm = sigma-delta modulator ? + printf("lo_vco_freq[%d] = %d, %d\n", channel_index, rf_calib_data->lo[channel_index].fcal, rf_calib_data->lo[channel_index].acal); + PACK(RF->vco1, vco1) { + vco1.lo_vco_freq_cw = rf_calib_data->lo[channel_index].fcal; + vco1.lo_vco_idac_cw = rf_calib_data->lo[channel_index].acal; + } + RF->lodist.lo_osmx_cap = rf_calib_data->lo[channel_index].fcal >> 4; + RF->sdm2.lo_sdmin = channel_div_table[channel_index]; + RF->sdm1.lo_sdm_bypass = 0; + + while (1) { + RF->fbdv.lo_fbdv_rst = 1; + BL602_Delay_US(10); + + RF->fbdv.lo_fbdv_rst = 0; + BL602_Delay_US(50); + + RF->pfdcp.lo_pfd_rst_csd = 1; + BL602_Delay_US(10); + + RF->pfdcp.lo_pfd_rst_csd = 0; + BL602_Delay_US(50); + + __typeof__ (((rf_regs* )(RF_BASE))->lo) mylo = RF->lo; + + if (mylo.lo_slipped_dn || mylo.lo_slipped_up) { + printf("."); + } else { + printf("LO locked %ld %ld\r\n", channel_index, (uint32_t)rf_calib_data->lo[channel_index].fcal); + break; + } + } +} + +static int32_t rf_pri_pm_pwr_avg(uint32_t iq, uint32_t acc_len) { + PACK(RF->dfe_ctrl_6, dfe_ctrl_6) { + RF->dfe_ctrl_6.rx_pm_en = 0; + RF->dfe_ctrl_6.rx_pm_freqshift_en = 0; + } + //RF->dfe_ctrl_6.value &= 0xdfefffff; + RF->dfe_ctrl_7.rx_pm_acc_len = acc_len; + + RF->dfe_ctrl_6.rx_pm_en = 1; + + for (; !(RF->dfe_ctrl_6.rx_pm_done);); + + int32_t iqacc = 0; + if (iq) { + // iq = 1 => i + iqacc = RF->dfe_ctrl_8.rx_pm_iqacc_i; + } else { + // iq = 0 => q + iqacc = RF->dfe_ctrl_9.rx_pm_iqacc_q; + } + iqacc = (iqacc << 7) >> 7; + //RF->dfe_ctrl_6.value &= 0xdfefffff; + PACK(RF->dfe_ctrl_6, dfe_ctrl_6) { + RF->dfe_ctrl_6.rx_pm_en = 0; + RF->dfe_ctrl_6.rx_pm_freqshift_en = 0; + } + return iqacc; +} + +static void rf_pri_roscal_config(uint32_t iq,uint32_t rosdac) { + uint32_t tmpVal = 0; + if (iq) { + RF->rbb1.rosdac_i = rosdac; + } else { + RF->rbb1.rosdac_q = rosdac; + } +} + +static uint32_t rf_pri_roscal_iq(uint32_t iq, uint32_t sram_start_addr, uint32_t length) { + uint32_t rosdac = 0; + for (int i = 5; i >= 0; i--) { + uint32_t uvar7 = rosdac + (1 << i); + rf_pri_roscal_config(iq, uvar7); + if (rf_pri_pm_pwr_avg(iq, 1024) < 1) // leak code says <= 0? + rosdac = uvar7; + } + + uint8_t seq_pattern = 0; + + for (int i = 0; i < 63; i++) { + rf_pri_roscal_config(iq, rosdac); + int32_t pwr = rf_pri_pm_pwr_avg(iq, 1024); + if (pwr < 1) { + seq_pattern = (seq_pattern << 1) & 0xf; + rosdac++; + } else { + seq_pattern = ((seq_pattern << 1) + 1) & 0xf; + rosdac--; + } + if ((seq_pattern == 0b1010) || (seq_pattern == 0b0101)) + break; + } + + return rosdac; +} + +void rf_pri_roscal() { + if (RF->rfcal_stateen.roscal_sten == 0) { + RF->rfcal_status.ros_status = 0; + return ; + } + + RF->rfcal_status.ros_status = 1; + // td + rf_pri_save_state_for_cal(); + rf_pri_config_mode(E_RF_MODE_ROSCAL); + RF->rfcal_ctrlen.roscal_en = 1; + + rf_pri_config_channel(3); // in the leak source the value here is 9. + + RF->trx_gain1.gc_rbb2 = 6; + RF->trx_gain1.gc_rbb1 = 3; + + uint32_t rosdac = rf_pri_roscal_iq(1, 0 /* unused */, 0 /* unused */); + + rf_calib_data->rxcal[3].rosdac_i = rosdac; + + RF->rosdac_ctrl_hw2.rosdac_i_gc3 = rosdac; + printf("rosdac_i_gc3=%ld\r\n", rosdac); + + rf_calib_data->rxcal[2].rosdac_i = rosdac; + + RF->rosdac_ctrl_hw2.rosdac_i_gc2 = rosdac; + printf("rosdac_i_gc2=%ld\r\n", rosdac); + + rf_calib_data->rxcal[1].rosdac_i = rosdac; + + RF->rosdac_ctrl_hw1.rosdac_i_gc1 = rosdac; + printf("rosdac_i_gc1=%ld\r\n", rosdac); + + rf_calib_data->rxcal[0].rosdac_i = rosdac; + + RF->rosdac_ctrl_hw1.rosdac_i_gc0 = rosdac; + printf("rosdac_i_gc0=%ld\r\n", rosdac); + + rosdac = rf_pri_roscal_iq(0, 0 /* unused */, 0 /* unused */); + + rf_calib_data->rxcal[3].rosdac_q = rosdac; + + RF->rosdac_ctrl_hw2.rosdac_q_gc3 = rosdac; + printf("rosdac_q_gc3=%ld\r\n", rosdac); + + rf_calib_data->rxcal[2].rosdac_q = rosdac; + + RF->rosdac_ctrl_hw2.rosdac_q_gc2 = rosdac; + printf("rosdac_q_gc2=%ld\r\n", rosdac); + + rf_calib_data->rxcal[1].rosdac_q = rosdac; + + RF->rosdac_ctrl_hw1.rosdac_q_gc1 = rosdac; + printf("rosdac_q_gc1=%ld\r\n", rosdac); + + rf_calib_data->rxcal[0].rosdac_q = rosdac; + + RF->rosdac_ctrl_hw1.rosdac_q_gc0 = rosdac; + printf("rosdac_q_gc0=%ld\r\n", rosdac); + + rf_pri_restore_state_for_cal(); + + RF->rfcal_status.ros_status = 3; +} + +void rf_pri_full_cal(void) { + // dfe + rf_pri_start_rxdfe(); + rf_pri_start_txdfe(); + rf_pri_fcal(); + rf_pri_lo_acal(); + rf_pri_roscal(); + rf_pri_rccal(); + rf_pri_txcal(); + + PACK(RF->rfctrl_hw_en, rfctrl_hw_en) { + rfctrl_hw_en.rx_gain_ctrl_hw = 1; + rfctrl_hw_en.tx_gain_ctrl_hw = 1; + } + + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.rfckg_rxclk_4s_on = 0; + rfif_dfe_ctrl0.rx_dfe_en_4s_en = 0; + rfif_dfe_ctrl0.rx_dfe_en_4s = 0; + } + + PACK(RF->rfif_dfe_ctrl0, rfif_dfe_ctrl0) { + rfif_dfe_ctrl0.rfckg_txclk_4s_on = 0; + rfif_dfe_ctrl0.tx_dfe_en_4s_en = 0; + rfif_dfe_ctrl0.tx_dfe_en_4s = 0; + rfif_dfe_ctrl0.tx_test_sel = 0; + } +} +static int32_t rx_notch_para[14][2] = { + {0,0}, {0,0}, {0,0}, {0,0}, + {1,8 MHz}, + {1,3 MHz}, + {1,-2 MHz}, + {1,-7 MHz}, + {0,0}, {0,0}, {0,0}, {0,0}, + {1,8 MHz}, + {1,-4 MHz}, +}; + +void rf_pri_get_notch_param(uint32_t chanfreq_MHz, uint8_t * ncf_on, int32_t * ncf_freq_Hz) { + uint32_t channel_id; + channel_id = 13; + if (chanfreq_MHz < 2473) { + channel_id = (chanfreq_MHz - 2412) / 5; + } + + *ncf_on = (uint8_t)rx_notch_para[channel_id][0]; + *ncf_freq_Hz = rx_notch_para[channel_id][1]; +} + +uint32_t rf_pri_get_vco_freq_cw(uint32_t chanfreq_MHz) { + int32_t a = (int32_t)((chanfreq_MHz-2404)/4 + 0.5); + a = a < 0 ? 0 : a; + if (a > NUM_CHANNELS - 1) + a = NUM_CHANNELS - 1; + return rf_calib_data->lo[a].fcal; +} + +uint32_t rf_pri_get_vco_idac_cw(uint32_t chanfreq_MHz) { + int32_t a = (int32_t)((chanfreq_MHz-2404)/4 + 0.5); + a = a < 0 ? 0 : a; + if (a > NUM_CHANNELS - 1) + a = NUM_CHANNELS - 1; + return rf_calib_data->lo[a].acal; +} + +void rf_pri_lo_acal(void) { + RF->rfcal_status.acal_status = 0x1; + rf_pri_save_state_for_cal(); + rf_pri_config_mode(E_RF_MODE_LO_ACAL); + + for (int i = 0; i < 21; i++) { + RF->rfcal_ctrlen.acal_en = 1; + RF->vco2.acal_vref_cw = 4; + RF->vco1.lo_vco_idac_cw = 0x10; + RF->vco1.lo_vco_freq_cw = rf_calib_data->lo[i].fcal; + RF->sdm2.lo_sdmin = channel_div_table[i]; + BL602_Delay_US(1); + uint32_t cw = 0x10; + for (int j = 3; j >= 0; j--) { + RF->vco1.lo_vco_idac_cw = cw; + BL602_Delay_US(1); + if (RF->vco2.acal_vco_ud) { + cw -= (1 << j); + } else { + cw += (1 << j); + } + } + RF->vco1.lo_vco_idac_cw = cw; + BL602_Delay_US(1); + if (!RF->vco2.acal_vco_ud) { + if (cw != (1<<5) - 1) { + cw++; + } + } + rf_calib_data->lo[i].acal = cw; + } + rf_pri_restore_state_for_cal(); + RF->rfcal_status.acal_status = 0x3; +} + + +static void rf_pri_rccal_config(uint32_t iq, uint32_t rbb_fc) { + PACK(RF->rbb2, rbb2) + if (iq) { + // i + rbb2.rbb_cap1_fc_i = rbb_fc; + rbb2.rbb_cap2_fc_i = rbb_fc; + } else { + rbb2.rbb_cap1_fc_q = rbb_fc; + rbb2.rbb_cap2_fc_q = rbb_fc; + } +} + + +static void rf_pri_singen_config(uint32_t fcw, uint32_t start_addr_i, uint32_t start_addr_q) { + RF->singen_ctrl0.singen_inc_step0 = fcw; + RF->singen_ctrl2.singen_start_addr0_i = start_addr_i; // 0; + RF->singen_ctrl3.singen_start_addr0_q = start_addr_q; // 0x300; +} + +static void rf_pri_singen_start(void) { + RF->singen_ctrl0.singen_en = 0; + + RF->singen_ctrl0.singen_en = 1; +} + +static void rf_pri_singen_amplitude(uint32_t gain_i, uint32_t gain_q) { + RF->singen_ctrl2.singen_gain_i = gain_i; + RF->singen_ctrl3.singen_gain_q = gain_q; +} + +static uint32_t rf_pri_pm_pwr() { + PACK(RF->dfe_ctrl_6, dfe) { + dfe.rx_pm_freqshift_en = 0; + dfe.rx_pm_en = 0; + } + + PACK(RF->dfe_ctrl_6, dfe) { + dfe.rx_pm_freqshift_en = 1; + dfe.rx_pm_en = 1; + } + + for (; ! RF->dfe_ctrl_6.rx_pm_done; ); + + int32_t pm_iacc = RF->dfe_ctrl_8.value; + pm_iacc = (pm_iacc << 7) >> (7 + 9); + + int32_t pm_qacc = RF->dfe_ctrl_9.value; + pm_qacc = (pm_qacc << 7) >> (7 + 9); + + + PACK(RF->dfe_ctrl_6, dfe) { + dfe.rx_pm_freqshift_en = 0; + dfe.rx_pm_en = 0; + } + + return pm_iacc * pm_iacc + pm_qacc * pm_qacc; +} + + +static uint32_t rf_pri_rccal_iq(uint32_t iq) { + if (iq) { + RF->dfe_ctrl_3.rx_adc_4s_q_en = 0; + RF->dfe_ctrl_3.rx_adc_4s_i_en = 1; + } else { + RF->dfe_ctrl_3.rx_adc_4s_i_en = 0; + RF->dfe_ctrl_3.rx_adc_4s_q_en = 1; + } + + PACK(RF->trx_gain1, trx_gain1) { + trx_gain1.gc_rbb1 = 1; + trx_gain1.gc_rbb2 = 3; + } + + int k1 = 3, k2 = 181; + rf_pri_singen_config(k1, 0, 0x300); + + rf_pri_singen_amplitude(0x3ff, 0x3ff); + + rf_pri_singen_start(); + rf_pri_start_txdfe(); + RF->dfe_ctrl_6.rx_pm_freqshift_cw = k1 << 10; + rf_pri_pm_pwr_avg(iq, 0x400); + + double rccal_power_scale = 0.9 * 0.9; + uint32_t rccal_ref = (uint32_t)(rccal_power_scale * rf_pri_pm_pwr()); + + + PACK(RF->trx_gain1, trx_gain1) { + trx_gain1.gc_rbb1 = 2; + trx_gain1.gc_rbb2 = 6; + } + + rf_pri_singen_config(k2, 0x0, 0x300); + rf_pri_singen_start(); + rf_pri_start_txdfe(); + + RF->dfe_ctrl_6.rx_pm_freqshift_cw = k2 << 10; + + uint32_t rbb_fc = 0; + for (int i = 5; i >= 0; i--) { + rf_pri_rccal_config(iq, rbb_fc + (1 << i)); + uint32_t rccal_val = rf_pri_pm_pwr(); + if (rccal_val > rccal_ref) { + rbb_fc += (1 << i); + } + } + + uint8_t seq_pattern = 0; + for (int i = 0; i < 63; i++) { + rf_pri_rccal_config(iq, rbb_fc); + uint32_t rccal_val = rf_pri_pm_pwr(); + if (rccal_ref < rccal_val) { + seq_pattern = ((seq_pattern << 1) | 1) & 0xf; + rbb_fc++; + } else { + seq_pattern = (seq_pattern << 1) & 0xf; + rbb_fc--; + } + if ((seq_pattern == 0b0101) || (seq_pattern == 0b1010)) + return 3; + } + + return 2; +} + +// resistor-capacitor? +void rf_pri_rccal(void) { + if (RF->rfcal_stateen.rccal_sten) { + RF->rfcal_status.rccal_status = 0; + } else { + RF->rfcal_status.rccal_status = 1; + rf_pri_save_state_for_cal(); + rf_pri_config_mode(E_RF_MODE_RCCAL); + RF->rbb3.rbb_bw = 2; + RF->adda1.dac_rccalsel = 1; + RF->rfcal_ctrlen.rccal_en = 1; + uint32_t i = rf_pri_rccal_iq(1); + uint32_t q = rf_pri_rccal_iq(0); + + __typeof__ (RF->rbb2) data = RF->rbb2; + + rf_calib_data->cal.rbb_cap1_fc_i = data.rbb_cap1_fc_i; + rf_calib_data->cal.rbb_cap1_fc_q = data.rbb_cap1_fc_q; + rf_calib_data->cal.rbb_cap2_fc_i = data.rbb_cap2_fc_i; + rf_calib_data->cal.rbb_cap2_fc_q = data.rbb_cap2_fc_q; + + printf("rbb_cap1_fc_i=%ld,rbb_cap2_fc_i=%ld,rbb_cap1_fc_q=%ld,rbb_cap2_fc_q=%ld\r\n", + (uint32_t)(rf_calib_data->cal.rbb_cap1_fc_i), + (uint32_t)(rf_calib_data->cal.rbb_cap2_fc_i), + (uint32_t)(rf_calib_data->cal.rbb_cap1_fc_q), + (uint32_t)(rf_calib_data->cal.rbb_cap2_fc_q)); + int32_t maxcw = MAX( MAX(rf_calib_data->cal.rbb_cap1_fc_i, rf_calib_data->cal.rbb_cap1_fc_q), + MAX(rf_calib_data->cal.rbb_cap2_fc_i, rf_calib_data->cal.rbb_cap2_fc_q)); + //int32_t tgt_offset_cw = 24; + //int32_t offset_cw = (max_cw + tgt_offset_cw) <= 63 ? tgt_offset_cw : 63 - max_cw; + int32_t offset_cw = 24; + if (maxcw > 39) + offset_cw = 63 - maxcw; + rf_calib_data->cal.rbb_cap1_fc_i += offset_cw; + rf_calib_data->cal.rbb_cap1_fc_q += offset_cw; + rf_calib_data->cal.rbb_cap2_fc_i += offset_cw; + rf_calib_data->cal.rbb_cap2_fc_q += offset_cw; + + rf_pri_rccal_config(1, rf_calib_data->cal.rbb_cap1_fc_i); + rf_pri_rccal_config(0, rf_calib_data->cal.rbb_cap1_fc_q); + + printf("new rbb_cap1_fc_i=%ld,rbb_cap2_fc_i=%ld,rbb_cap1_fc_q=%ld,rbb_cap2_fc_q=%ld\r\n", + (uint32_t)(rf_calib_data->cal.rbb_cap1_fc_i), + (uint32_t)(rf_calib_data->cal.rbb_cap2_fc_i), + (uint32_t)(rf_calib_data->cal.rbb_cap1_fc_q), + (uint32_t)(rf_calib_data->cal.rbb_cap2_fc_q)); + + rf_pri_restore_state_for_cal(); + + if ((i == 2) || (q == 2)) { + RF->rfcal_status.rccal_status = 2; + } else { + RF->rfcal_status.rccal_status = 3; + } + } +} + +static uint32_t txcal_para[E_RF_TXCAL_GAIN_CNT][4]; +static uint32_t txcal_para_a0[E_RF_TXCAL_GAIN_CNT][4] = { + { 0, 2, 6, 256}, + { 0, 2, 1, 256}, + { 0, 2, 0, 304}, + { 0, 4, 0, 240}, + { 0, 4, 0, 304}, + { 0, 4, 0, 352}, + { 0, 4, 0, 416}, + { 0, 4, 0, 416} +}; + +static uint32_t txcal_para_a1[E_RF_TXCAL_GAIN_CNT][4] = { + { 0, 2, 14, 256}, + { 0, 2, 5, 256}, + { 0, 2, 1, 256}, + { 0, 4, 2, 272}, + { 0, 4, 0, 224}, + { 0, 4, 0, 272}, + { 0, 4, 0, 288}, + { 0, 4, 0, 304} +}; + +static void rf_pri_config_txgain(uint32_t gc_tbb_boost, uint32_t gc_tmx, uint32_t gc_tbb) { + PACK(RF->trx_gain1, value) { + value.gc_tbb_boost = gc_tbb_boost; + value.gc_tmx = gc_tmx; + value.gc_tbb = gc_tbb; + } +} + +static int32_t tx_pwr_os = 0; // channel offset +static int32_t tx_pwr_os_temperature = 0; // temperature offset + +static int32_t tx_pwr_table[E_RF_TXPWR_TBL_CNT][7]; +static int32_t tx_pwr_table_origin[E_RF_TXPWR_TBL_CNT][7]; +static int32_t tx_pwr_table_a0[E_RF_TXPWR_TBL_CNT][7] = { + // gain_ctrl_gc_tbb, gain_ctrl_gc_tmx, gain_ctrl_dac_bias_sel, gain_ctrl_gc_tbb_boost + {0, 1, 7, 0x14, 32, 4, 233}, + {0, 1, 7, 0x14, 32, 0, 223}, + {0, 1, 7, 0xe, 32, 4, 212}, + {0, 1, 7, 0xe, 32, 0, 202}, + {0, 1, 7, 0xa, 32, 4 + 1, 188 + 3}, + {0, 1, 7, 0xa, 32, 0 + 1, 178 + 3}, + {0, 1, 7, 8, 32, 4 - 1, 173 - 3}, + {0, 1, 7, 8, 32, 0 - 1, 163 - 3}, + {0, 1, 7, 6, 32, 4 - 1, 153 - 3}, + {0, 1, 7, 6, 32, 0 - 1, 143 - 3}, + {0, 1, 6, 5, 32, 4 + 1, 129 + 3}, + {0, 1, 6, 5, 32, 0 + 1, 119 + 3}, + {0, 1, 6, 4, 32, 4 - 1, 114 - 3}, + {0, 1, 6, 4, 32, 0 - 1, 104 - 3}, + {0, 1, 5, 4, 32, 0, 91}, + {0, 1, 5, 4, 32, -4, 81}, +}; + +static int32_t tx_pwr_table_a1[E_RF_TXPWR_TBL_CNT][7] = { + // gain_ctrl_gc_tbb, gain_ctrl_gc_tmx, gain_ctrl_dac_bias_sel, gain_ctrl_gc_tbb_boost + { 0, 1, 7, 27, 32, -4, 230}, + { 0, 1, 7, 27, 32, -8, 220}, + { 0, 1, 7, 20, 32, -4, 210}, + { 0, 1, 7, 20, 32, -8, 200}, + { 0, 1, 7, 15, 32, -4, 190}, + { 0, 1, 7, 15, 32, -8, 180}, + { 0, 1, 7, 11, 32, -4, 170}, + { 0, 1, 7, 11, 32, -8, 160}, + { 0, 1, 6, 10, 32, -4, 150}, + { 0, 1, 6, 10, 32, -8, 140}, + { 0, 1, 6, 8, 32, -5, 130}, + { 0, 1, 6, 8, 32, -9, 120}, + { 0, 1, 5, 7, 32, -4, 110}, + { 0, 1, 5, 7, 32, -8, 100}, + { 0, 1, 4, 7, 32, -5, 90}, + { 0, 1, 4, 7, 32, -9, 80} +}; + +void rf_pri_query_txgain_table(uint32_t index, uint32_t * rfg_index, uint32_t * dg) { + if (index > 15) index = 15; + *rfg_index = 7 - (index >> 1); + *dg = tx_pwr_table[index][5]; +} + +static int32_t tx_pwr_ch_os[NUM_WIFI_CHANNELS]; // TBD +static int32_t tx_pwr_ch_os_a0[NUM_WIFI_CHANNELS] = { + -16, -13, -10, -8, -5, -2, 0, 2, 5, 7, 9, 11, 14, 18 +}; +static int32_t tx_pwr_ch_os_a1[NUM_WIFI_CHANNELS] = { + // not assigned in the binary, put something here... + // TODO: get some values.. + 13, //2412MHz + 15, //2417MHz + 16, //2422MHz + 18, //2427MHz + 21, //2432MHz + 23, //2437MHz + 0, //2442MHz + 0, //2447MHz + 5, //2452MHz + 7, //2457MHz + 9, //2462MHz + 11, //2467MHz + 14, //2472MHz + 18 //2484MHz +}; + +void rf_pri_update_power_offset(int32_t * power_offset) { + for (int i = 0; i < NUM_WIFI_CHANNELS; i++) { + tx_pwr_ch_os[i] = power_offset[i]; + tx_pwr_ch_os_a1[i] = power_offset[i]; + } +} + +static void rf_pri_set_gain_table_regs() { + // Little-endian? looks okay.. + typedef struct { + uint32_t gain_ctrl_gc_tbb : 5; + uint32_t pad0 : 3; + uint32_t gain_ctrl_gc_tmx : 3; + uint32_t pad1 : 1; + uint32_t gain_ctrl_dac_bias_sel : 2; + uint32_t gain_ctrl_gc_tbb_boost : 2; + } __attribute__((packed)) tbb_gain_t; + union { + tbb_gain_t vals[8]; + uint32_t pack[4]; + } tbb_gain = {.pack = {0}}; + + for (int i = 0, idx = 14; i < 8; i++, idx-=2) { + tbb_gain.vals[i].gain_ctrl_gc_tbb = tx_pwr_table[idx][3]; + tbb_gain.vals[i].gain_ctrl_gc_tmx = tx_pwr_table[idx][2]; + tbb_gain.vals[i].gain_ctrl_dac_bias_sel = tx_pwr_table[idx][1]; + tbb_gain.vals[i].gain_ctrl_gc_tbb_boost = tx_pwr_table[idx][0]; + } + + RF->tbb_gain_index1.value = tbb_gain.pack[0]; + RF->tbb_gain_index2.value = tbb_gain.pack[1]; + RF->tbb_gain_index3.value = tbb_gain.pack[2]; + RF->tbb_gain_index4.value = tbb_gain.pack[3]; +} + +void rf_pri_update_tx_power_offset(uint8_t channel, int8_t * power_offset) { + uint8_t po = power_offset[channel]; + memcpy(tx_pwr_table, tx_pwr_table_origin, sizeof(tx_pwr_table_origin)); + for (int i = 0; i < E_RF_TXPWR_TBL_CNT; i++) { + tx_pwr_table[i][5] = tx_pwr_table[i][5] + po % 4; + tx_pwr_table[i][6] = tx_pwr_table[i][6] + ((int)po / 4) * -10; + } + rf_pri_set_gain_table_regs(); +} + +static uint32_t Tchannels[6] = { + 2412, 2417, 2427, 2442, + 2457, 2472 +}; + +static int32_t Tchannel_os[6] = {2, 3, 3, 4, 6, 8}; +static int32_t Tchannel_os_low[6] = {0, 0, 1, 2, 4, 7}; +static int32_t temps[13] = {-65, -45, -25, -5, 15, 51, + 75, 95, 120, 145, 170, 195, 220}; + +static regs_to_opti opti_regs_data_a0 = { + .vbcore = 10, + .iet = 3, + .vbcore_11n = 10, + .iet_11n = 3, + .vbcore_11g = 10, + .iet_11g = 3, + .vbcore_11b = 10, + .iet_11b = 3, + .lo_fbdv_halfstep_en = 0, + .lo_fbdv_halfstep_en_tx = 0, + .lo_fbdv_halfstep_en_rx = 0, + .clkpll_reset_postdiv = 0, + .clkpll_dither_sel = 0, +}; + +static regs_to_opti opti_regs_data_a1 = { + .vbcore = 0xc, + .iet = 5, + .vbcore_11n = 0xc, + .iet_11n = 5, + .vbcore_11g = 0xc, + .iet_11g = 5, + .vbcore_11b = 0xc, + .iet_11b = 5, + .lo_fbdv_halfstep_en = 1, + .lo_fbdv_halfstep_en_tx = 1, + .lo_fbdv_halfstep_en_rx = 1, + .clkpll_reset_postdiv = 1, + .clkpll_dither_sel = 2, +}; + +regs_to_opti *opti_regs = &opti_regs_data_a1; + +static uint16_t tmxcss[3] = {5,5,5}; + +static int32_t index_os_pre; +static int32_t index_os_pre_mdb; +static int32_t dvga_os_pre; +static int32_t up_dn; + +static void rf_pri_singen_pwrmx_dc(uint32_t amp, uint32_t num_data, int32_t adc_mean_max, int32_t adc_mean_min){ + uint32_t step; + int32_t adc_mean_i = 0; + step = amp >> 1; + while(1) { + rf_pri_singen_amplitude(amp, amp); + rf_pri_singen_start(); + rf_pri_start_txdfe(); + + BL602_Delay_US(10); + adc_mean_i = rf_pri_pm_pwr_avg(1, num_data); + adc_mean_i = adc_mean_i>>10; + printf("amp=%ld,step=%ld,adc_mean_i=%ld\r\n", amp, step, adc_mean_i); + + if(adc_mean_i > adc_mean_max) + amp -= step; + else if (adc_mean_i < adc_mean_min) + amp += step; + else + break; + if(step > 0) + step = step >> 1; + else + break; + } +} + +// TODO: verify me +static void rf_pri_txcal_config(uint32_t param_ind, int32_t val) { + switch (param_ind) { + case E_RF_GAIN: { + PACK(RF->dfe_ctrl_0, dfe) { + dfe.tx_iqc_gain = val; + dfe.tx_iqc_gain_en = 1; + } + break; + } + case E_RF_PHASE: { + val = val >= 0 ? val : (val+0x400); + PACK(RF->dfe_ctrl_0, dfe) { + dfe.tx_iqc_phase = val; + dfe.tx_iqc_phase_en = 1; + } + break; + } + case E_RF_BRANCH_I: { + RF->tbb.tbb_tosdac_i = val; + break; + } + case E_RF_BRANCH_Q: { + RF->tbb.tbb_tosdac_i = val; + break; + } + default: + break; + } +} + +// kinda like Gradient descent to find minimum point? +// todo: verify me +static int32_t rf_pri_txcal_search_core(uint32_t param_ind, uint32_t center, uint32_t delta, uint32_t meas_freq) { + rf_pri_txcal_config(param_ind, center); + BL602_Delay_US(10); + + RF->dfe_ctrl_6.rx_pm_freqshift_cw = meas_freq << 10; + + uint32_t y_center = rf_pri_pm_pwr(); + + int32_t x_center = center; + int32_t x_delta = delta; + + for (int32_t x_left, x_right, y_left, y_right; x_delta; x_delta >>= 1) { + x_left = x_center - x_delta; + x_right = x_center + x_delta; + switch (param_ind) { + case E_RF_BRANCH_I ... E_RF_BRANCH_Q: + x_left = x_left < 0 ? 0 : x_left; + x_right = x_right > 63 ? 63 : x_right; + break; + case E_RF_GAIN: + x_left = x_left < 0 ? 0 : x_left; + x_right = x_right > 2047 ? 2047 : x_right; + break; + case E_RF_PHASE: + x_left = x_left < -512 ? -512 : x_left; + x_right = x_right > 511 ? 511 : x_right; + break; + } + + // left + rf_pri_txcal_config(param_ind, x_left); + BL602_Delay_US(10); + y_left = rf_pri_pm_pwr(); + + if (y_center <= y_left) { + // right + + rf_pri_txcal_config(param_ind, x_right); + BL602_Delay_US(10); + y_right = rf_pri_pm_pwr(); + + if (y_center > y_right) { + x_center = x_right; + y_center = y_right; + } + } else { + x_center = x_left; + y_center = y_left; + } + } + + return x_center; +} + +static void rf_pri_txcal_config_hw() { + typedef struct { + uint32_t tbb_tosdac_i_gc0 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t tbb_tosdac_q_gc0 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + } __attribute__((packed)) tosdac_t; + union { + tosdac_t vals[8]; + uint32_t pack[4]; + } tosdac = {.pack = {0}}; + for (int i = 0; i < 8; i++) { + tosdac.vals[i].tbb_tosdac_i_gc0 = rf_calib_data->txcal[i].tosdac_i; + tosdac.vals[i].tbb_tosdac_q_gc0 = rf_calib_data->txcal[i].tosdac_q; + } + RF->tosdac_ctrl_hw1.value = tosdac.pack[0]; + RF->tosdac_ctrl_hw2.value = tosdac.pack[1]; + RF->tosdac_ctrl_hw3.value = tosdac.pack[2]; + RF->tosdac_ctrl_hw4.value = tosdac.pack[3]; + + __typeof__ (RF->tx_iq_gain_hw0) iq_gain[8]; + + for (int i = 0; i < 8; i++) { + iq_gain[i].tx_iq_gain_comp_gc0 = rf_calib_data->txcal[i].tx_iq_gain_comp; + iq_gain[i].tx_iq_phase_comp_gc0 = rf_calib_data->txcal[i].tx_iq_phase_comp; + } + + RF->tx_iq_gain_hw0.value = iq_gain[0].value; + RF->tx_iq_gain_hw1.value = iq_gain[1].value; + RF->tx_iq_gain_hw2.value = iq_gain[2].value; + RF->tx_iq_gain_hw3.value = iq_gain[3].value; + RF->tx_iq_gain_hw4.value = iq_gain[4].value; + RF->tx_iq_gain_hw5.value = iq_gain[5].value; + RF->tx_iq_gain_hw6.value = iq_gain[6].value; + RF->tx_iq_gain_hw7.value = iq_gain[7].value; +} + +void rf_pri_txcal(void) { + // + PACK(RF->rfcal_status, rfcal_status) { + rfcal_status.lo_leakcal_status = 1; + rfcal_status.tiqcal_status_resv = 1; + } + // + rf_pri_save_state_for_cal(); + rf_pri_config_mode(E_RF_MODE_TXCAL); + rf_pri_config_channel(E_RF_CHANNEL_2424M); // E_RF_CHANNEL_2440M in the leak code + + // + PACK(RF->rfcal_ctrlen, rfcal_ctrlen) { + rfcal_ctrlen.tiqcal_en = 1; + rfcal_ctrlen.lo_leakcal_en = 1; + } + // + RF->rbb3.pwr_det_en = 1; + + RF->pa1.pa_pwrmx_dac_pn_switch = 1; + + RF->tmx.tmx_cs = tmxcss[0]; // leak code use 3 + + uint32_t k1 = 61; + rf_pri_singen_config(k1, 0x0, 0x300); + + for (int i = 0; i < 8; i++) { + // + PACK(RF->pa1, pa1) { + pa1.pa_att_gc = txcal_para[i][0]; + pa1.pa_pwrmx_osdac = txcal_para[i][2]; + } + // + RF->ten_ac.atest_gain_r5 = txcal_para[i][1]; + + // + rf_pri_config_txgain(tx_pwr_table[i<<1][0], 7, tx_pwr_table[i<<1][3]); + // + + BL602_Delay_US(10); + + int32_t adc_mean_min=192; + int32_t adc_mean_max=320; + uint32_t num_data=1024; + rf_pri_singen_pwrmx_dc(txcal_para[i][3],num_data,adc_mean_max,adc_mean_min); + + rf_pri_pm_pwr_avg(1, 0x1000); + + uint32_t tos_i = rf_pri_txcal_search_core(E_RF_BRANCH_I, 32, 16, k1); + rf_pri_txcal_config(E_RF_BRANCH_I, tos_i); + + uint32_t tos_q = rf_pri_txcal_search_core(E_RF_BRANCH_Q, 32, 16, k1); + rf_pri_txcal_config(E_RF_BRANCH_Q, tos_q); + + tos_i = rf_pri_txcal_search_core(E_RF_BRANCH_I, tos_i, 2, k1); + rf_pri_txcal_config(E_RF_BRANCH_I, tos_i); + + uint32_t gain = rf_pri_txcal_search_core(E_RF_GAIN, 0x400, 0x80, 2 * k1); + rf_pri_txcal_config(E_RF_GAIN, gain); + + uint32_t phase = rf_pri_txcal_search_core(E_RF_PHASE, 0, 0x40, 2 * k1); + rf_pri_txcal_config(E_RF_PHASE, phase); + + gain = rf_pri_txcal_search_core(E_RF_GAIN, gain, 0x40, 2 * k1); + rf_pri_txcal_config(E_RF_GAIN, gain); + + phase = rf_pri_txcal_search_core(E_RF_PHASE, 0, 0x20, 2 * k1); + rf_pri_txcal_config(E_RF_PHASE, phase); + + rf_calib_data->txcal[E_RF_TXCAL_GAIN_CNT - 1 - i].tosdac_i = tos_i; + rf_calib_data->txcal[E_RF_TXCAL_GAIN_CNT - 1 - i].tosdac_q = tos_q; + rf_calib_data->txcal[E_RF_TXCAL_GAIN_CNT - 1 - i].tx_iq_gain_comp = gain; + rf_calib_data->txcal[E_RF_TXCAL_GAIN_CNT - 1 - i].tx_iq_phase_comp = phase; + + printf("tosdac_i=%ld,tosdac_q=%ld,tx_iq_gain_comp=%ld,tx_iq_phase_comp=%ld\r\n", + tos_i, tos_q, gain, phase); + } + + rf_pri_txcal_config_hw(); + PACK(RF->rfcal_ctrlen, rfcal_ctrlen) { + rfcal_ctrlen.lo_leakcal_en = 0; + rfcal_ctrlen.tiqcal_en = 0; + } + rf_pri_restore_state_for_cal(); + + PACK(RF->rfcal_status, rfcal_status) { + rfcal_status.lo_leakcal_status = 0x3; + rfcal_status.tiqcal_status_resv = 0x3; + } + + PACK(RF->tbb, tbb) { + tbb.tbb_tosdac_i = rf_calib_data->txcal[3].tosdac_i; + tbb.tbb_tosdac_q = rf_calib_data->txcal[3].tosdac_q; + } + + PACK(RF->dfe_ctrl_0, dfe_ctrl_0) { + dfe_ctrl_0.tx_iqc_gain = rf_calib_data->txcal[3].tx_iq_gain_comp; + dfe_ctrl_0.tx_iqc_phase = rf_calib_data->txcal[3].tx_iq_phase_comp; + } +} + + +void rf_pri_update_param(uint32_t chanfreq_MHz) { + uint32_t low_chan = 7; + int32_t i4 = 8; + + index_os_pre = 0; + index_os_pre_mdb = 0; + dvga_os_pre = 0; + up_dn = 0; + + for (int i = 1; i < 6; i++) { + if (chanfreq_MHz < Tchannels[i]) { + low_chan = i - 1; + break; + } + } + + if (low_chan != 7) { + uint32_t low_chanfreq_Mhz = Tchannels[low_chan]; + int freq_diff = chanfreq_MHz - low_chanfreq_Mhz; + int high_ch = low_chan + 1; + i4 = (uint32_t)((Tchannel_os[high_ch] - Tchannel_os[low_chan]) + * freq_diff) / (Tchannels[high_ch] - low_chanfreq_Mhz) + + Tchannel_os[low_chan]; + + low_chan = (uint32_t)((Tchannel_os_low[high_ch] - Tchannel_os_low[low_chan]) * freq_diff) / + (Tchannels[high_ch] - low_chanfreq_Mhz) + Tchannel_os_low[low_chan]; + } + + int d = 0; + for (int i = 10, j = 4; i != -10; i -=5, j -= 1) { + int i2 = (temps[j] + d) - (20 - low_chan); + d = 0; + if (i2 > i) { + d = i2 - i; + i2 = i; + } + temps[j - 1] = i2; + } + + d = 0; + for (int i = 56, j = 5; i != 91; i += 5, j++) { + int i8 = (temps[j] - d) + (20 - i4); + if (i8 > 95) { + i8 = i8 + (5 - i4 / 4); + } + d = 0; + if (i8 < i) { + d = i - i8; + i8 = i; + } + temps[j + 1] = i8; + } + + temps[4] = 15; + temps[5] = 51; + + // the leak code use tmx_csl/tmx_csh from rf_calib_data + if (chanfreq_MHz < 2438) { + RF->tmx.tmx_cs = tmxcss[1]; + } else { + RF->tmx.tmx_cs = tmxcss[2]; + } + + switch(chanfreq_MHz){ + case 2412: + tx_pwr_os = tx_pwr_ch_os[0]; + break; + case 2417: + tx_pwr_os = tx_pwr_ch_os[1]; + break; + case 2422: + tx_pwr_os = tx_pwr_ch_os[2]; + break; + case 2427: + tx_pwr_os = tx_pwr_ch_os[3]; + break; + case 2432: + tx_pwr_os = tx_pwr_ch_os[4]; + break; + case 2437: + tx_pwr_os = tx_pwr_ch_os[5]; + break; + case 2442: + tx_pwr_os = tx_pwr_ch_os[6]; + break; + case 2447: + tx_pwr_os = tx_pwr_ch_os[7]; + break; + case 2452: + tx_pwr_os = tx_pwr_ch_os[8]; + break; + case 2457: + tx_pwr_os = tx_pwr_ch_os[9]; + break; + case 2462: + tx_pwr_os = tx_pwr_ch_os[10]; + break; + case 2467: + tx_pwr_os = tx_pwr_ch_os[11]; + break; + case 2472: + tx_pwr_os = tx_pwr_ch_os[12]; + break; + case 2484: + tx_pwr_os = tx_pwr_ch_os[13]; + break; + default: + tx_pwr_os = 0; + break; + } + +} + +static int32_t Tthr; + +static int8_t temps_dvga[16] = { + -4, -8, -4, -8, + -4, -8, -4, -8, + -4, -8, -5, -9, + -4, -8, -5, -9, +}; + +void rf_pri_update_dvga_os(int8_t dvga_os) { + for (int i = 0; i < 16; i++) { + temps_dvga[i] = tx_pwr_table[i][5] + dvga_os; + } +} + +// TODO: re-verify this function +void rf_pri_tx_gain_comp(int32_t Tsens) { + + if (((up_dn == 1) && ((Tthr <= Tsens) || (Tsens <= Tthr + -5))) + || ((((up_dn != -1 && up_dn != 1) || (Tsens <= Tthr)) || (Tthr + 5 <= Tsens)))) { + uint32_t dvga_os = 0; + int i; + for (i = 12; i >= 0; i--) { + if (temps[i] <= Tsens) + break; + } + if (i == -1) i = 0; + int32_t index_os = i - 4; + int32_t T = temps[i]; + Tthr = T; + if (Tsens < 35) { + if (T < Tsens) { + Tthr = temps[i + 1]; + if (34 < temps[i + 1]) { + Tthr = T; + } + } else { + index_os = i - 5; + } + } else { + if (T < 36) { + Tthr = temps[i + 1]; + } + } + + if (index_os_pre_mdb < index_os) { + up_dn = 1; + } else { + if (index_os_pre_mdb > index_os) + up_dn = -1; + } + if (index_os < 1) { + dvga_os = 0; + index_os_pre = index_os; + if (index_os != 0) { + dvga_os = -1; + if ((index_os & 1) != 0) { + dvga_os = 1; + } + index_os_pre = (index_os - 1) / 2; + } + } else { + dvga_os = (index_os + 1) & 1; + if (dvga_os == 0) { + dvga_os = -1; + } + index_os_pre = (index_os + 1) / 2; + } + tx_pwr_os_temperature = index_os_pre * -10; + dvga_os_pre = dvga_os; + index_os_pre_mdb = index_os; + } else { + tx_pwr_os_temperature = index_os_pre * -10; + } + + rf_pri_update_dvga_os(dvga_os_pre); + rfc_apply_tx_dvga(temps_dvga); +} + + +void rf_pri_update_txgain_tempos(int16_t tempos) { + tx_pwr_os_temperature = tempos; +} + +int32_t rf_pri_get_txgain_max(void) { + return tx_pwr_table[0][6] + tx_pwr_os + tx_pwr_os_temperature; +} + +int32_t rf_pri_get_txgain_min(void) { + return tx_pwr_table[15][6] + tx_pwr_os + tx_pwr_os_temperature; +} + +uint32_t rf_pri_get_txgain_index(int32_t pwr, uint32_t mode) { + pwr += tx_pwr_os; + if (mode == E_RF_MODE_11B) { + pwr -= 33; + } + for (int i = 0; i < E_RF_TXPWR_TBL_CNT; i++) { + if (pwr >= tx_pwr_table[i][6]) { + return i; + } + } + return E_RF_TXPWR_TBL_CNT - 1; +} + + +static void rf_pri_chipv(uint8_t chipv) { + #define cpy_rev(dest, rev) memcpy(dest, dest##_a##rev, sizeof(dest##_a##rev)); + // init based on chip revision + if (chipv == 0) { + tmxcss[0] = 3; + tmxcss[1] = 6; + tmxcss[2] = 6; + cpy_rev(tx_pwr_table, 0); + memcpy(tx_pwr_table_origin, tx_pwr_table_a0, sizeof(tx_pwr_table_a0)); + cpy_rev(tx_pwr_ch_os, 0); + cpy_rev(txcal_para, 0); + opti_regs = &opti_regs_data_a0; + } + if (chipv == 1) { + tmxcss[0] = 5; + tmxcss[1] = 5; + tmxcss[2] = 5; + cpy_rev(tx_pwr_table, 1); + memcpy(tx_pwr_table_origin, tx_pwr_table_a1, sizeof(tx_pwr_table_a1)); + cpy_rev(tx_pwr_ch_os, 1); + cpy_rev(txcal_para, 1); + opti_regs = &opti_regs_data_a1; + } +} + +static int32_t init_fast = 0; + +static void rf_pri_fixed_val_regs(){ + AON->dcdc18_top_0.dcdc18_vpfm_aon = 3; + HBN->HBN_GLB.sw_ldo11_rt_vout_sel = 8; + PACK(RF->pucr1, pucr1) { + pucr1.pu_sfreg = 1; + pucr1.pu_adda_ldo = 1; + } + AON->xtal_cfg.xtal_capcode_extra_aon = 1; + // leak code also set xtal_capcode_out_aon and xtal_capcode_in_aon + + if (!init_fast) { + BL602_Delay_MS(10); + } + + PACK(RF->pa1, pa1) { + pa1.pa_iaq = 2; + pa1.pa_iet = opti_regs->iet; + pa1.pa_vbcore = opti_regs->vbcore; + pa1.pa_vbcas = 4; + } + PACK(RF->pa_reg_ctrl_hw1, pa_reg_ctrl_hw1) { + pa_reg_ctrl_hw1.pa_iet_11n = opti_regs->iet_11n; + pa_reg_ctrl_hw1.pa_vbcas_11n = 4; + pa_reg_ctrl_hw1.pa_vbcore_11n = opti_regs->vbcore_11n; + } + PACK(RF->pa_reg_ctrl_hw2, pa_reg_ctrl_hw2) { + pa_reg_ctrl_hw2.pa_iet_11g = opti_regs->iet_11g; + pa_reg_ctrl_hw2.pa_vbcore_11g = opti_regs->vbcore_11g; + pa_reg_ctrl_hw2.pa_vbcas_11g = 4; + + pa_reg_ctrl_hw2.pa_iet_11b = opti_regs->iet_11b; + pa_reg_ctrl_hw2.pa_vbcore_11b = opti_regs->vbcore_11b; + pa_reg_ctrl_hw2.pa_vbcas_11b = 4; + } + + RF->adda2.adc_gt_rm = 1; + + RF->fbdv.lo_fbdv_halfstep_en = opti_regs->lo_fbdv_halfstep_en; + + PACK(RF->lo_reg_ctrl_hw1, lo_reg_ctrl_hw1) { + lo_reg_ctrl_hw1.lo_fbdv_halfstep_en_tx = opti_regs->lo_fbdv_halfstep_en_tx; + lo_reg_ctrl_hw1.lo_fbdv_halfstep_en_rx = opti_regs->lo_fbdv_halfstep_en_rx; + // the disassembly uses lo_fbdv_halfstep_en_tx for both, and + // in chipv it also uses lo_fbdv_halfstep_en_tx for both, + // I think it's typo + } + + PACK(RF->lo_reg_ctrl_hw1, lo_reg_ctrl_hw1) { + lo_reg_ctrl_hw1.lo_lf_rz_tx = 0; + lo_reg_ctrl_hw1.lo_lf_cz_tx = 3; + lo_reg_ctrl_hw1.lo_cp_sel_tx = 0; + } + + PACK(RF->pa_reg_wifi_ctrl_hw, pa_reg_wifi_ctrl_hw) { + pa_reg_wifi_ctrl_hw.pa_half_on_wifi = 0; + pa_reg_wifi_ctrl_hw.pa_ib_fix_wifi = 0; + } +} + +static void rf_pri_restore_cal_reg(void) { + PACK(RF->rosdac_ctrl_hw1, rosdac) { + rosdac.rosdac_i_gc0 = rf_calib_data->rxcal[0].rosdac_i; + rosdac.rosdac_q_gc0 = rf_calib_data->rxcal[0].rosdac_q; + rosdac.rosdac_i_gc1 = rf_calib_data->rxcal[1].rosdac_i; + rosdac.rosdac_q_gc1 = rf_calib_data->rxcal[1].rosdac_q; + } + PACK(RF->rosdac_ctrl_hw2, rosdac) { + rosdac.rosdac_i_gc2 = rf_calib_data->rxcal[2].rosdac_i; + rosdac.rosdac_q_gc2 = rf_calib_data->rxcal[2].rosdac_q; + rosdac.rosdac_i_gc3 = rf_calib_data->rxcal[3].rosdac_i; + rosdac.rosdac_q_gc3 = rf_calib_data->rxcal[3].rosdac_q; + } + PACK(RF->rbb2, rbb2) { + rbb2.rbb_cap1_fc_i = rf_calib_data->cal.rbb_cap1_fc_i; + rbb2.rbb_cap1_fc_q = rf_calib_data->cal.rbb_cap1_fc_q; + rbb2.rbb_cap2_fc_i = rf_calib_data->cal.rbb_cap2_fc_i; + rbb2.rbb_cap2_fc_q = rf_calib_data->cal.rbb_cap2_fc_q; + } + + PACK(RF->tbb, tbb) { + tbb.tbb_tosdac_i = rf_calib_data->txcal[3].tosdac_i; + tbb.tbb_tosdac_q = rf_calib_data->txcal[3].tosdac_q; + } + + PACK(RF->dfe_ctrl_0, dfe_ctrl_0) { + dfe_ctrl_0.tx_iqc_gain = rf_calib_data->txcal[3].tx_iq_gain_comp; + dfe_ctrl_0.tx_iqc_phase = rf_calib_data->txcal[3].tx_iq_phase_comp; + } +} + +void rf_pri_init(uint8_t reset, uint8_t chipv) { + rf_pri_chipv(chipv); + init_fast = reset == 0; + + rf_pri_fixed_val_regs(); + + PDS->pu_rst_clkpll.clkpll_reset_postdiv = opti_regs->clkpll_reset_postdiv; + PDS->clkpll_sdm.clkpll_dither_sel = opti_regs->clkpll_dither_sel; + RF->adda1.dac_dvdd_sel = 2; + HBN->HBN_GLB.sw_ldo11soc_vout_sel_aon = 0xc; + + rf_pri_set_gain_table_regs(); + + PDS->clkpll_top_ctrl.clkpll_refclk_sel = 1; + PACK(PDS->clkpll_output_en, clkpll_output_en) { + clkpll_output_en.clkpll_en_480m = 1; + clkpll_output_en.clkpll_en_240m = 1; + clkpll_output_en.clkpll_en_192m = 1; + clkpll_output_en.clkpll_en_160m = 1; + clkpll_output_en.clkpll_en_120m = 1; + clkpll_output_en.clkpll_en_96m = 1; + clkpll_output_en.clkpll_en_80m = 1; + clkpll_output_en.clkpll_en_48m = 1; + } + + if (rf_calib_data->inited && !reset) { + rf_pri_restore_cal_reg(); + } else { + rf_pri_full_cal(); + rf_calib_data->inited = 1; + } +} + +void rf_pri_init_fast(uint32_t flag) { + init_fast = flag; +} + +/// data for different crystal freq +static uint32_t channel_div_table_24M[21] = { + 0x21638e39, 0x2171c71c, 0x21800000, 0x218e38e4, 0x219c71c7, + 0x21aaaaab, 0x21b8e38e, 0x21c71c72, 0x21d55555, 0x21e38e39, + 0x21f1c71c, 0x22000000, 0x220e38e4, 0x221c71c7, 0x222aaaab, + 0x2238e38e, 0x22471c72, 0x22555555, 0x22638e39, 0x2271c71c, + 0x22800000 +}; +static uint16_t channel_cnt_table_24M[21] = { + 0xa6f2, 0xa739, 0xa780, 0xa7c7, 0xa80e, 0xa855, 0xa89c, 0xa8e4, + 0xa92b, 0xa972, 0xa9b9, 0xaa00, 0xaa47, 0xaa8e, 0xaad5, 0xab1c, + 0xab64, 0xabab, 0xabf2, 0xac39, 0xac80 +}; +static uint16_t channel_cnt_range_24M[21] = { + 0xa6a7, 0xa6e7, 0xace7 +}; +static int32_t rx_notch_para_24M[14][2] = { + {0, 0}, {1, 7000000}, {1, 2000000}, {1, -3000000}, {1, -8000000}, {0, 0}, + {1, 6000000}, {1, 1000000}, {1, -4000000}, {1, -9000000}, {0, 0}, {1, 5000000}, + {1, 0}, {0, 0} +}; +static uint16_t fcal_div_24M = 1280; + +static uint32_t channel_div_table_26M[21] = { + 0x1ed20d21, 0x1edf2df3, 0x1eec4ec5, 0x1ef96f97, 0x1f069069, + 0x1f13b13b, 0x1f20d20d, 0x1f2df2df, 0x1f3b13b1, 0x1f483483, + 0x1f555555, 0x1f627627, 0x1f6f96f9, 0x1f7cb7cb, 0x1f89d89e, + 0x1f96f970, 0x1fa41a42, 0x1fb13b14, 0x1fbe5be6, 0x1fcb7cb8, + 0x1fd89d8a +}; +static uint16_t channel_cnt_table_26M[21] = { + 0xa6fc, 0xa743, 0xa78a, 0xa7d1, 0xa819, 0xa860, 0xa8a7, 0xa8ee, + 0xa935, 0xa97c, 0xa9c3, 0xaa0a, 0xaa52, 0xaa99, 0xaae0, 0xab27, + 0xab6e, 0xabb5, 0xabfc, 0xac43, 0xac8b +}; +static uint16_t channel_cnt_range_26M[21] = { + 0xa6b1, 0xa6f1, 0xacf2 +}; +static int32_t rx_notch_para_26M[14][2] = { + {1, 6000000}, {1, 1000000}, {1, -4000000}, {1, -9000000}, {0, 0}, {1, 7000000}, + {1, 2000000}, {1, -3000000}, {1, -8000000}, {0, 0}, {1, 8000000}, {1, 3000000}, + {1, -2000000}, {0, 0} +}; +static uint16_t fcal_div_26M = 1387; + +static uint32_t channel_div_table_32M[21] = { + 0x190aaaab, 0x19155555, 0x19200000, 0x192aaaab, 0x19355555, + 0x19400000, 0x194aaaab, 0x19555555, 0x19600000, 0x196aaaab, + 0x19755555, 0x19800000, 0x198aaaab, 0x19955555, 0x19a00000, + 0x19aaaaab, 0x19b55555, 0x19c00000, 0x19caaaab, 0x19d55555, + 0x19e00000 +}; +static uint16_t channel_cnt_table_32M[21] = { + 0xa6fa, 0xa741, 0xa788, 0xa7d0, 0xa817, 0xa85e, 0xa8a5, 0xa8ec, + 0xa933, 0xa97a, 0xa9c1, 0xaa09, 0xaa50, 0xaa97, 0xaade, 0xab25, + 0xab6c, 0xabb3, 0xabfa, 0xac42, 0xac89 +}; +static uint16_t channel_cnt_range_32M[21] = { + 0xa6af, 0xa6ef, 0xacf0 +}; +static int32_t rx_notch_para_32M[14][2] = { + {0, 0}, {0, 0}, {1, 10000000}, {1, 5000000}, {1, 0}, {1, -5000000}, + {1, -10000000}, {0, 0}, {0, 0}, {1, 7000000}, {1, 2000000}, {1, -3000000}, + {1, -8000000}, {0, 0} +}; +static uint16_t fcal_div_32M = 1707; + +static uint32_t channel_div_table_38M4[21] = { + 0x14de38e4, 0x14e71c72, 0x14f00000, 0x14f8e38e, 0x1501c71c, + 0x150aaaab, 0x15138e39, 0x151c71c7, 0x15255555, 0x152e38e4, + 0x15371c72, 0x15400000, 0x1548e38e, 0x1551c71c, 0x155aaaab, + 0x15638e39, 0x156c71c7, 0x15755555, 0x157e38e4, 0x15871c72, + 0x15900000 +}; +static uint16_t channel_cnt_table_38M4[21] = { + 0xa6f2, 0xa739, 0xa780, 0xa7c7, 0xa80e, 0xa855, 0xa89c, 0xa8e4, + 0xa92b, 0xa972, 0xa9b9, 0xaa00, 0xaa47, 0xaa8e, 0xaad5, 0xab1c, + 0xab64, 0xabab, 0xabf2, 0xac39, 0xac80 +}; +static uint16_t channel_cnt_range_38M4[21] = { + 0xa6a7, 0xa6e7, 0xace7 +}; +static int32_t rx_notch_para_38M4[14][2] = { + {1, 7200000}, {1, 2200000}, {1, -2800000}, {1, -7800000}, {0, 0}, {0, 0}, + {0, 0}, {0, 0}, {1, 5600000}, {1, 600000}, {1, -4400000}, {1, -9400000}, + {0, 0}, {0, 0} +}; +static uint16_t fcal_div_38M4 = 2048; + +static uint32_t channel_div_table_40M[21] = { + 0x14088889, 0x14111111, 0x1419999a, 0x14222222, 0x142aaaab, + 0x14333333, 0x143bbbbc, 0x14444444, 0x144ccccd, 0x14555555, + 0x145dddde, 0x14666666, 0x146eeeef, 0x14777777, 0x14800000, + 0x14888889, 0x14911111, 0x1499999a, 0x14a22222, 0x14aaaaab, + 0x14b33333 +}; +static uint16_t channel_cnt_table_40M[21] = { + 0xa6eb, 0xa732, 0xa779, 0xa7c0, 0xa808, 0xa84f, + 0xa896, 0xa8dd, 0xa924, 0xa96b, 0xa9b2, 0xa9f9, + 0xaa40, 0xaa87, 0xaacf, 0xab16, 0xab5d, 0xaba4, + 0xabeb, 0xac32, 0xac79 +}; +static uint16_t channel_cnt_range_40M[21] = { + 0xa6a0, 0xa6e0, 0xace0 +}; +static int32_t rx_notch_para_40M[14][2] = { + {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 8000000}, {1, 3000000}, + {1, -2000000}, {1, -7000000}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, + {1, 8000000}, {1, -4000000} +}; +static uint16_t fcal_div_40M = 2133; + +static uint32_t channel_div_table_52M[21] = { + 0xf690690, 0xf6f96f9, 0xf762762, 0xf7cb7cb, 0xf834835, + 0xf89d89e, 0xf906907, 0xf96f970, 0xf9d89d9, 0xfa41a42, + 0xfaaaaab, 0xfb13b14, 0xfb7cb7d, 0xfbe5be6, 0xfc4ec4f, + 0xfcb7cb8, 0xfd20d21, 0xfd89d8a, 0xfdf2df3, 0xfe5be5c, + 0xfec4ec5 +}; +static uint16_t channel_cnt_table_52M[21] = { + 0xa6ed, 0xa734, 0xa77b, 0xa7c2, 0xa809, 0xa850, + 0xa897, 0xa8de, 0xa925, 0xa96d, 0xa9b4, 0xa9fb, + 0xaa42, 0xaa89, 0xaad0, 0xab17, 0xab5e, 0xaba5, + 0xabec, 0xac34, 0xac7b +}; +static uint16_t channel_cnt_range_52M[21] = { + 0xa6a2, 0xa6e2, 0xace2 +}; +static int32_t rx_notch_para_52M[14][2] = { + {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 7000000}, + {1, 2000000}, {1, -3000000}, {1, -8000000}, {0, 0}, {0, 0}, {0, 0}, + {0, 0}, {0, 0} +}; +static uint16_t fcal_div_52M = 2773; + +void rf_pri_xtalfreq(uint32_t xtalfreq) { + switch (xtalfreq) { + case E_RF_XTAL_24M: + memcpy(channel_div_table, channel_div_table_24M, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_24M, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_24M, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_24M, sizeof(rx_notch_para)); + fcal_div = fcal_div_24M; + break; + case E_RF_XTAL_26M: + memcpy(channel_div_table, channel_div_table_26M, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_26M, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_26M, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_26M, sizeof(rx_notch_para)); + fcal_div = fcal_div_26M; + break; + case E_RF_XTAL_32M: + memcpy(channel_div_table, channel_div_table_32M, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_32M, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_32M, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_32M, sizeof(rx_notch_para)); + fcal_div = fcal_div_32M; + break; + case E_RF_XTAL_38M4: + default: + memcpy(channel_div_table, channel_div_table_38M4, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_38M4, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_38M4, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_38M4, sizeof(rx_notch_para)); + fcal_div = fcal_div_38M4; + break; + case E_RF_XTAL_40M: + memcpy(channel_div_table, channel_div_table_40M, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_40M, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_40M, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_40M, sizeof(rx_notch_para)); + fcal_div = fcal_div_40M; + break; + case E_RF_XTAL_52M: + memcpy(channel_div_table, channel_div_table_52M, sizeof(channel_div_table)); + memcpy(channel_cnt_table, channel_cnt_table_52M, sizeof(channel_cnt_table)); + memcpy(channel_cnt_range, channel_cnt_range_52M, sizeof(channel_cnt_range)); + memcpy(rx_notch_para, rx_notch_para_52M, sizeof(rx_notch_para)); + fcal_div = fcal_div_52M; + break; + } +} diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_adapt.c b/src/bl602_wifi/driver/phy/phy_rf/phy_adapt.c new file mode 100644 index 0000000..8f8a888 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_adapt.c @@ -0,0 +1,175 @@ +#include +#include +#include +#include + +static pa_state_t pa_env[4]; // :136:19 + +void pa_adapt(uint8_t id) { + static uint32_t count = 0; + count++; + if (id > 3) { + return ; + } + int next_ptr = pa_env[id].input_buffer_ptr; + int ptr = (next_ptr - 1 + 8) % 8; // (next_ptr - 1) & 7 + if (pa_env[id].input_buffer[ptr].new) { + int rssi = pa_env[id].input_buffer[ptr].rssi; + if (pa_env[id].rss_state == 0) { + if (pa_env[id].rss_count < 7) { + pa_env[id].rss_count ++; + } else { + pa_env[id].rss_state = 1; + int sum_rssi = 0; + int min_rssi = 100; + int max_rssi = -100; + for (int i = 1; i < 7; i++) { + int _rssi = (int)pa_env[id].input_buffer[(next_ptr - i) % 8].rssi; + sum_rssi = _rssi; + if (_rssi > max_rssi) { + max_rssi = _rssi; + } + if (_rssi < min_rssi) { + min_rssi = _rssi; + } + } + pa_env[id].rss = (sum_rssi - min_rssi - max_rssi) / 4; + } + } else { + if (pa_env[id].rss_hit_count < 5) { + if (rssi + 100 < 101) { + char rss = pa_env[id].rss; + int diff = rssi - rss; + if (diff + 10 < 21) { + pa_env[id].rss_hit_count = 0; + pa_env[id].rss = (char)(diff >> 2) + rss; + } else { + pa_env[id].rss_hit_count ++; + } + } + } else { + pa_env[id].rss_hit_count = 0; + pa_env[id].rss_state = 0; + pa_env[id].rss_count = 0; + } + } + + if ((count & 0xf) == 0xf) { + float ppm; + if ((rssi - pa_env[id].rss) + 10U < 0x15) { + ppm = pa_env[id].input_buffer[ptr].ppm; + if (ABS(ppm) < 2.0) { + double d_ppm = (double)ppm; + double a = 0; + double d_ce = ((double)pa_env[id].ce); + if (rssi < -0x55) { + d_ppm = d_ce * (double)0.03125; + // 0x3fa00000 00000000 + } else { + d_ppm = d_ce * (double)0.125; + // 0x3fc00000 00000000 + } + d_ppm += d_ce; + ppm = (float) d_ppm; + pa_env[id].ce = ppm; + } + } + ppm = pa_env[id].ce; + if (ABS(ppm) > 5) { + if (ppm > 0) { + int cap = hal_get_capcode(); + if (cap != 0) { + hal_set_capcode(hal_get_capcode() - 1); + } + } + if (ppm < 0) { + int cap = hal_get_capcode(); + if (cap < 0x3f) { + hal_set_capcode(hal_get_capcode() + 1); + } + } + pa_env[id].ce = 0.0; + } + } + } +} + +void pa_init(void) { + for (int i = 0; i < 3; i++) { + pa_env[i].rss_state = 0; + pa_env[i].rss_count = 0; + pa_env[i].rss_state = 0; + pa_env[i].rss_count = 0; + pa_env[i].last_update = 0; + pa_env[i].input_buffer_ptr = 0; + pa_env[i].ce_state = 0; + pa_env[i].ce = 0.0; + pa_env[i].ce_num_up_cmds = 0; + pa_env[i].ce_num_dn_cmds = 0; + for (int j = 0; j < 8; j++) { + pa_env[i].input_buffer[j].lna = 0; + pa_env[i].input_buffer[j].new = 0; + pa_env[i].input_buffer[j].ppm = 0; + pa_env[i].input_buffer[j].rssi = 0; + } + } +} + + +float calc_ppm_dsss(uint8_t rxv_freqoff) { + return ((double)((int8_t)rxv_freqoff)) * 0.7; +} + +float calc_ppm_ofdm(uint16_t rxv_freqoff) { + return (((double)(-(int)rxv_freqoff)) * 20.0) / 2440.0; +} + +float calc_ppm(rvec_t * rvec) { + if ((rvec->format_mod) == 0 && (rvec->leg_rate < 4)) { + return calc_ppm_dsss(rvec->freqoff_lo); + } else { + return calc_ppm_ofdm(rvec->freqoff); + } +} + + +void pa_input(uint8_t id, struct rx_hd *rhd) { + if (id < 4) { + int ptr = pa_env[id].input_buffer_ptr; + rvec_t *rvec = (rvec_t *)&(rhd->recvec1a); + input_t *buffer = &(pa_env[id].input_buffer[ptr]); + pa_env[id].last_update = rhd->tsflo; + buffer->new = 1; + //pa_env[id].input_buffer[id].rssi = *(int8_t *)((int)&rhd->recvec1c + 3); + buffer->rssi = rvec->rssi1; + //pa_env[id].input_buffer[id].lna = (char)((int)(rhd->recvec1d << 20) >> 28); + buffer->lna = rvec->agc_lna; + buffer->ppm = calc_ppm(rvec); + ptr = (ptr + 1) & 7; + pa_env[id].input_buffer_ptr = ptr; + } +} + +int8_t pa_alloc(uint32_t vif_addr) { + for (int i = 0; i < 4; i++) { + if (!pa_env[i].used) { + pa_env[i].used = 1; + pa_env[i].vif_tag = vif_addr; + return i; + } + } + + return -1; +} + +void pa_reset(uint8_t id) { + return ; +} + +void pa_free(uint8_t id) { + if (id < 4) { + pa_env[id].used = 0; + pa_env[id].vif_tag = 0; + } +} + diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_bl602.c b/src/bl602_wifi/driver/phy/phy_rf/phy_bl602.c new file mode 100644 index 0000000..8d0aa0c --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_bl602.c @@ -0,0 +1,407 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int8_t rxgain_offset_vs_temperature; // :79:15 +static int8_t poweroffset[14]; // :80:15 + +struct phy_env_tag phy_env[1]; // :75:20 + +void phy_config_rxgain(int offset) { + if (rxgain_offset_vs_temperature != offset) { + rxgain_offset_vs_temperature = (int8_t) offset; + AGC->rxgain_offset_vs_temperature[0] = (int)rxgain_offset_vs_temperature + 3; + AGC->rxgain_offset_vs_temperature[1] = (int)rxgain_offset_vs_temperature + 11; + AGC->rxgain_offset_vs_temperature[2] = (int)rxgain_offset_vs_temperature + 18; + AGC->rxgain_offset_vs_temperature[3] = (int)rxgain_offset_vs_temperature + 25; + AGC->rxgain_offset_vs_temperature[4] = (int)rxgain_offset_vs_temperature + 32; + AGC->rxgain_offset_vs_temperature[5] = (int)rxgain_offset_vs_temperature + 39; + AGC->rxgain_offset_vs_temperature[6] = (int)rxgain_offset_vs_temperature + 45; + AGC->rxgain_offset_vs_temperature[7] = (int)rxgain_offset_vs_temperature + 53; + AGC->rxgain_offset_vs_temperature[8] = (int)rxgain_offset_vs_temperature + 59; + } +} + +void phy_get_channel(struct phy_channel_info *info, uint8_t index) { + info->info1 = (uint32_t)phy_env[0].chnl_type << 8 | (uint32_t)phy_env[0].chnl_prim20_freq << 16 | + (uint32_t)phy_env[0].band; + info->info2 = phy_env[0].chnl_center1_freq | ((uint32_t)phy_env[0].chnl_center2_freq << 16); +} + +uint8_t phy_get_mac_freq(void) { + return PHY_BL602_MACCORE_FREQ_MHZ; +} + +uint8_t phy_get_nss(void) { + return (uint8_t)(( (int8_t)(MDM->version.nss & 0xf) )- 1); +} + +uint8_t phy_get_nsts(void) { + return (uint8_t)(( (int8_t)(MDM->version.nsts & 0xf) )- 1); +} + +uint8_t phy_get_ntx(){ + return (uint8_t)(( (int8_t)(MDM->version.ntx & 0xf) )- 1); +} + +void phy_get_version(uint32_t *version_1,uint32_t *version_2) { + *version_1 = MDM->version.value; + *version_2 = 0; + return; +} + +void agc_config(void) { + AGC->RWNXAGCCNTL.riu_htstfgainen = 0x0; + AGC->RWNXAGCCNTL.riu_rifsdeten = 0x0; + AGC->r0xb3a4.riu_fe20gain = 0x0; + AGC->r0xb3a4.riu_fe40gain = 0x0; + AGC->r0xb394.riu_vpeakadcqdbv = 0xf8; + AGC->r0xb398.riu_adcpowmindbm = 0x9e; + AGC->r0xb3c4.riu_adcpowsupthrdbm = 0xce; + AGC->r0xb364.riu_satdelay50ns = 0x8; + AGC->r0xb364.riu_sathighthrdbv = 0x3c; + AGC->r0xb364.riu_satlowthrdbv = 0x38; + AGC->r0xb364.riu_satthrdbv = 0x39; + AGC->r0xb368.riu_crossdnthrqdbm = 0x70; + AGC->r0xb368.riu_crossupthrqdbm = 0x70; + AGC->RWNXAGCRAMP.riu_rampupgapqdb = 0x12; + AGC->RWNXAGCRAMP.riu_rampupndlindex = 0x5; + AGC->RWNXAGCRAMP.riu_rampdngapqdb = 0x28; + AGC->RWNXAGCRAMP.riu_rampdnndlindex = 0x7; + AGC->r0xb370.riu_adcpowdisthrdbv = 0x58; + AGC->r0xb3c0.riu_idinbdpowgapdnqdbm = 0x18; + AGC->r0xb380.riu_evt0op3 = 0x3e; + AGC->r0xb380.riu_evt0op2 = 0x37; + AGC->r0xb380.riu_evt0op1 = 0x1; + AGC->r0xb380.riu_evt0pathcomb = 0x0; + AGC->r0xb380.riu_evt0opcomb = 0x1; + AGC->r0xb384.riu_evt1op1 = 0x39; + AGC->r0xb384.riu_evt1op2 = 0x37; + AGC->r0xb384.riu_evt1op3 = 0x14; + AGC->r0xb384.riu_evt1pathcomb = 0x0; + AGC->r0xb384.riu_evt1opcomb = 0x2; + AGC->r0xb388.riu_evt2op1 = 0xf; + AGC->r0xb388.riu_evt2op2 = 0x17; + AGC->r0xb388.riu_evt2op3 = 0x2a; + AGC->r0xb388.riu_evt2pathcomb = 0x0; + AGC->r0xb388.riu_evt2opcomb = 0x5; + AGC->r0xb38c.riu_evt3op1 = 0x19; + AGC->r0xb38c.riu_evt3op2 = 0x0; + AGC->r0xb38c.riu_evt3op3 = 0xe; + AGC->r0xb38c.riu_evt3opcomb = 0x2; + AGC->r0xc830.rc2_evt4op1 = 0x3f; + AGC->r0xc830.rc2_evt4op2 = 0x1; + AGC->r0xc830.rc2_evt4op3 = 0x36; + AGC->r0xc830.rc2_evt4opcomb = 0x5; + AGC->r0xc814.rc2_pkdet_mode = 0x0; + AGC->r0xc814.rc2_pkdet_cnt_thr = 0x2; + AGC->r0xc814.rc2_pkdet_cnt_thr = 0x2; + AGC->r0xc040.rc2_rx0_vga_idx_max = 0xc; + AGC->r0xc040.rc2_rx0_vga_idx_min = 0x3; + AGC->r0xc044.rc2_rx0_lna_idx_max = 0x8; + AGC->r0xc044.rc2_rx0_lna_idx_min = 0x0; + + phy_config_rxgain(0); + + AGC->r0xb3a0.riu_inbdpowmindbm = 0x9e; + AGC->r0xb3c0.riu_inbdpowsupthrdbm = 0xa4; + AGC->r0xb3c0.riu_inbdpowinfthrdbm = 0xa3; + AGC->r0xc82c.rc2_inbdpow_adj_thr_dbm = 0xb5; + AGC->r0xc82c.rc2_inbdpowsupthr_adj_en = 0x1; + AGC->r0xc82c.rc2_inbdpowinfthr_adj_en = 0x1; + AGC->r0xc838.rc2_reflevofdmthd_en = 0x1; + AGC->r0xc838.rc2_reflevofdmthd = 0x100; + AGC->r0xc83c.rc2_reflevdsssthd_en = 0x1; + AGC->r0xc83c.rc2_reflevdsssthd = 0x17c; + AGC->r0xc840.rc2_reflevdssscontthd_en = 0x1; + AGC->r0xc840.rc2_reflevdssscontthd = 0x100; + AGC->r0xc82c.rc2_inbdpowfastvalid_cnt = 0x40; +} + +void bz_phy_reset(void) { + int tx_rampup_time_us = 8; + int tx_rampdn_time_us = 4; // 4 + int tx_padzero_time_us = 0; + BZ_PHY->r0x2808.bz_phy_tx_rampup_fm_on = 0x1; + BZ_PHY->r0x2808.bz_phy_tx_rampup_time_us = tx_rampup_time_us; + BZ_PHY->r0x280c.bz_phy_tx_rampdn_fm_on = 0x1; + BZ_PHY->r0x280c.bz_phy_tx_rampdn_time_us = tx_rampdn_time_us; + BZ_PHY->r0x280c.bz_phy_tx_rampdn_pad0_time_us = tx_padzero_time_us; + BZ_PHY->r0x2854.bz_phy_rx_proc_time_mlsd_us = 0x20; + BZ_PHY->r0x2854.bz_phy_rx_proc_time_direct_us = 0x1e; + BZ_PHY->r0x2854.bz_phy_rx_proc_time_eq_us = 0xa; + BZ_PHY->r0x2854.bz_phy_rx_proc_time_viterbi_us = 0x1e; + BZ_PHY->r0x2810.bz_phy_rx_dfe_notch_en = 0x0; + BZ_PHY->r0x2810.bz_phy_rx_dfe_toc_en = 0x1; + BZ_PHY_AGC->r0x2cac.bz_agc_rbb_ind_min = 0x4; + return ; +} + +void mdm_reset() { + MDM->swreset.value = 0x1111; + MDM->swreset.value = 0x0; +} + +void mpif_clk_init(void) { + // Empty Function + return ; +} + +uint8_t phy_bfmee_supported() { + return MDM->version.bfmee_supported; +} + +uint8_t phy_bfmer_supported(void) { + return MDM->version.bfmer_supported; +} + +void phy_get_rf_gain_capab(int8_t *max,int8_t *min) { + *max = trpc_get_rf_max_power(); + *min = trpc_get_rf_min_power(); +} + +void phy_get_rf_gain_idx(int8_t *power,uint8_t *idx) { + *idx = (uint8_t)rfc_get_power_level(RFC_FORMATMOD_11N, (int)*power * 10); +} + +void phy_get_rf_gain_idx_vs_mode(uint8_t mode,int8_t *power,uint8_t *idx) { + *idx = (uint8_t)rfc_get_power_level(mode, (int)*power * 10); +} + +void phy_get_trpc_idx(uint8_t formatmod,uint8_t mcs,int8_t power,uint8_t *idx) { + // THIS IS ONLY MY GUESS. THE REAL DISASSEMBLY LOOKS VERY WEIRD AND IT MUST BE WRONG + ASSERT_ERR(formatmod <= PHY_FORMATMOD_11N); + if (formatmod == PHY_FORMATMOD_11G) + ASSERT_ERR((formatmod == PHY_FORMATMOD_11G) && (mcs <= 7)); // lc9 + if (formatmod == PHY_FORMATMOD_11B) + ASSERT_ERR((formatmod == PHY_FORMATMOD_11B) && (mcs <= 3)); // lc10 + if (formatmod == PHY_FORMATMOD_11N) + ASSERT_ERR((formatmod == PHY_FORMATMOD_11N) && (mcs <= 7)); // lc11 + *idx = (uint8_t)trpc_get_power_idx(formatmod, mcs, power); +} + +void phy_powroffset_set(int8_t *power_offset) { + for (int i = 0; i < 14; i++) { + poweroffset[i] = power_offset[i]; + } +} + +void phy_hw_set_channel(uint8_t band, uint16_t freq, uint16_t freq1, uint8_t chantype) { + ASSERT_ERR(chantype == PHY_CHNL_BW_20); + ASSERT_ERR(band == PHY_BAND_2G4); + AGC->RWNXAGCCNTL.riu_ofdmonly = 0; + MDM->rxchan.rxdsssen = 1; + MDM->mdmconf = 0; + mdm_reset(); + + MDM->txstartdelay = 180; + MDM->txctrl1 = 0x1c13; // (txfeofdm80delay = 19, txfeofdm40delay = 28, txfeofdm20delay = 0, txfedsssdelay = 0)(txfeofdm80delay = 0x13, txfeofdm40delay = 0x1c, txfeofdm20delay = 0, txfedsssdelay = 0) + MDM->txctrl3 = 0x2d00438; // mdm_txctrl3_pack(txphyrdyhtdelay = 720, txphyrdynonhtdelay = 1080) + + MDM->TBECTRL0.tbe_count_adjust_20 = 0; // TBE for 60MHz + + MDM->DCESTIMCTRL.value = 0xf0f; // (starthtdc = 0, startdc = 0, delaysynctd20 = 0, delaysync = 0xf, waithtstf = 0xf) + + MDM->DCESTIMCTRL.WAITHTSTF = 7; // For FPGA, divide value by 2 due to timing constraints + + MDM->r834.tddchtstfmargin = 0x6; + MDM->SMOOTHCTRL.value = 0x1880c06; // smooth enable/auto-selection + MDM->tbectrl2 = 0x7f03; + + // No ACI margin in BW=20MHz due to latency on HTSIG decoding + AGC->riu_rwnxagcaci20marg0 = 0; + AGC->riu_rwnxagcaci20marg1 = 0; + AGC->riu_rwnxagcaci20marg2 = 0; + + MDM->txchan.txcbwmax = chantype; + + if (AGC->r000.iqcomp) { + AGC->riu_iqestiterclr = 1; + } + + rf_set_channel(chantype, freq1); + + uint8_t channel = 0; + + channel = phy_freq_to_channel(band, freq); + rfc_apply_tx_power_offset(channel, poweroffset); + trpc_update_vs_channel((int8_t)freq1); +} + +void phy_set_channel(uint8_t band,uint8_t type,uint16_t prim20_freq,uint16_t center1_freq, + uint16_t center2_freq,uint8_t index) { + if ((center1_freq >= 2412 && center1_freq <= 2484) || (band == PHY_BAND_5G)) { + phy_hw_set_channel(band,prim20_freq,center1_freq,type); + phy_env[0].chnl_prim20_freq = prim20_freq; + phy_env[0].chnl_center1_freq = center1_freq; + phy_env[0].band = band; + phy_env[0].chnl_type = type; + } +} + +extern uint32_t agcmem[]; + +static void agc_download() { + AGC->RWNXAGCCNTL.agcfsmreset = 1; + + MDM->r0x874.mdm_agcmemclkforce = 1; + + for (int i = 0; i < PHY_BL602_AGC_MEM_SIZE / 4; i++) + AGCRAM->agcram[i] = agcmem[i]; + + MDM->r0x874.mdm_agcmemclkforce = 0; + AGC->RWNXAGCCNTL.agcfsmreset = 0; + AGC->r0xc020.rc_paoff_delay = 0x14; +} + +static void phy_hw_init(const struct phy_bl602_cfg_tag *cfg) { + MDM->mdmconf = BW_20MHZ; + mdm_reset(); + + // realname = rxmode + MDM->rxchan.value = 0x20d; + /* + PACK(MDM->rxchan, rxmode) { + rxmode.rxdsssen = 1; // MDM_RXDSSSEN_BIT + rxmode.pad0 = 0b11; // bit 2-3 MDM_RXMMEN_BIT MDM_RXGFEN_BIT + rxmode.pad2 = 1; // bit 9 MDM_RXSTBCEN_BIT + } + */ + MDM->rxchan.rxnssmax = phy_get_nss(); + MDM->rxchan.rxndpnstsmax = phy_get_nsts(); + MDM->rxchan.rxldpcen = MDM->version.ldpcdec; + MDM->rxchan.rxvhten = phy_vht_supported(); + MDM->rxchan.rxmumimoen = MDM->version.mu_mimo_rx; + MDM->r3024.precomp = 45; + + // Rx frame violation check + // [31:15]: VHT + // [14: 4]: HT + // [ 3: 0]: NON-HT + MDM->rxframeviolationmask = 0xffffffff; + + MDM->txchan.value = 0x20d; + /* + PACK(MDM->txchan, txmode) { + txmode.txdsssen = 1; // MDM_TXDSSSEN_BIT + txmode.pad1 = 0b11; // bit 2-3 MDM_TXMMEN_BIT MDM_TXGFEN_BIT + txmode.pad3 = 1; // bit 9 MDM_TXSTBCEN_BIT + } + */ + + MDM->txchan.txnssmax = phy_get_nss(); + MDM->txchan.ntxmax = phy_get_ntx(); + MDM->txchan.txcbwmax = MDM->version.chbw; + MDM->txchan.txldpcen = MDM->version.ldpcenc; + MDM->txchan.vht = phy_vht_supported(); + MDM->txchan.txmumimoen = MDM->version.mu_mimo_tx; + + // AGC reset mode + // Don't turn off RF if rxreq de-asserted for few cycles after a RXERR + MDM->r834.rxtdctrl1 = 1; + + // Enable automatic smoothing filter selection from SNR, then disable force + MDM->SMOOTHCTRL.CFGSMOOTHFORCE = 0; + MDM->SMOOTHSNRTHR.smoothsnrthrhigh = 0x1b; + MDM->SMOOTHSNRTHR.smoothsnrthrmid = 0xf; + + // limit NDBPSMAX to 1x1 80 MCS7 LGI(292.5Mb/s) / SGI (325.0Mb/s) + MDM->rxctrl1 = 0x4920492; + MDM->r0x874.rcclkforce = 1; + + AGC->r0xb500.riu_txshift4044 = 0x02; + if (AGC->r000.iqcomp) { + AGC->r0xb110.riu_rxiqphaseesten = 0; + AGC->r0xb110.riu_rxiqgainesten = 0; + AGC->r0xb110.riu_rxiqphasecompen = 0; + AGC->r0xb110.riu_rxiqgaincompen = 0; + AGC->riu_iqestiterclr = 0; + } + + // limit RIU to 1 or 2 antenna active depending on modem capabilities + AGC->activeant = 1; + + // limit AGC with a single antenna (path0) + AGC->RWNXAGCCNTL.combpathsel = 1; + + // CCA timeout + AGC->RWNXAGCCCATIMEOUT = 4000000; + AGC->irqmacccatimeouten.irqmacccatimeouten = 1; + + agc_config(); + + agc_download(); +} + +void phy_init(const phy_cfg_tag *config) { + const struct phy_bl602_cfg_tag *cfg = (const struct phy_bl602_cfg_tag *)&config->parameters; + phy_hw_init(cfg); + + phy_env[0].cfg.reserved = (config->parameters)[0]; + phy_env[0].chnl_center1_freq = PHY_UNUSED; + phy_env[0].chnl_center2_freq = PHY_UNUSED; + phy_env[0].chnl_prim20_freq = PHY_UNUSED; + phy_env[0].band = PHY_BAND_2G4; + phy_env[0].chnl_type = PHY_CHNL_BW_OTHER; + + trpc_init(); + pa_init(); + phy_tcal_reset(); + phy_tcal_start(); +} + +uint8_t phy_vht_supported() { + if (MDM->version.vht) + return 1; + return MDM->version.chbw > PHY_CHNL_BW_40; +} + +uint8_t phy_ldpc_rx_supported(void) { + return MDM->version.ldpcrx; +} + +uint8_t phy_ldpc_tx_supported(void) { + return MDM->version.ldpctx; +} + +void phy_mdm_isr(void) { + return; +} + +uint8_t phy_mu_mimo_rx_supported(void) { + return MDM->version.mu_mimo_rx; +} + +uint8_t phy_mu_mimo_tx_supported(void) { + return MDM->version.mu_mimo_tx; +} + +void phy_rc_isr(void) { + uint32_t val = AGC->rwnxmacintstatmasked.value; + AGC->rwnxmacintack = val; + if (val & 0x100) { + // RIU_IRQMACCCATIMEOUTMASKED_BIT + mdm_reset(); + } +} + +void phy_reset(void) { + return ; +} + +void phy_stop(void) { + return ; +} diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_hal.c b/src/bl602_wifi/driver/phy/phy_rf/phy_hal.c new file mode 100644 index 0000000..2875832 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_hal.c @@ -0,0 +1,44 @@ +#include +#include + +static struct phy_hal_tag hal_env; + +uint8_t hal_get_capcode(void) { + return AON->xtal_cfg.xtal_capcode_in_aon; +} + +void hal_set_capcode(uint32_t capcode) { + /* + AON->xtal_cfg.xtal_capcode_out_aon = capcode; + AON->xtal_cfg.xtal_capcode_in_aon = capcode; + */ + AON->xtal_cfg.value = (capcode & 0x3f) << 0x10 | (capcode & 0x3f) << 0x16 | AON->xtal_cfg.value & 0xf000ffff; +} + +void hal_set_capcode_asymm(uint32_t capcode_in, uint32_t capcode_out) { + /* + AON->xtal_cfg.xtal_capcode_out_aon = capcode_out; + AON->xtal_cfg.xtal_capcode_in_aon = capcode_in; + */ + + AON->xtal_cfg.value = (capcode_out & 0x3f) << 0x10 | (capcode_in & 0x3f) << 0x16 | AON->xtal_cfg.value & 0xf000ffff; +} + +void hal_get_capcode_asymm(uint8_t *capcode_in, uint8_t *capcode_out) { + if (capcode_in) { + *capcode_in = AON->xtal_cfg.xtal_capcode_in_aon; + } + if (capcode_out) { + *capcode_out = AON->xtal_cfg.xtal_capcode_out_aon; + } +} + +bool hal_get_temperature(int16_t *temperature) { + *temperature = hal_env.temperature; + return 1; +} + +void hal_set_temperature(int16_t temperature) { + hal_env.temperature = temperature; +} + diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_helper.c b/src/bl602_wifi/driver/phy/phy_rf/phy_helper.c new file mode 100644 index 0000000..e342402 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_helper.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include + +#include "utils.h" + +static char *rc_state_str[8] = { + "RC_IDLE", + "RC_RX2ON", + "RC_TX2ON", + "RC_RXON", + "RC_TX2PAON", + "UNKNOWN", + "UNKNOWN", + "RC_TXPAON", +}; + +static char *rf_state_str[8] = { + "RF_PD", + "RF_SB", + "RF_LO", + "RF_RX", + "RF_TX", + "RF_T2RI", + "RF_R2T", + "RF_MS", +}; + +static struct dump_data_t dump_data_poll[18]; // :86:27 +static uint8_t dump_data_ptr; // :87:16 + +int bl60x_check_mac_status(int * is_ok) { + int ok = 0; + for (int i = 0; i < dump_data_ptr; i++) { + if (dump_data_poll[i].mac_debugRegHWSM2 != 0x8801e000) { + ok = 1; + break; + } + } + * is_ok = ok; +} + +void helper_channel_monitor(uint32_t chanfreq, timer_func_ptr * timer_func, int nrepeats, int mon_time_ms) { + // no code + return ; +} + +void helper_record_all_states(char * func_name) { + int id = dump_data_ptr; + dump_data_poll[id].func_name = func_name; + dump_data_poll[id].time = MAC_CORE->MONOTONIC_COUNTER_2_LO.value; + + helper_record_rc_rf_states(&dump_data_poll[id].rc_state, &dump_data_poll[id].rf_state); + + dump_data_poll[id].mac_debugRegHWSM1 = MAC_CORE->DEBUG_HWSM_1.value; + dump_data_poll[id].mac_debugRegHWSM2 = MAC_CORE->DEBUG_HWSM_2.value; + + MAC_CORE->DEBUG_PORT_SEL.debugPortSel1 = 0x31; + MAC_CORE->DEBUG_PORT_SEL.debugPortSel2 = 0; + + *(uint32_t*)(&dump_data_poll[id].mac_debugPortCoex) = MAC_CORE->DEBUG_PORT_VALUE.value; + + MAC_CORE->DEBUG_PORT_SEL.debugPortSel1 = 0xb; + MAC_CORE->DEBUG_PORT_SEL.debugPortSel2 = 0x2f; + + *(uint32_t*)(&dump_data_poll[id].mac_debugPortMacPhyIf) = MAC_CORE->DEBUG_PORT_VALUE.value; + + SYSCTRL->r074 = 0x33a; + SYSCTRL->diag_conf.diag_sel = 0x14; + + GLB->DBG_SEL_LL.value = 0x4; + GLB->DBG_SEL_LH.value = 0x40000004; + GLB->DBG_SEL_HL.value = 0x80000004; + GLB->DBG_SEL_HH.value = 0xc0000004; + + GLB->debug.debug_oe = 0; + + uint32_t debug = GLB->debug.value; + + dump_data_poll[id].phy_debugPortTDTX = (uint16_t)(debug >> 1); + dump_data_poll[id].phy_debugPortMainFSM = (uint16_t)(debug >> 0x11); + + SYSCTRL->r074 = 0xb09; + + GLB->debug.debug_oe = 0; + debug = GLB->debug.value; + dump_data_poll[id].phy_debugPortDSSSCCK1 = (uint16_t)(debug >> 1); + dump_data_poll[id].phy_debugPortDSSSCCKTx = (uint16_t)(debug >> 0x11); + dump_data_ptr = (dump_data_ptr + 1) & 0xf; +} + +void helper_record_dump(void) { + puts("========= helper_record_dump\r\n"); + for (int i = 0; i < dump_data_ptr; i++) { + struct dump_data_t *data = &dump_data_poll[i]; + printf("[%d] time %ld, func %s\r\n", i, data->time, data->func_name); + printf("MAC: %08lx: rxControlCs %d,txControlCs %d,macControlCs %d\r\n", + data->mac_debugRegHWSM2, + data->mac_debugRegHWSM2 & 0x3f, + data->mac_debugRegHWSM2 >> 8 & 0x1ff, + data->mac_debugRegHWSM2 >> 24 & 0xff + ); + printf("MAC: Coex %04x,Backoff %04x,MPIF %04x,MPIF2 %04x\r\n", + (uint32_t)data->mac_debugPortCoex, + (uint32_t)data->mac_debugPortBackoff, + (uint32_t)data->mac_debugPortMacPhyIf, + (uint32_t)data->mac_debugPortMacPhyIf2 + ); + printf("PHY: MainFSM %04x,TDTX %04x,DSSSCCK1 %04x,DSSSCCKTx %04x\r\n", + (uint32_t)data->phy_debugPortMainFSM, + (uint32_t)data->phy_debugPortTDTX, + (uint32_t)data->phy_debugPortDSSSCCK1, + (uint32_t)data->phy_debugPortDSSSCCKTx + ); + + printf("RFC: RC %s, RF %s\r\n", rc_state_str[data->rc_state], rf_state_str[data->rf_state]); + } + printf("\r\n\r\n"); +} + +void helper_record_rc_rf_states(uint32_t * rc_state, uint32_t * rf_state) { + RF->rfif_dfe_ctrl0.value = RF->rfif_dfe_ctrl0.value & 0xfffffff | 0x10000000; + uint32_t x = RF->rfif_test_read.value; + RF->rfif_dfe_ctrl0.value = RF->rfif_dfe_ctrl0.value & 0xfffffff | 0x20000000; + x = RF->rfif_test_read.value; + *rc_state = x >> 0x1c & 7; + *rf_state = x >> 0x19 & 7; +} + +void helper_record_reset(void) { + dump_data_ptr = 0; +} diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_tcal.c b/src/bl602_wifi/driver/phy/phy_rf/phy_tcal.c new file mode 100644 index 0000000..c2cdded --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_tcal.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include +#include + +static struct tcal_tag tcal_env; // :41:24 + +void phy_tcal_reset(void) { + memset(&tcal_env, 0, sizeof(tcal_env)); + tcal_env.prev_temperature = 0x19; + tcal_env.last_action_temperature[0] = 0x19; + tcal_env.last_action_temperature[1] = 0x19; + tcal_env.last_action_temperature[2] = 0x19; + tcal_env.last_action_temperature[3] = 0x19; + tcal_env.enabled = 1; +} + +void phy_tcal_start(void) { + tcal_env.enabled = 1; +} + +void phy_tcal_stop(void) { + tcal_env.enabled = 0; +} + +void phy_tcal_handle(void) { + int16_t temp; + if (hal_get_temperature(&temp)) { + phy_tcal_txpwr(temp); + int cutoff = temp; + if (cutoff > 125) + cutoff = 125; + if (cutoff < -40) + cutoff = -40; + // iVar3 = (int)((uVar2 - 0x19) * 0x10000) >> 0x10; sign? + int offset = cutoff - 25; + if (offset < 1) { + offset = (offset * -6) >> 8; + } else { + offset = ((offset * 6) >> 8) * (-1); + } + if (offset != tcal_env.last_action_out[2]) { + phy_config_rxgain(offset); + tcal_env.last_action_temperature[2] = cutoff; + tcal_env.last_action_out[2] = offset; + } + tcal_env.prev_temperature = temp; + } +} + +void phy_tcal_callback(int16_t temperature) { + hal_set_temperature(temperature); + if (tcal_env.enabled) { + phy_tcal_handle(); + } +} + +void phy_tcal_txpwr(int16_t curr_temperature) { + rf_pri_tx_gain_comp(curr_temperature); + trpc_update_vs_temperature((int8_t)curr_temperature); +} diff --git a/src/bl602_wifi/driver/phy/phy_rf/phy_trpc.c b/src/bl602_wifi/driver/phy/phy_rf/phy_trpc.c new file mode 100644 index 0000000..5410503 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/phy_trpc.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include + +int8_t txpwr_vs_rate_table[3][8] = { + {0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12}, + {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x0e}, + {0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, 0x0e}, +}; // :12:15 + +static struct trpc_env_tag trpc_env; + +uint8_t trpc_get_default_power_idx(uint8_t formatmod, uint8_t mcs) { + if (formatmod > PHY_FORMATMOD_11N) { + formatmod = PHY_FORMATMOD_11N; + } + int mcs_max = 3; + if (formatmod) { + mcs_max = 7; + } + if (mcs > mcs_max) { + mcs = mcs_max; + } + return trpc_get_power_idx(formatmod, mcs, txpwr_vs_rate_table[formatmod][mcs]); +} + +uint8_t trpc_get_power_idx(uint8_t formatmod, uint8_t mcs, int8_t pwr_dbm) { + if (formatmod > PHY_FORMATMOD_11N) { + formatmod = PHY_FORMATMOD_11N; + } + int mcs_max = 3; + if (formatmod) { + mcs_max = 7; + } + if (mcs > mcs_max) { + mcs = mcs_max; + } + int pwr = MIN(trpc_env.power_dbm_max_rf, trpc_env.power_dbm_lim_reg); + pwr = MIN(pwr, pwr_dbm); + pwr = MIN(pwr, txpwr_vs_rate_table[formatmod][mcs]); + pwr = MAX(pwr, trpc_env.power_dbm_min_rf); + int x = (int)(((double)((int)(pwr * -510 + trpc_env.power_dbm_max_rf) / 512)) + (double)0.5) & 0xff; + + if (formatmod == PHY_FORMATMOD_11B) + x += 3; + x &= 0xff; + if (x > 0xf) + x = 0xf; + + return x << 2; +} + +int8_t trpc_get_rf_max_power() { + return trpc_env.power_dbm_max_rf; +} + +int8_t trpc_get_rf_min_power() { + return trpc_env.power_dbm_min_rf; +} + +void trpc_init(void) { + trpc_env.channel_freq = 2442; + trpc_env.power_dbm_max_rf = rf_pri_get_txgain_max(); + trpc_env.power_dbm_min_rf = rf_pri_get_txgain_min(); + trpc_env.power_dbm_lim_reg = 30; + trpc_env.temperature = 25; +} + +void trpc_power_get(int8_t *power_rate_table) { + memcpy(power_rate_table, txpwr_vs_rate_table, sizeof(txpwr_vs_rate_table)); +} + +void trpc_update_power(int8_t (*power_rate_table) [8]) { + for (int i = 0; i < 3; i ++) { + for (int j = 0; j < 8; j++) { + txpwr_vs_rate_table[i][j] = power_rate_table[i][j]; + } + } +} + +void trpc_update_power_11b(int8_t *power_rate_table) { + for (int j = 0; j < 8; j++) { + txpwr_vs_rate_table[0][j] = power_rate_table[j]; + } +} + +void trpc_update_power_11g(int8_t *power_rate_table) { + for (int j = 0; j < 8; j++) { + txpwr_vs_rate_table[1][j] = power_rate_table[j]; + } +} + +void trpc_update_power_11n(int8_t *power_rate_table) { + for (int j = 0; j < 8; j++) { + txpwr_vs_rate_table[2][j] = power_rate_table[j]; + } +} + +void trpc_update_vs_channel(int8_t channel_MHz) { + trpc_env.channel_freq = channel_MHz; + trpc_env.power_dbm_max_rf = rf_pri_get_txgain_max(); + trpc_env.power_dbm_min_rf = rf_pri_get_txgain_min(); +} + + +void trpc_update_vs_temperature(int8_t temperature) { + trpc_env.temperature = temperature; + trpc_env.power_dbm_max_rf = rf_pri_get_txgain_max(); + trpc_env.power_dbm_min_rf = rf_pri_get_txgain_min(); +} diff --git a/src/bl602_wifi/driver/phy/phy_rf/rf.c b/src/bl602_wifi/driver/phy/phy_rf/rf.c new file mode 100644 index 0000000..32f713d --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/rf.c @@ -0,0 +1,24 @@ +#include +#include +#include + +void rf_set_channel(uint8_t bandwidth, uint16_t channel_freq) { + rfc_config_channel(channel_freq); +} + +void rf_clkpll_isr(void) { + return ; +} + +void rf_init(void) { + __disable_irq(); + __enable_irq(); +} + +void rf_lo_isr(void) { + return ; +} + +void rf_dump_status(void) { + return ; +} \ No newline at end of file diff --git a/src/bl602_wifi/driver/phy/phy_rf/rf_private_save.h b/src/bl602_wifi/driver/phy/phy_rf/rf_private_save.h new file mode 100644 index 0000000..06aa13b --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/rf_private_save.h @@ -0,0 +1,29 @@ +#ifdef RF_PRI_SAVE +RF_PRI_SAVE(rf_fsm_ctrl_hw); +RF_PRI_SAVE(rfctrl_hw_en); +RF_PRI_SAVE(rfcal_ctrlen); +RF_PRI_SAVE(pucr1); +RF_PRI_SAVE(fbdv); +RF_PRI_SAVE(sdm1); +RF_PRI_SAVE(sdm2); +RF_PRI_SAVE(rbb3); +RF_PRI_SAVE(adda1); +RF_PRI_SAVE(dfe_ctrl_0); +RF_PRI_SAVE(dfe_ctrl_3); +RF_PRI_SAVE(dfe_ctrl_6); +RF_PRI_SAVE(dfe_ctrl_7); +RF_PRI_SAVE(trx_gain1); +RF_PRI_SAVE(singen_ctrl0); +RF_PRI_SAVE(singen_ctrl2); +RF_PRI_SAVE(singen_ctrl3); +RF_PRI_SAVE(rf_sram_ctrl0); +RF_PRI_SAVE(rf_sram_ctrl1); +RF_PRI_SAVE(rf_sram_ctrl2); +RF_PRI_SAVE(rf_resv_reg_1); +RF_PRI_SAVE(pa1); +RF_PRI_SAVE(ten_ac); +RF_PRI_SAVE(rfif_dfe_ctrl0); +RF_PRI_SAVE(tbb); +RF_PRI_SAVE(vco2); +#undef RF_PRI_SAVE +#endif \ No newline at end of file diff --git a/src/bl602_wifi/driver/phy/phy_rf/rfc_bl602.c b/src/bl602_wifi/driver/phy/phy_rf/rfc_bl602.c new file mode 100644 index 0000000..05cdd31 --- /dev/null +++ b/src/bl602_wifi/driver/phy/phy_rf/rfc_bl602.c @@ -0,0 +1,785 @@ + +#include +#include +#include + +#include +#include +#include +#include + +#define prefix "[RFC] " + +static int inited = 0; +static double xtalfreq_MHz = 40.0; +static void wait_us(uint32_t); +static void wait_ms(uint32_t); +static void _set_rfc(); +static void _set_mdm(); +static void _set_rf_channel_sw(uint32_t); +static void _set_rf_channel_hw(uint32_t); +static uint32_t _calc_sdm_cw(float xtalfreq_MHz, float freq); +//static void _calc_sdm_params(uint32_t xtalfreq,uint32_t *lo_center_freq_mhz,uint32_t *lo_sdmin_center,uint32_t *lo_sdmin_1m,uint32_t *lo_sdmin_if); +static void _set_rfc_powercontrol(uint32_t pc_mode); + +// todo: check me +static void _sync_tx_power_offset() { + uint32_t rfg_index; + uint32_t dg; + + typedef struct { + uint32_t rf_tbb_ind_gc : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + } __attribute__((packed)) rf_tbb_ind_t; + union { + rf_tbb_ind_t val[16]; + uint32_t pack[2]; + } rf_tbb_ind = {.pack = {0}}; + typedef struct { + uint32_t tx_dvga_gain_qdb_gc : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + } __attribute__((packed)) dvga_gain_t; + union { + dvga_gain_t val[16]; + uint32_t pack[4]; + } dvga_gain = {.pack = {0}}; + for (int i = 0; i < 16; i++) { + rf_pri_query_txgain_table(i, &rfg_index, &dg); + rf_tbb_ind.val[i].rf_tbb_ind_gc = rfg_index & 7; + dvga_gain.val[i].tx_dvga_gain_qdb_gc = dg; + } + RF->dfe_ctrl_16.value = rf_tbb_ind.pack[0]; + RF->dfe_ctrl_12.value = dvga_gain.pack[0]; + RF->dfe_ctrl_13.value = dvga_gain.pack[1]; + RF->dfe_ctrl_17.value = rf_tbb_ind.pack[1]; + RF->dfe_ctrl_14.value = dvga_gain.pack[2]; + RF->dfe_ctrl_15.value = dvga_gain.pack[3]; +} + +void rfc_apply_tx_power_offset(uint8_t channel, int8_t *power_offset) { + rf_pri_update_tx_power_offset(channel, power_offset); + _sync_tx_power_offset(); +} + +// todo: check me +void rfc_apply_tx_dvga(int8_t *dvga_qdb) { + uint32_t dvga_qdb_align[4]; + memcpy(dvga_qdb_align, dvga_qdb, sizeof(dvga_qdb_align)); + dvga_qdb_align[0] &= 0x7f7f7f7f; + dvga_qdb_align[1] &= 0x7f7f7f7f; + dvga_qdb_align[2] &= 0x7f7f7f7f; + dvga_qdb_align[3] &= 0x7f7f7f7f; + RF->dfe_ctrl_12.value = dvga_qdb_align[0]; + RF->dfe_ctrl_13.value = dvga_qdb_align[1]; + RF->dfe_ctrl_14.value = dvga_qdb_align[2]; + RF->dfe_ctrl_15.value = dvga_qdb_align[3]; +} + +// todo: verify me +void rfc_apply_tx_dvga_offset(int8_t offset_qdb) { + volatile uint8_t * gain = (volatile uint8_t *) (&RF->dfe_ctrl_12); + for (int i = 0; i < 16; i++) { + uint8_t vold_gain = gain[i]; + int old_gain = ((int)vold_gain << 0x19) >> 0x19; + int new_gain = RF->dfe_ctrl_12.tx_dvga_gain_qdb_gc0 + offset_qdb; + if (new_gain > 24) + new_gain = 24; + if (new_gain < -48) + new_gain = -48; + gain[i] = (vold_gain & 0x80) | (new_gain & 0x7f); + } +} + +void rfc_rxdfe_set_notch0(uint8_t en, uint8_t alpha, int8_t nrmfc) { + RF->r0x1700.rf_rx_notch0_en = en; + RF->r0x1700.rf_rx_notch0_alpha = alpha; + RF->r0x1700.rf_rx_notch0_nrmfc = nrmfc; +} + +static void _set_rf_channel_hw(uint32_t channel_freq) { + RF->rf_fsm_ctrl0.rf_ch_ind_wifi = channel_freq & 0xfff; + RF->rf_fsm_ctrl1.rf_fsm_lo_rdy_rst = 1; + wait_us(10); + RF->rf_fsm_ctrl1.rf_fsm_lo_rdy_rst = 0; + wait_us(10); + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 0; + wait_us(10); + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 1; + wait_us(10); + RF->rf_fsm_ctrl2.rf_fsm_st_dbg = 1; + wait_us(10); + RF->rf_fsm_ctrl2.rf_fsm_st_dbg_en = 1; + wait_us(10); + RF->rf_fsm_ctrl2.rf_fsm_st_dbg = 2; + wait_us(100); + RF->rf_fsm_ctrl2.rf_fsm_st_dbg_en = 0; + wait_us(10); +} + +static void _print_channel_info() { + printf("Channel information:\r\n"); + printf(" lo_sdmin_hw %lx\r\n", RF->sdm3.lo_sdmin_hw); + printf(" lo_sdmbypass_hw %ld\r\n", RF->sdm1.lo_sdm_bypass_hw); + printf(" lo_vco_idac_cw_hw %lx\r\n", RF->vco1.lo_vco_idac_cw_hw); + printf(" lo_vco_freq_cw_hw %lx\r\n", RF->vco1.lo_vco_freq_cw_hw); + printf(" lo_unlocked %ld\r\n", RF->rf_fsm_ctrl_sw.lo_unlocked); + printf(" lo_halfstep_en_hw %ld\r\n", RF->fbdv.lo_fbdv_halfstep_en_hw); + printf(" lo_slipped_up"); + for (int i = 0; i < 8; i++) { + wait_us(1000); + printf("%ld", RF->lo.lo_slipped_up ? (uint32_t)1 : (uint32_t)0); + } + printf("\r\n"); + printf(" lo_slipped_dn "); + for (int i = 0; i < 8; i++) { + wait_us(1000); + printf("%ld", RF->lo.lo_slipped_dn ? (uint32_t)1 : (uint32_t)0); + } + printf("\r\n"); +} + +void rfc_config_channel(uint32_t channel_freq) { + RF->rfif_dig_ctrl.rfif_int_lo_unlocked_mask = 1; + RF->rfctrl_hw_en.lo_ctrl_hw = 1; + RF->rfctrl_hw_en.sdm_ctrl_hw = 1; + RF->rfctrl_hw_en.pu_ctrl_hw = 1; + + _set_rf_channel_hw(channel_freq); + _print_channel_info(); + rf_pri_update_param(channel_freq); + uint8_t ncf_on; + int32_t ncf_freq_Hz; + rf_pri_get_notch_param(channel_freq, &ncf_on, (int32_t *)&ncf_freq_Hz); + double freq = ncf_freq_Hz; + freq /= 40000000.0; + freq *= 256.0; + freq += 0.5; + int32_t new_freq = freq; + rfc_rxdfe_set_notch0(ncf_on, 1, new_freq); + RF->rfif_dig_ctrl.rfif_int_lo_unlocked_mask = 0; +} + +void rfc_config_channel_sw(uint32_t channel_freq) { + RF->rfctrl_hw_en.lo_ctrl_hw = 0; + RF->rfctrl_hw_en.sdm_ctrl_hw = 0; + RF->rfctrl_hw_en.pu_ctrl_hw = 0; + _set_rf_channel_sw(channel_freq); + + rf_pri_update_param(channel_freq); + uint8_t ncf_on; + int32_t ncf_freq_Hz; + rf_pri_get_notch_param(channel_freq, &ncf_on, &ncf_freq_Hz); + double ncf_fs_Hz = 40 * 1000 * 1000; + int8_t ncf_nrmfc = (int8_t)((ncf_freq_Hz / ncf_fs_Hz) * (1 << 8) + 0.5); + uint8_t ncf_alpha = 1; + rfc_rxdfe_set_notch0(ncf_on, ncf_alpha, ncf_nrmfc); +} + + +void rfc_config_power(uint32_t mode, uint32_t tbb_boost, uint32_t tbb, uint32_t tmx) { + _set_rfc_powercontrol(mode); + + RF->trx_gain1.gc_tbb_boost = tbb_boost; + RF->trx_gain1.gc_tbb = tbb; + RF->trx_gain1.gc_tmx = tmx; +} + + +void rfc_config_bandwidth(uint32_t mode) { + if (mode == RFC_BW_20M) { + // dac + PDS->clkpll_output_en.clkpll_en_div2_480m = 0; + + // adc + RF->adda2.adc_clk_div_sel = 1; + RF->rfif_dig_ctrl.rfckg_rxclk_div2_mode = 0; + + // rbb bw + RF->rbb3.rbb_bw = 2; + // rmxgm + RF->rmxgm.rmxgm_10m_mode_en = 0; + } + else if (mode == RFC_BW_10M) { + // dac + PDS->clkpll_output_en.clkpll_en_div2_480m = 1; + + // adc + + RF->adda2.adc_clk_div_sel = 0; + RF->rfif_dig_ctrl.rfckg_rxclk_div2_mode = 1; + + // rbb bw + RF->rbb3.rbb_bw = 1; + + // rmxgm + RF->rmxgm.rmxgm_10m_mode_en = 1; + } +} + + +uint32_t rfc_get_power_level(uint32_t formatmod, int32_t power) { + if (formatmod > 2) + formatmod = 0; + return rf_pri_get_txgain_index(power, formatmod) << 2; +} + +void rfc_init(uint32_t xtalfreq_hz) { + RF->rfif_dfe_ctrl0.bbmode_4s = 0; + RF->rfif_dfe_ctrl0.bbmode_4s_en = 1; + int xtal_mode = 4; + switch (xtalfreq_hz) { + case 24000000: + xtal_mode = 1; + break; + case 32000000: + xtal_mode = 2; + break; + case 38400000: + xtal_mode = 3; + break; + case 52000000: + xtal_mode = 5; + break; + case 40000000: + default: + break; + } + rf_pri_xtalfreq(xtal_mode); + rf_pri_init(!inited, 1); + inited = 1; + + + _set_rfc(xtalfreq_hz); + _set_mdm(); + + RF->rfif_dfe_ctrl0.bbmode_4s_en = 0; + + // leak code has RF Optimized and CFG_RF_ICAL here + RF->rf_fsm_ctrl_hw.rf_fsm_t2r_cal_mode = 0; + + PDS->clkpll_output_en.clkpll_en_80m = 0; + wait_us(1); + RF->rf_fsm_ctrl_hw.rf_fsm_t2r_cal_mode = 1; + wait_us(1); + PDS->clkpll_output_en.clkpll_en_80m = 1; + + // _check_config(); skipped + printf("rf controller init done\r\n"); +} + +void rfc_reset() { + inited = 0; + rfc_init(xtalfreq_MHz * 1000 * 1000); +} + +static uint32_t _calc_sdm_cw(float xtalfreq_MHz, float freq) { + return (((freq * 4.0) / 3.0) / xtalfreq_MHz) * (1<<22); +} + +void rfc_ver_set(uint8_t ver) { + return ; +} + +void rfc_wlan_mode_force(uint32_t force_mode) { + if (force_mode < 3) { + RF->rfif_dfe_ctrl0.wifimode_4s = force_mode; + RF->rfif_dfe_ctrl0.wifimode_4s_en = 1; + } else { + RF->rfif_dfe_ctrl0.wifimode_4s = 0; + RF->rfif_dfe_ctrl0.wifimode_4s_en = 0; + } +} + +void rfc_txdfe_start() { + RF->rfif_dfe_ctrl0.tx_dfe_en_4s = 1; + wait_us(1); + RF->rfif_dfe_ctrl0.tx_dfe_en_4s_en = 1; +} + +void rfc_txdfe_stop() { + RF->rfif_dfe_ctrl0.tx_dfe_en_4s = 0; + wait_us(1); + RF->rfif_dfe_ctrl0.tx_dfe_en_4s_en = 0; +} + +void rfc_txdfe_mux(int8_t signal_source) { + RF->rfif_dfe_ctrl0.tx_test_sel = signal_source & 3; +} + +void rfc_txdfe_set_dvga(int8_t dvga_qdb) { + if (dvga_qdb < -48 || dvga_qdb > +24) { + printf(prefix "dvga_qdb out of range -48~+24,skip\r\n"); + return ; + } + RF->dfe_ctrl_0.tx_dvga_gain_qdb = dvga_qdb; +} + +void rfc_txdfe_set_iqgaincomp(uint8_t en,uint16_t coeff) { + RF->dfe_ctrl_0.tx_iqc_gain_en = en; + RF->dfe_ctrl_0.tx_iqc_gain = coeff; +} + +void rfc_txdfe_set_iqphasecomp(uint8_t en,int16_t coeff) { + RF->dfe_ctrl_0.tx_iqc_phase_en = en; + RF->dfe_ctrl_0.tx_iqc_phase = coeff; +} + +void rfc_txdfe_set_dccomp(int16_t dcc_i,int16_t dcc_q) { + RF->dfe_ctrl_1.tx_dac_os_i = dcc_i; + RF->dfe_ctrl_1.tx_dac_os_q = dcc_q; + +} + +void rfc_txdfe_set_iqswap(uint8_t swap_on) { + RF->dfe_ctrl_1.tx_dac_iq_swap = swap_on; +} + +void rfc_rxdfe_start() {} +void rfc_rxdfe_stop(); +void rfc_rxdfe_set_iqgaincomp(uint8_t en,uint16_t coeff); +void rfc_rxdfe_set_iqphasecomp(uint8_t en,int16_t coeff); +void rfc_rxdfe_set_dccomp(int16_t dcc_i,int16_t dcc_q); +void rfc_rxdfe_set_iqswap(uint8_t swap_on); +void rfc_rxdfe_set_notch0(uint8_t en,uint8_t alpha,int8_t nrmfc); +void rfc_rxdfe_set_notch1(uint8_t en,uint8_t alpha,int8_t nrmfc); + + +void rfc_sg_start(uint32_t inc_step,uint32_t gain_i,uint32_t gain_q,uint32_t addr_i,uint32_t addr_q) { + RF->singen_ctrl0.singen_en = 0; + RF->singen_ctrl0.singen_inc_step0 = inc_step; + RF->singen_ctrl0.singen_clkdiv_n = 0; // work clock + RF->singen_ctrl1.singen_mode_i = RFC_SG_SINGLE_TONE; // 0: single tone, 1: two tone, 2: ramp + RF->singen_ctrl1.singen_mode_q = RFC_SG_SINGLE_TONE; // 0: single tone, 1: two tone, 2: ramp + + RF->singen_ctrl2.singen_gain_i = gain_i; + RF->singen_ctrl3.singen_gain_q = gain_q; + + RF->singen_ctrl2.singen_start_addr0_i = addr_i; + RF->singen_ctrl3.singen_start_addr0_q = addr_q; + + RF->singen_ctrl0.singen_en = 1; +} + +void rfc_sg_stop() { + RF->singen_ctrl0.singen_en = 0; +} + +uint32_t rfc_pm_start(uint32_t insel,int32_t freq_cw,uint32_t acclen,uint32_t rshiftlen, + int32_t *raw_acc_i,int32_t *raw_acc_q) { + + // turn off and configure power meter + RF->dfe_ctrl_6.rx_pm_en = 0; + + RF->dfe_ctrl_7.rx_pm_start_ofs = 1024; + + RF->dfe_ctrl_7.rx_pm_acc_len = acclen; + RF->dfe_ctrl_6.rx_pm_freqshift_en = (freq_cw != 0); + RF->dfe_ctrl_6.rx_pm_freqshift_cw = freq_cw; + + RF->dfe_ctrl_6.rx_pm_in_sel = insel; + RF->dfe_ctrl_6.rx_pm_en = 1; + + wait_us(100); + + int32_t iqacc_i = RF->dfe_ctrl_8.rx_pm_iqacc_i; // 25BIT + int32_t iqacc_q = RF->dfe_ctrl_9.rx_pm_iqacc_q; // 25BIT + iqacc_i = iqacc_i << 7 >> 7; + iqacc_q = iqacc_q << 7 >> 7; + + if (raw_acc_i) { + *raw_acc_i = iqacc_i; + } + if (raw_acc_q) { + *raw_acc_q = iqacc_q; + } + + iqacc_i = iqacc_i >> rshiftlen; + iqacc_q = iqacc_q >> rshiftlen; + + uint64_t pwr64 = (int64_t)iqacc_i * (int64_t)iqacc_i + (int64_t)iqacc_q * (int64_t)iqacc_q; + + if ((pwr64 >> 32) != 0) { + printf(prefix "overflow occurred\r\n"); + } + + return (uint32_t)(pwr64 & 0xffffffff); +} + +void rfc_pm_stop() { + RF->dfe_ctrl_6.rx_pm_en = 0; + RF->dfe_ctrl_6.rx_pm_freqshift_en = 0; +} + +void rfc_hwctrl_txrfgain(uint8_t hwctrl_on) { + RF->rfctrl_hw_en.tx_gain_ctrl_hw = hwctrl_on; +} + +void rfc_hwctrl_rxgain(uint8_t hwctrl_on) { + RF->rfctrl_hw_en.rx_gain_ctrl_hw = hwctrl_on; +} + +void rfc_hwctrl_txdvga(uint8_t hwctrl_on) { + RF->dfe_ctrl_0.tx_dvga_gain_ctrl_hw = hwctrl_on; +} + +void rfc_hwctrl_calparam(uint8_t hwctrl_on) { + RF->rfctrl_hw_en.trxcal_ctrl_hw = hwctrl_on; +} + +void rfc_fsm_force(uint8_t state) { + if (state != RFC_FSM_FORCE_OFF) { + RF->rf_fsm_ctrl2.rf_fsm_st_dbg = state; + wait_us(20); + RF->rf_fsm_ctrl2.rf_fsm_st_dbg_en = 1; + } else { + RF->rf_fsm_ctrl2.rf_fsm_st_dbg_en = 0; + } +} + +void rfc_rc_fsm_force(uint8_t state) { + if (state == RFC_FSM_FORCE_OFF) { + RF->rf_fsm_ctrl_hw.rf_rc_state_dbg = 0; + wait_us(20); + RF->rf_fsm_ctrl_hw.rf_rc_state_dbg_en = 0; + } else { + RF->rf_fsm_ctrl_hw.rf_rc_state_dbg = state; + wait_us(20); + RF->rf_fsm_ctrl_hw.rf_rc_state_dbg_en = 1; + } +} + +void rfc_coex_force_to(uint32_t force_enable, uint32_t bbmode) { + // reset rf_fsm, fpga_fsm, state_cci + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 0; + + wait_us(10); + + // force coex + RF->rfif_dfe_ctrl0.bbmode_4s = bbmode; + RF->rfif_dfe_ctrl0.bbmode_4s_en = force_enable ? 1 : 0; + + wait_us(10); + + // start fsm + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 1; +} + +void rfc_dump() { + struct rfc_status_tag *p_test_read; + uint32_t test_read[2]; + static char* rc_state_str[8] = { + "RC_IDLE", + "RC_RX2ON", + "RC_TX2ON", + "RC_RXON", + "RC_TX2PAON", + "RC_TXPAON", + "UNKNOWN", + "UNKNOWN" + }; + static char* rf_state_str[8] = { + "RF_PD", + "RF_SB", + "RF_LO", + "RF_RX", + "RF_TX", + "RF_T2RI", + "RF_R2T", + "RF_MS" + }; + + + RF->rfif_dfe_ctrl0.test_sel = 1; + test_read[0] = RF->rfif_test_read.value; + + RF->rfif_dfe_ctrl0.test_sel = 2; + test_read[1] = RF->rfif_test_read.value; + + p_test_read = (struct rfc_status_tag*)test_read; + + printf("******************************** [RFC DUMP START] *****************************\r\n"); + printf(" rc_state : %s\r\n", rc_state_str[p_test_read->rf_rc_state]); + printf(" rf_state : %s\r\n", rf_state_str[p_test_read->rf_fsm_state]); + printf(" fsm_pu_lna : %d\r\n", p_test_read->fsm_pu_lna ); + printf(" fsm_pu_rmxgm : %d\r\n", p_test_read->fsm_pu_rmxgm ); + printf(" fsm_pu_rmx : %d\r\n", p_test_read->fsm_pu_rmx ); + printf(" fsm_pu_rbb : %d\r\n", p_test_read->fsm_pu_rbb ); + printf(" fsm_pu_pkdet : %d\r\n", p_test_read->fsm_pu_pkdet ); + printf(" fsm_pu_adc : %d\r\n", p_test_read->fsm_pu_adc ); + printf(" fsm_trsw_en : %d\r\n", p_test_read->fsm_trsw_en ); + printf(" fsm_pu_dac : %d\r\n", p_test_read->fsm_pu_dac ); + printf(" fsm_pu_tosdac : %d\r\n", p_test_read->fsm_pu_tosdac); + printf(" fsm_pu_rxbuf : %d\r\n", p_test_read->fsm_pu_rxbuf ); + printf(" fsm_pu_txbuf : %d\r\n", p_test_read->fsm_pu_txbuf ); + + printf("\r\n\r\n"); + printf(" tx_gain_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.tx_gain_ctrl_hw); + printf(" rx_gain_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.rx_gain_ctrl_hw); + printf(" trxcal_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.trxcal_ctrl_hw); + printf(" lo_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.lo_ctrl_hw); + printf(" lna_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.lna_ctrl_hw); + printf(" pu_ctrl_hw : %ld\r\n", RF->rfctrl_hw_en.pu_ctrl_hw); + + printf("\r\n\r\n"); + printf(" rf_lo_vco_freq_cw_hw : %ld\r\n", RF->vco1.lo_vco_freq_cw_hw); + printf(" rf_lo_vco_idac_cw_hw : %ld\r\n", RF->vco1.lo_vco_idac_cw_hw); + printf(" rf_lo_sdmin_hw : %ld\r\n", RF->sdm3.lo_sdmin_hw); + printf(" rf_ch_ind_wifi : %ld\r\n", RF->rf_fsm_ctrl0.rf_ch_ind_wifi); + + + if (RF->rf_fsm_ctrl_sw.lo_unlocked) { + printf("rf_lo_unlocked_getf = 1\r\n"); + printf("rf_lo_unlocked_getf (after csd reset) = "); + for (int i = 0; i < 8; i++) { + RF->pfdcp.lo_pfd_rst_csd = 1; + wait_us(10); + RF->pfdcp.lo_pfd_rst_csd = 0; + wait_us(10); + printf("%ld", RF->rf_fsm_ctrl_sw.lo_unlocked); + } + printf("\r\n"); + } + else { + printf("rf_lo_unlocked_getf = 0\r\n"); + } + + printf("******************************** [RFC DUMP END] *****************************\r\n"); + +} + +_Bool rfc_config_power_ble(int32_t pwr_dbm) { + int i2 = 0; + if ((uint32_t)pwr_dbm < 16) { + if (pwr_dbm < 4) { + RF->pa1.pa_ib_fix = 1; + RF->pa1.pa_half_on = 1; + RF->pa1.pa_vbcas = 4; + RF->pa1.pa_vbcore = 9; + RF->pa1.pa_etb_en = 0; // weird, this 9 will always be 0 + RF->tmx.tmx_cs = 5; + RF->trx_gain1.gc_tbb = 2; + RF->trx_gain1.gc_tmx = 5; + i2 = pwr_dbm * 4 - 18; + } else { + if (pwr_dbm < 7) { + RF->pa1.pa_ib_fix = 1; + RF->pa1.pa_half_on = 1; + RF->pa1.pa_vbcas = 4; + RF->pa1.pa_vbcore = 9; + RF->pa1.pa_etb_en = 0; // weird, this 9 will always be 0 + RF->tmx.tmx_cs = 5; + RF->trx_gain1.gc_tbb = 2; + RF->trx_gain1.gc_tmx = 7; + i2 = pwr_dbm * 4 - 30; + } else { + if (pwr_dbm < 10) { + RF->pa1.pa_ib_fix = 1; + RF->pa1.pa_half_on = 1; + RF->pa1.pa_vbcas = 4; + + RF->pa1.pa_vbcore = 9; + RF->pa1.pa_etb_en = 0; // weird, this 9 will always be 0 + + RF->tmx.tmx_cs = 5; + RF->trx_gain1.gc_tbb = 3; + RF->trx_gain1.gc_tmx = 7; + i2 = pwr_dbm - 10; + } else { + if (pwr_dbm < 12) { + RF->pa1.pa_ib_fix = 1; + RF->pa1.pa_half_on = 1; + RF->pa1.pa_vbcas = 4; + + RF->pa1.pa_vbcore = 9; + RF->pa1.pa_etb_en = 0; // weird, this 9 will always be 0 + + RF->tmx.tmx_cs = 5; + RF->trx_gain1.gc_tbb = 4; + RF->trx_gain1.gc_tmx = 7; + i2 = pwr_dbm - 12; + } else { + RF->pa1.pa_ib_fix = 1; + RF->pa1.pa_half_on = 1; + RF->pa1.pa_vbcas = 4; + + RF->pa1.pa_vbcore = 9; + RF->pa1.pa_etb_en = 0; // weird, this 9 will always be 0 + + RF->tmx.tmx_cs = 5; + RF->trx_gain1.gc_tbb = 6; + RF->trx_gain1.gc_tmx = 7; + i2 = pwr_dbm - 15; + } + } + i2 = i2 << 2; + } + } + uint32_t u2 = i2 - 1; + RF->dfe_ctrl_18.tx_dvga_gain_qdb_ble_gc0 = u2 & 0x7f; + RF->dfe_ctrl_18.tx_dvga_gain_qdb_ble_gc1 = u2 & 0x7f; + RF->dfe_ctrl_18.tx_dvga_gain_qdb_ble_gc2 = u2 & 0x7f; + } + return 0; +} + + + + +static void _set_rfc(uint32_t xtalfreq_hz) { + xtalfreq_MHz = xtalfreq_hz / 1000000; + float xtal_MHz = xtalfreq_hz / 1000000; + uint32_t lo_center_freq_mhz; + /// _calc_sdm_params + if (xtalfreq_hz == 40000000) { + lo_center_freq_mhz = 2430.0; + } else { + lo_center_freq_mhz = 2448.0; + } + RF->lo_sdm_ctrl_hw5.lo_center_freq_mhz = lo_center_freq_mhz; //??? + uint32_t lo_sdmin_center = _calc_sdm_cw(xtal_MHz, lo_center_freq_mhz); + uint32_t lo_sdmin_1m = _calc_sdm_cw(xtal_MHz, 1.0); + uint32_t lo_sdmin_if = _calc_sdm_cw(xtal_MHz, 1.25); + RF->lo_sdm_ctrl_hw6.lo_sdmin_center = lo_sdmin_center; + RF->lo_sdm_ctrl_hw7.lo_sdmin_1m = lo_sdmin_1m; + RF->lo_sdm_ctrl_hw8.lo_sdmin_if = lo_sdmin_if; + + union { + uint8_t seq[2][2]; + uint32_t val; + } lo_cw = {.val = 0}; + volatile uint32_t *ptr = (volatile uint32_t *)&(RF->lo_cal_ctrl_hw1); + for (int freq = 2404, i = 0; freq <= 2484; freq += 4, i += 1) { + int freq_cw = rf_pri_get_vco_freq_cw(freq); + int idac_cw = rf_pri_get_vco_idac_cw(freq); + if (freq == 2404) freq_cw += 1; + lo_cw.seq[i&1][0] = idac_cw; + lo_cw.seq[i&1][1] = freq_cw; + if ((freq == 2484) || (i&1)) { + *ptr = lo_cw.val; + lo_cw.val = 0; + ptr++; + } + } + + _sync_tx_power_offset(); + + // configure rf_fsm related params + RF->rf_fsm_ctrl_hw.rf_rc_state_dbg_en = 0; + RF->rf_fsm_ctrl2.rf_fsm_st_dbg_en = 0; + RF->rf_fsm_ctrl1.rf_fsm_lo_time = 0x1040; + RF->rf_fsm_ctrl_hw.rf_fsm_ctrl_en = 1; + + // configure tx gain control + RF->rfctrl_hw_en.tx_gain_ctrl_hw = 1; + RF->dfe_ctrl_0.tx_dvga_gain_ctrl_hw = 1; + RF->dfe_ctrl_0.tx_dvga_gain_qdb = 0; + + // configure rf compensation paramas + // turn off trxcal if ROSDAC table changes vs gain to prevent pkdet false triggers + // caused by the transient response of ROSDAC + RF->rfctrl_hw_en.trxcal_ctrl_hw = 1; + + // configure rx gain control + RF->rfctrl_hw_en.rx_gain_ctrl_hw = 1; + +} + +static void _set_mdm() { + AGC->rc218.txhbf20coeffsel = 0; + MDM->r3030 = 0; + MDM->r3034 = 0xa027f7f; + MDM->r3038 = 0x23282317; + MDM->r303c = 0x7f020a17; + MDM->r3040 = 0x7f; +} + + + + + +static void wait_us(uint32_t us) +{ + volatile uint32_t n; + us = (us >= (1<<24)-1) ? (1<<24)-1 : us; + // if (us < 2) { + // return; + // } + // else + { + n = us << 4; + while(n--); + } +} + +__attribute__((unused)) static void wait_ms(uint32_t ms) +{ + wait_us(1000*ms); +} + +static void _set_rfc_powercontrol(uint32_t pc_mode) { + RF->pa1.pa_ib_fix = 0; + RF->tmx.tmx_cs = 6; + switch (pc_mode) { + case RFC_PC_AUTO: + RF->pa_reg_ctrl_hw2.pa_vbcore_11b = 0xf; + RF->pa_reg_ctrl_hw1.pa_vbcore_11n = 0xa; + RF->pa_reg_ctrl_hw2.pa_vbcore_11g = 0xa; + + RF->pa_reg_ctrl_hw2.pa_vbcas_11b = 5; + RF->pa_reg_ctrl_hw1.pa_vbcas_11n = 5; + RF->pa_reg_ctrl_hw2.pa_vbcas_11g = 5; + + RF->pa_reg_ctrl_hw2.pa_iet_11b = 7; + RF->pa_reg_ctrl_hw1.pa_iet_11n = 5; + RF->pa_reg_ctrl_hw2.pa_iet_11g = 5; + case RFC_PC_WLAN_11B: + case RFC_PC_BT_BLE: + RF->pa1.pa_vbcore = 0xf; + RF->pa1.pa_vbcas = 5; + RF->pa1.pa_iet = 7; + break; + case RFC_PC_WLAN_11N: + case RFC_PC_WLAN_11G: + RF->pa1.pa_vbcore = 0xa; + RF->pa1.pa_vbcas = 5; + RF->pa1.pa_iet = 5; + break; + } + RF->trx_gain1.gc_tbb_boost = 0; + RF->trx_gain1.gc_tbb = 6; + RF->trx_gain1.gc_tmx = 5; + RF->adda1.dac_bias_sel = 1; +} + +static void _set_rf_channel_sw(uint32_t channel_freq) { + uint32_t sdmin = (uint32_t)(channel_freq*4.0/3/xtalfreq_MHz*(1<<22)); + + RF->rfctrl_hw_en.lo_ctrl_hw = 0; + RF->rfctrl_hw_en.sdm_ctrl_hw = 0; + RF->pucr1.pu_vco = 1; + RF->pucr1.pu_fbdv = 1; + RF->pucr1.pu_pfd = 1; + RF->pucr1.pu_osmx = 1; + RF->rfctrl_hw_en.pu_ctrl_hw = 0; + + // set channel + // rf_lo_fbdv_halfstep_en_setf(1); + RF->vco1.lo_vco_freq_cw = rf_pri_get_vco_freq_cw(channel_freq); + RF->vco1.lo_vco_idac_cw = rf_pri_get_vco_idac_cw(channel_freq); + RF->lodist.lo_osmx_cap = rf_pri_get_vco_freq_cw(channel_freq) >> 4; + + RF->sdm2.lo_sdmin = sdmin; + RF->sdm1.lo_sdm_bypass = 0; + + // wait channel lock + do { + RF->fbdv.lo_fbdv_rst = 1; + wait_us(10); + RF->fbdv.lo_fbdv_rst = 0; + wait_us(50); + RF->pfdcp.lo_pfd_rst_csd = 1; + wait_us(10); + RF->pfdcp.lo_pfd_rst_csd = 0; + wait_us(50); + } while (0); +} \ No newline at end of file diff --git a/src/bl602_wifi/driver/phyif/phyif_utils.c b/src/bl602_wifi/driver/phyif/phyif_utils.c new file mode 100644 index 0000000..6715d87 --- /dev/null +++ b/src/bl602_wifi/driver/phyif/phyif_utils.c @@ -0,0 +1,56 @@ +#include + +typedef struct { + uint32_t leg_length:12; // +0 + uint32_t leg_rate:4; // +0 + uint32_t ht_length:16; // +0 + uint32_t _ht_length:4; // +4 + uint32_t short_gi:1; // +4 + uint32_t stbc:2; // +4 + uint32_t smoothing:1; // +4 + uint32_t mcs:7; // +4 + uint32_t pre_type:1; // +4 + uint32_t format_mod:3; // +4 + uint32_t ch_bw:2; // +4 + uint32_t n_sts:3; // +4 + uint32_t lsig_valid:1; // +4 + uint32_t sounding:1; // +4 + uint32_t num_extn_ss:2; // +4 + uint32_t aggregation:1; // +4 + uint32_t fec_coding:1; // +4 + uint32_t dyn_bw:1; // +4 + uint32_t doze_not_allowed:1; // +4 + uint32_t antenna_set:8; // +8 + uint32_t partial_aid:9; // +8 + uint32_t group_id:6; // +8 + uint32_t reserved_1c:1; // +8 + int32_t rssi1:8; // +8 + int32_t rssi2:8; // +12 + union { + int32_t rssi34:16; + struct { + int32_t rssi3:8; // +12 + int32_t rssi4:8; // +12 + }; + }; + uint32_t reserved_1d:8; // +12 + uint32_t rcpi:8; // +16 + uint32_t evm1:8; // +16 + uint32_t evm2:8; // +16 + uint32_t evm3:8; // +16 + uint32_t evm4:8; // +20 + uint32_t reserved2b_1:8; // +20 + uint32_t reserved2b_2:8; // +20 + uint32_t reserved2b_3:8; // +20 +} phyif_utils_recvtable_priv_t; // :47:3 + +int phyif_utils_decode(phyif_utils_recvtable_t *vec,int8_t *ppm) { + phyif_utils_recvtable_priv_t* pvec = (phyif_utils_recvtable_priv_t*) vec; + int8_t vppm = 0; + if (pvec->format_mod < 2 && pvec->leg_rate < 4) { + vppm = (int)((double)(-(int)pvec->rssi3) * 0.7); + } else { + vppm = ((int)pvec->rssi34 / 0x7a); + } + *ppm = vppm; +} diff --git a/src/bl602_wifi/driver/sysctrl/sysctrl.c b/src/bl602_wifi/driver/sysctrl/sysctrl.c new file mode 100644 index 0000000..e1a2121 --- /dev/null +++ b/src/bl602_wifi/driver/sysctrl/sysctrl.c @@ -0,0 +1,8 @@ +#include +#include +#include + +void sysctrl_init() { + SYSCTRL->diag_conf.value = 0x8000000c; + SYSCTRL->misc_cntl.set1 = 0x1ff; +} diff --git a/src/bl602_wifi/hal/hal_desc.c b/src/bl602_wifi/hal/hal_desc.c new file mode 100644 index 0000000..e69de29 diff --git a/src/bl602_wifi/hal/hal_dma.c b/src/bl602_wifi/hal/hal_dma.c new file mode 100644 index 0000000..e2fe886 --- /dev/null +++ b/src/bl602_wifi/hal/hal_dma.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct hal_dma_env_tag hal_dma_env; + +const uint8_t dma2chan[2] = {0x2, 0x0}; +const uint8_t dma2lli[2] = {0x9, 0xb}; + +void hal_dma_init(void) { + co_list_init(hal_dma_env.prog + 0); + hal_dma_env.lli_cnt[0] = DMA->LinkListItem0.counter; + co_list_init(hal_dma_env.prog + 1); + hal_dma_env.lli_cnt[1] = DMA->LinkListItem1.counter; +} + +void hal_dma_push(struct hal_dma_desc_tag *desc, int type) { + struct dma_desc *dma_desc = desc->dma_desc; + if (desc->cb == 0) { + dma_desc->ctrl = 0; + } else { + dma_desc->ctrl = ((uint32_t)dma2lli[type] << 8) | 0x1000 | ((uint32_t)dma2lli[type]) | 0x10; + co_list_push_back(hal_dma_env.prog + type, &desc->hdr); + } + memcpy((void *)dma_desc->dest, (void *)dma_desc->src, (uint32_t)dma_desc->length); + evt_field_t event; + if (type == DMA_DL) { + event = KE_EVT_DMA_DL_BIT; + } else { + if (type != DMA_UL) { + do { + vTaskDelay(1000); + puts("[FW] Dead loop when using dma push\r\n"); + } while (true); + } + event = KE_EVT_DMA_UL_BIT; + } + ke_evt_set(event); +} + +void hal_dma_evt(int dma_queue) { + evt_field_t event; + if (dma_queue == DMA_DL) { + event = KE_EVT_DMA_DL_BIT; + } else { + event = KE_EVT_DMA_UL_BIT; + } + ke_evt_clear(event); + struct hal_dma_desc_tag *l; + while (l = (struct hal_dma_desc_tag*)co_list_pop_front(hal_dma_env.prog + dma_queue)) { + if (l->cb != 0) { + l->cb(l->env, dma_queue); + } + } +} diff --git a/src/bl602_wifi/hal/hal_machw.c b/src/bl602_wifi/hal/hal_machw.c new file mode 100644 index 0000000..e69de29 diff --git a/src/bl602_wifi/hal/hal_mib.c b/src/bl602_wifi/hal/hal_mib.c new file mode 100644 index 0000000..e69de29 diff --git a/src/bl602_wifi/ip/lmac/bl/bl.c b/src/bl602_wifi/ip/lmac/bl/bl.c new file mode 100644 index 0000000..af4dba5 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/bl/bl.c @@ -0,0 +1,143 @@ +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + +struct bl_env_tag bl_env; +static struct notifier_block *fw_nap_chain_ptr; +struct notifier_block fw_nap_chain; + +extern void supplicantFuncInit(void); /// from bl_supplicant.c + +void bl_init(void) { + fw_nap_chain_ptr = &fw_nap_chain; + bl_env.hw_in_doze = 0; + dbg_init(); + me_init(); + mm_init(); + ke_init(); + memset(&sta_conn_info, 0, 0xec); + sta_conn_info.ptkHwKeyId = sta_conn_info.mfpHwKeyId = 0xff; + sta_conn_info.conType = 0; + sta_conn_info.gtkHwKeyId = 0xff; + supplicantFuncInit(); + allocSupplicantData(&sta_conn_info); +} + +void bl_reset_evt(int dummy) { + __disable_irq(); + ke_evt_clear(KE_EVT_RESET_BIT); + hal_machw_reset(); + rxl_reset(); + txl_reset(); + mm_reset(); + vif_mgmt_reset(); + __enable_irq(); +} + +int bl_sleep(void) { + // fun fact, this function is not going to + // put anything into sleep. + if (ke_evt_get()) return false; + if (ke_state_get(TASK_SCANU) == 0) { + if (!ps_sleep_check()) + return false; + if (txl_cntrl_env.pck_cnt == 0) { + return hal_machw_sleep_check(); + } + } + return false; +} + +void bl_wakeup(void) { + if (bl_env.hw_in_doze != 0) { + // okay, bl_env.hw_in_doze is always zero + MAC_PL->GEN_INT_ENABLE.masterGenIntEn = 0; + MAC_PL->DOZE_CNTRL_2.wakeUpFromDoze = 1; + bl_env.hw_in_doze = 0; + for (; MAC_PL->GEN_INT_STATUS.idleInterrupt == 0;); + MAC_PL->GEN_INT_ACK.value = 4; + MAC_PL->GEN_INT_ENABLE.masterGenIntEn = 1; + if (bl_env.prev_hw_state != HW_IDLE) { + ASSERT_ERR((bl_env.prev_hw_state & (~0xf)) == 0); + MAC_CORE->STATE_CNTRL.value = ((uint32_t)bl_env.prev_hw_state) << 4; + for (; bl_env.prev_hw_state != MAC_CORE->STATE_CNTRL.currentState; ); + } + MAC_PL->DOZE_CNTRL_2.wakeUpFromDoze = 0; + } +} + +uint32_t bl_nap_calculate(void) { + uint32_t unmask = MAC_PL->TIMERS_INT_UN_MASK.value; + // only used timer 0 - 8? + uint32_t nap_time = 0xffffffff; + for (int i = 0; i < 9; i++) { + if ((1 << i) & unmask) { + // timer i in use + uint32_t tick = MAC_CORE->ABS_TIMER[i]; + uint32_t now = hal_machw_time(); + if (now < tick) { + tick = tick - now; + } else { + tick = (now - 1) - tick; + } + if (tick < nap_time) { + nap_time = tick; + } + } + } + return nap_time; +} + +int bl_nap_call(uint32_t time) { + return 0; +} + +int bl_nap_hook_register(struct notifier_block *nb) { + notifier_chain_regsiter(&fw_nap_chain_ptr, nb); + return 0; +} + +int bl_nap_hook_register_fromCritical(struct notifier_block *nb) { + notifier_chain_regsiter_fromCritical(&fw_nap_chain_ptr, nb); + return 0; +} + +int bl_nap_hook_unregister(struct notifier_block *nb) { + notifier_chain_unregsiter(&fw_nap_chain_ptr, nb); + return 0; +} + +int bl_nap_hook_unregister_fromCritical(struct notifier_block *nb) { + notifier_chain_unregsiter_fromCritical(&fw_nap_chain_ptr, nb); + return 0; +} + +int bl_nap_hook_call(int event, void *env) { + notifier_chain_call(&fw_nap_chain_ptr, event, env); + return 0; +} + +int bl_nap_hook_call_fromCritical(int event, void *env){ + notifier_chain_call_fromeCritical(&fw_nap_chain_ptr, event, env); + return 0; +} diff --git a/src/bl602_wifi/ip/lmac/chan/chan.c b/src/bl602_wifi/ip/lmac/chan/chan.c new file mode 100644 index 0000000..dea57d0 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/chan/chan.c @@ -0,0 +1,1000 @@ +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include +#include + +struct chan_env_tag chan_env; +struct chan_ctxt_tag chan_ctxt_pool[CHAN_CHAN_CTXT_CNT]; + +static void chan_switch_start(struct chan_ctxt_tag *p_chan_entry); +static void chan_switch_channel(void); +static void chan_pre_switch_channel(void); + +static uint16_t chan_get_nb_slots(uint32_t time1, uint32_t time2) { + // Get time difference in us + int32_t diff = time1 - time2; + // Return time difference in slots + return (int16_t)(diff / CHAN_SLOT_DURATION_US); +} + +static uint16_t chan_get_nb_avail_slots(struct chan_ctxt_tag *p_chan_entry) { + if (p_chan_entry->nb_res_slots < p_chan_entry->nb_rem_slots) { + return (p_chan_entry->nb_rem_slots - p_chan_entry->nb_res_slots); + } + return 0; +} + +static struct chan_ctxt_tag *chan_get_next_chan(void) { + struct chan_tbtt_tag * p_tbtt_entry = (struct chan_tbtt_tag *)co_list_pick(&chan_env.list_tbtt); + struct chan_ctxt_tag * p_next_chan_entry = chan_env.current_channel; + uint32_t now = ke_time(); + if (chan_env.current_channel) { + if (p_tbtt_entry && p_tbtt_entry->status == CHAN_TBTT_PRESENCE) { + return chan_env.current_channel; + } + if (!hal_machw_time_cmp(now + (CHAN_MIN_PRES_DUR * CHAN_SLOT_DURATION_US), chan_env.tmr_cde.time)) { + return chan_env.current_channel; + } + if (chan_env.current_channel->status == CHAN_ENV_DELAY_PROG_BIT) { + return chan_env.current_channel; + } + } + + if (p_tbtt_entry && hal_machw_time_cmp(p_tbtt_entry->time, chan_env.tmr_cde.time)) { + p_next_chan_entry = vif_info_tab[p_tbtt_entry->vif_index].chan_ctxt; + ASSERT_ERR(p_next_chan_entry); + if (!hal_machw_time_cmp(now + (CHAN_MIN_PRES_DUR * CHAN_SLOT_DURATION_US), p_tbtt_entry->time)) { + return p_next_chan_entry; + } + uint32_t avail_slots = chan_get_nb_avail_slots(p_next_chan_entry); + if (chan_get_nb_slots(p_tbtt_entry->time, now) <= avail_slots) { + return p_next_chan_entry; + } + } + uint32_t remain_slot = 0; + for (int i = 0; i < CHAN_TRAF_CTXT_CNT; i++) { + if (chan_ctxt_pool[i].status != CHAN_NOT_SCHEDULED && remain_slot <= chan_ctxt_pool[i].nb_rem_slots) { + p_next_chan_entry = chan_ctxt_pool + i; + remain_slot = p_next_chan_entry->nb_rem_slots; + } + } + + ASSERT_ERR(p_next_chan_entry); + return p_next_chan_entry; +} + +// in the reversed code, here they used a pointer to &(p_chan_entry->nb_rem_slots) rather than +// p_chan_entry +static void chan_upd_nb_rem_slots(struct chan_ctxt_tag *p_chan_entry, uint32_t current_time) { + uint8_t nb_slots = chan_get_nb_slots(current_time, chan_env.cde_time); + p_chan_entry->nb_rem_slots -= co_min(nb_slots, p_chan_entry->nb_rem_slots); +} + +static void chan_upd_ctxt_status(struct chan_ctxt_tag *p_chan_entry, uint8_t next_status) { + uint32_t now = ke_time(); + uint32_t tmr_exp_time = 0; + if (next_status == CHAN_GOTO_IDLE) { + if (p_chan_entry->idx < CHAN_TRAF_CTXT_CNT) + tmr_exp_time = now + CHAN_SWITCH_TO_DUR; + } else { + if (next_status == CHAN_WAITING_END) { + if (p_chan_entry->idx < CHAN_TRAF_CTXT_CNT) { + if (chan_env.nb_sched_ctxt > 1) { + // >= 2 + uint32_t avail_slots = chan_get_nb_avail_slots(p_chan_entry); + if (avail_slots < CHAN_MIN_PRES_DUR) { + next_status = CHAN_PRESENT; + } else { + chan_env.cde_time = now; + tmr_exp_time = now + (avail_slots * CHAN_SLOT_DURATION_US); + } + } else { + // 0, 1 + next_status = CHAN_PRESENT; + } + } else { + tmr_exp_time = now + (p_chan_entry->nb_rem_slots * CHAN_SLOT_DURATION_US); + } + + } + } + p_chan_entry->status = next_status; + if (tmr_exp_time != 0) { + chan_env.tmr_ctxt_op.env = p_chan_entry; + mm_timer_set(&chan_env.tmr_ctxt_op, tmr_exp_time); + } else { + if (next_status != CHAN_WAIT_NOA_CFM) { + mm_timer_clear(&chan_env.tmr_ctxt_op); + } + } +} + +static void chan_update_reserved_slots(struct vif_info_tag *p_vif_entry, struct chan_ctxt_tag *p_chan_entry) { + uint32_t bcn_int; + if (p_vif_entry->type == VIF_STA) { + bcn_int = sta_info_tab[p_vif_entry->u.sta.ap_id].bcn_int; + } else { + bcn_int = ((uint32_t)p_vif_entry->u.ap.bcn_int) << 10; + } + uint8_t nb_tbtt = co_max(1, (chan_env.cde_dur_us / bcn_int)); + p_chan_entry->nb_res_slots += nb_tbtt * CHAN_MAX_TBTT_PRES_DUR; +} + +static void chan_distribute_slots(void) { + struct vif_info_tag *p_vif_entry = vif_mgmt_first_used(); + uint8_t nb_vifs = 0; + uint8_t nb_vif_busy = 0; + uint8_t nb_slots_alloc_busy_additional = 0; + uint8_t nb_slots_alloc_Nbusy = 0; + for (struct chan_ctxt_tag *p_chan_entry; p_vif_entry; p_vif_entry = vif_mgmt_next(p_vif_entry)) { + p_chan_entry = p_vif_entry->chan_ctxt; + if (p_chan_entry) { + nb_vifs++; + if ((td_get_status(p_vif_entry->index)) || (p_vif_entry->active == false)) { + nb_vif_busy++; + } + p_chan_entry->nb_slots = 0; + p_chan_entry->nb_res_slots = 0; + } + } + + ASSERT_WARN(nb_vifs == (chan_env.cde_dur_us / (CHAN_VIF_NB_SLOTS * CHAN_SLOT_DURATION_US))); + + if (nb_vif_busy == 0 || (nb_vif_busy == nb_vifs)) { + nb_slots_alloc_Nbusy = CHAN_VIF_NB_SLOTS; + nb_slots_alloc_busy_additional = 0; + } else { + nb_slots_alloc_Nbusy = CHAN_MAX_TBTT_PRES_DUR; + nb_slots_alloc_busy_additional = ((nb_vifs - nb_vif_busy) * (CHAN_VIF_NB_SLOTS - CHAN_MAX_TBTT_PRES_DUR)) / nb_vif_busy; + } + + p_vif_entry = vif_mgmt_first_used(); + for (struct chan_ctxt_tag *p_chan_entry; p_vif_entry; p_vif_entry = vif_mgmt_next(p_vif_entry)) { + p_chan_entry = p_vif_entry->chan_ctxt; + if (p_chan_entry) { + if ((td_get_status(p_vif_entry->index)) || (p_vif_entry->active == false)) { + p_chan_entry->nb_slots += nb_slots_alloc_busy_additional + CHAN_VIF_NB_SLOTS; + } else { + p_chan_entry->nb_slots += nb_slots_alloc_Nbusy; + } + p_chan_entry->nb_rem_slots = p_chan_entry->nb_slots; + chan_update_reserved_slots(p_vif_entry, p_chan_entry); + } + } +} + +static void chan_conn_less_delay_prog(void) { + chan_env.status |= CO_BIT(CHAN_ENV_DELAY_PROG_BIT); + mm_timer_set(&chan_env.tmr_conn_less, ke_time() + CHAN_CONN_LESS_DELAY); +} + +static void chan_notify_presence(void) { + struct vif_info_tag *p_vif_entry = vif_mgmt_first_used(); + struct chan_ctxt_tag *p_cur_ctxt = chan_env.current_channel; + if ((ps_env.ps_on) && !(ps_env.prevent_sleep & PS_PSM_PAUSED)) + return ; + MAC_CORE->MAC_CNTRL_1.pwrMgt = 0; + for (; p_vif_entry; p_vif_entry = vif_mgmt_next(p_vif_entry)) { + if ((p_cur_ctxt == p_vif_entry->chan_ctxt) && (p_vif_entry->type == VIF_STA) && (p_vif_entry->active == true)) { + txl_frame_send_null_frame(p_vif_entry->u.sta.ap_id, 0, 0); + } + } +} + +static void chan_switch_channel(void) { + struct chan_ctxt_tag *p_chan_entry = chan_env.chan_switch; + phy_set_channel((p_chan_entry->channel).band,(p_chan_entry->channel).type, + (p_chan_entry->channel).prim20_freq, + (p_chan_entry->channel).center1_freq, + (p_chan_entry->channel).center2_freq, PHY_PRIM); + tpc_update_tx_power((p_chan_entry->channel).tx_power); + MAC_CORE->RATES.value = 0x10; // or mm_env.basic_rates[param->band]? + // chan_send_switch_ind(p_chan_entry); ? not exists?? + chan_env.current_channel = p_chan_entry; + chan_env.chan_switch = 0x0; + + chan_upd_ctxt_status(p_chan_entry, CHAN_WAITING_END); + + if (p_chan_entry->idx != CHAN_SCAN_CTXT_IDX) { + if (p_chan_entry->idx != CHAN_ROC_CTXT_IDX) { + chan_notify_presence(); + } + if (p_chan_entry->idx < CHAN_TRAF_CTXT_CNT) { + for (struct vif_info_tag* p_vif_entry = vif_mgmt_first_used(); p_vif_entry; p_vif_entry = vif_mgmt_next(p_vif_entry)) { + if (p_chan_entry == p_vif_entry->chan_ctxt) { + td_env[p_vif_entry->index].has_active_chan = true; + vif_mgmt_send_postponed_frame(p_vif_entry); + } + } + // a + } + } else { + MAC_CORE->EDCA_CCA_BUSY.ccaBusyDur = 0; + ke_msg_send_basic(MM_SCAN_CHANNEL_START_IND, TASK_SCAN, TASK_NONE); + // a + } + + if (p_chan_entry->idx >= CHAN_SCAN_CTXT_IDX) { + // a + __disable_irq(); + ps_env.prevent_sleep = ps_env.prevent_sleep | PS_SCAN_ONGOING; + __enable_irq(); + chan_env.pm = MAC_CORE->MAC_CNTRL_1.pwrMgt; + MAC_CORE->MAC_CNTRL_1.pwrMgt = 0; + } + + mm_active(); +} + +static void chan_tx_cfm(void *dummy, uint32_t status) { + ASSERT_ERR(chan_env.cfm_cnt); + chan_env.cfm_cnt --; + if (chan_env.cfm_cnt == 0) { + mm_force_idle_req(); + chan_pre_switch_channel(); + } +} + +static int chan_notify_absence(void) { + if (!chan_env.current_channel) + return 0; + struct chan_ctxt_tag *cur = chan_env.current_channel; + if (ps_env.ps_on && !(ps_env.prevent_sleep & PS_PSM_PAUSED)) + return 0; + int cnt = 0; + MAC_CORE->MAC_CNTRL_1.pwrMgt = 1; + for (struct vif_info_tag *p_vif_entry = vif_mgmt_first_used(); p_vif_entry; vif_mgmt_next(p_vif_entry)) { + if (p_vif_entry->chan_ctxt == cur) { + if ( (p_vif_entry->type == VIF_STA) && p_vif_entry->active && + (p_vif_entry->u.sta.ap_id != INVALID_STA_IDX)) { + uint8_t status = cur->status; + cur->status = CHAN_SENDING_NOA; + if (txl_frame_send_null_frame(p_vif_entry->u.sta.ap_id, chan_tx_cfm, (void *)0x0) == 0) + cnt++; + cur->status = status; + } + } + } + chan_env.cfm_cnt = cnt; + if (cnt) { + chan_upd_ctxt_status(chan_env.chan_switch, CHAN_WAIT_NOA_CFM); + mm_active(); + } + return cnt; +} + +static void chan_cde_evt(void *env) { + uint32_t now = ke_time(); + struct chan_ctxt_tag * p_chan_entry = chan_env.chan_switch; + if (chan_env.nb_sched_ctxt > 1) { + if (!(chan_env.status & (CO_BIT(CHAN_ENV_ROC_BIT) | CO_BIT(CHAN_ENV_SCAN_BIT) | CO_BIT(CHAN_ENV_TIMEOUT_BIT)))) { + mm_timer_set(&chan_env.tmr_cde, chan_env.cde_dur_us + now); + chan_env.cde_time = now; + + chan_distribute_slots(); + + if (chan_env.current_channel) { + chan_upd_ctxt_status(chan_env.current_channel, CHAN_NOT_PROG); + } + + p_chan_entry = chan_get_next_chan(); + + if (!env) { + chan_switch_start(p_chan_entry); + } else { + chan_env.chan_switch = p_chan_entry; + } + } + } +} + +static void chan_pre_switch_channel(void) { + mm_timer_clear(&chan_env.tmr_ctxt_op); + if (chan_env.status & CO_BIT(CHAN_ENV_TIMEOUT_BIT)) { + if ((chan_env.nb_sched_ctxt >= 2) && (chan_env.chan_switch)) { + chan_env.chan_switch->status = CHAN_NOT_PROG; + chan_env.chan_switch = 0; + } + chan_env.status &= ~CO_BIT(CHAN_ENV_TIMEOUT_BIT); + } + struct chan_ctxt_tag *p_new_chan_switch = NULL; + if (chan_env.status & CO_BIT(CHAN_ENV_SCAN_BIT)) { + p_new_chan_switch = chan_ctxt_pool + CHAN_SCAN_CTXT_IDX; + } else if (chan_env.status & CO_BIT(CHAN_ENV_ROC_BIT)) { + p_new_chan_switch = chan_ctxt_pool + CHAN_ROC_CTXT_IDX; + } + if (p_new_chan_switch) { + if (chan_env.chan_switch) { + chan_env.chan_switch->status = CHAN_NOT_PROG; + } + chan_env.chan_switch = p_new_chan_switch; + } + if (!chan_env.chan_switch) { + if (chan_env.nb_sched_ctxt >= 2) { + chan_cde_evt((void *)1); + } else if (chan_env.nb_sched_ctxt == 1) { + chan_env.chan_switch = (struct chan_ctxt_tag *)co_list_pick(&chan_env.list_sched_ctxt); + } + } + if (chan_env.chan_switch) + chan_switch_channel(); +} + +static void chan_goto_idle_cb(void) { + mm_force_idle_req(); + struct vif_info_tag *p_vif_entry = vif_mgmt_first_used(); + + if (chan_env.current_channel && ((chan_env.status & CO_BIT(CHAN_ENV_TIMEOUT_BIT)) == 0)) { + if (chan_notify_absence()) return ; + } + chan_pre_switch_channel(); +} + +static void chan_send_force_idle(void) { + struct mm_force_idle_req *req = (struct mm_force_idle_req *)ke_msg_alloc(MM_FORCE_IDLE_REQ, TASK_MM, TASK_NONE, sizeof(struct mm_force_idle_req)); + req->cb = chan_goto_idle_cb; + ke_msg_send(req); +} + +static void chan_switch_start(struct chan_ctxt_tag *p_chan_entry) { + if (chan_env.current_channel == p_chan_entry) { + if ((chan_env.nb_sched_ctxt > 1) && (p_chan_entry->idx < CHAN_TRAF_CTXT_CNT)) { + chan_upd_ctxt_status(p_chan_entry, CHAN_WAITING_END); + } + } else { + if (chan_env.chan_switch == 0) { + // if (chan_env.current_channel) chan_send_pre_switch_ind(chan_env.current_channel); + // ^^ not used + chan_env.chan_switch = p_chan_entry; + chan_upd_ctxt_status(p_chan_entry, CHAN_GOTO_IDLE); + chan_send_force_idle(); + } + } +} + +static void chan_conn_less_delay_evt(void *env) { + struct chan_ctxt_tag * p_chan_entry = 0; + if (!(chan_env.status & CO_BIT(CHAN_ENV_ROC_WAIT_BIT))) { + if (!(chan_env.status & CO_BIT(CHAN_ENV_SCAN_WAIT_BIT))) { + return ; + } + ASSERT_ERR((chan_env.status & CO_BIT(CHAN_ENV_SCAN_BIT)) == 0); + p_chan_entry = chan_ctxt_pool + CHAN_SCAN_CTXT_IDX; + chan_env.status = chan_env.status & ~CO_BIT(CHAN_ENV_SCAN_WAIT_BIT) | CO_BIT(CHAN_ENV_SCAN_BIT); + } else { + ASSERT_ERR((chan_env.status & CO_BIT(CHAN_ENV_ROC_BIT)) == 0); + p_chan_entry = chan_ctxt_pool + CHAN_ROC_CTXT_IDX; + chan_env.status = chan_env.status & ~CO_BIT(CHAN_ENV_ROC_WAIT_BIT) | CO_BIT(CHAN_ENV_ROC_BIT); + } + if (!chan_env.chan_switch) { + chan_switch_start(p_chan_entry); + } +} + +static void chan_send_survey_ind(void) { + // not used + __builtin_trap(); + return ; +} + +static void chan_send_roc_exp_ind(struct chan_ctxt_tag *roc_chan_ctxt) { + // not used + __builtin_trap(); + return ; +} + +static void chan_ctxt_op_evt(void *env) { + struct chan_ctxt_tag *p_chan_entry = (struct chan_ctxt_tag *)env; + uint32_t current_time; + switch (p_chan_entry->status) { + // >1 + // < 4 + // 2,3 + case CHAN_GOTO_IDLE: + case CHAN_WAIT_NOA_CFM: + chan_env.status = chan_env.status | CO_BIT(CHAN_ENV_TIMEOUT_BIT); + break; + // == 4 + case CHAN_WAITING_END: + if (p_chan_entry->idx < CHAN_TRAF_CTXT_CNT) { + p_chan_entry->status = CHAN_NOT_PROG; + if (chan_env.nb_sched_ctxt == 1) { + p_chan_entry = (struct chan_ctxt_tag *)co_list_pick(&chan_env.list_sched_ctxt); + } else if (chan_env.nb_sched_ctxt > 1) { + current_time = ke_time(); + chan_upd_nb_rem_slots(p_chan_entry, current_time); + chan_env.cde_time = current_time; + p_chan_entry = chan_get_next_chan(); + } + chan_switch_start(p_chan_entry); + } else { + __disable_irq(); + ps_env.prevent_sleep = ps_env.prevent_sleep & ~PS_SCAN_ONGOING; + __enable_irq(); + MAC_CORE->MAC_CNTRL_1.pwrMgt = chan_env.pm; + chan_env.current_channel = NULL; + if (p_chan_entry->idx == CHAN_SCAN_CTXT_IDX) { + chan_env.status &= ~CO_BIT(CHAN_ENV_SCAN_BIT); + ke_msg_send_basic(MM_SCAN_CHANNEL_END_IND, TASK_SCAN, TASK_NONE); + } else if (p_chan_entry->idx == CHAN_ROC_CTXT_IDX) { + if (p_chan_entry->taskid == TASK_MM) { + chan_env.status &= ~CO_BIT(CHAN_ENV_BCN_DETECT_BIT); + } + chan_env.status &= ~CO_BIT(CHAN_ENV_ROC_BIT); + } + + p_chan_entry->idx = CHAN_CTXT_UNUSED; + + if ((chan_env.status & (CO_BIT(CHAN_ENV_ROC_WAIT_BIT) | CO_BIT(CHAN_ENV_SCAN_WAIT_BIT))) == 0) { + chan_env.status &= ~CO_BIT(CHAN_ENV_DELAY_PROG_BIT); + } else { + chan_conn_less_delay_prog(); + } + if (chan_env.nb_sched_ctxt == 1) + chan_switch_start(p_chan_entry); + else { + if (chan_env.nb_sched_ctxt != 1) { + if (chan_env.nb_sched_ctxt > 1) { + chan_cde_evt(NULL); + return ; + } + mm_force_idle_req(); + mm_back_to_host_idle(); + return ; + } + } + } + default: + break; + } +} + +static void chan_send_pre_switch_ind(struct chan_ctxt_tag *old_chan_ctxt) { + // not used + __builtin_trap(); + return ; +} + +static void chan_send_switch_ind(struct chan_ctxt_tag *new_chan_ctxt) { + // not used + __builtin_trap(); + return ; +} + +static bool chan_tbtt_detect_conflict(uint32_t time2, uint32_t time1) { + // check [time2, time1+P] not overlay with [time1, time1+P] + bool conflict; + uint32_t start1, start2, end1, end2; + + start1 = time2; + start2 = time1; + end1 = (start1 + CHAN_MAX_TBTT_PRES_DUR * CHAN_SLOT_DURATION_US); + end2 = (start2 + CHAN_MAX_TBTT_PRES_DUR * CHAN_SLOT_DURATION_US); + + if ((!hal_machw_time_cmp(start1, start2) && !hal_machw_time_cmp(end2, start1)) || + (!hal_machw_time_cmp(start2, start1) && !hal_machw_time_cmp(end1, start2))) { + conflict = true; + } else { + conflict = false; + } + return conflict; +} + + +static void chan_tbtt_switch_evt(void *env) { + struct chan_tbtt_tag *p_tbtt_entry = (struct chan_tbtt_tag *)env; + uint32_t current_time = ke_time(); + if ((chan_env.nb_sched_ctxt >= 2) && ((chan_env.status & (CO_BIT(CHAN_ENV_ROC_BIT) | CO_BIT(CHAN_ENV_SCAN_BIT))) == 0)) { + struct chan_ctxt_tag *p_chan_entry = vif_info_tab[p_tbtt_entry->vif_index].chan_ctxt; + if ((chan_env.chan_switch == NULL) || (chan_env.chan_switch == p_chan_entry)) { + p_tbtt_entry->priority = 0; + chan_upd_nb_rem_slots(chan_env.current_channel, current_time); + p_chan_entry->nb_res_slots -= co_max(CHAN_MAX_TBTT_PRES_DUR, p_chan_entry->nb_res_slots); + chan_env.cde_time = current_time; + p_tbtt_entry->status = CHAN_TBTT_PRESENCE; + if (!chan_env.chan_switch) { + chan_switch_start(p_chan_entry); + } + } + } +} + +static void chan_tbtt_delay(struct chan_tbtt_tag *p_tbtt_entry) { + uint32_t bcn_int; + struct vif_info_tag *p_vif_entry = vif_info_tab + p_tbtt_entry->vif_index; + if (p_vif_entry->type == VIF_STA) { + bcn_int = sta_info_tab[p_vif_entry->u.sta.ap_id].bcn_int; + } else { + bcn_int = ((uint32_t)p_vif_entry->u.ap.bcn_int) << 10; + } + + p_tbtt_entry->time += bcn_int; + + if (p_tbtt_entry->priority < CHAN_TBTT_PRIORITY_MAX) { + p_tbtt_entry->priority++; + } +} + +///// +/// Find a location in list_tbtt that p_tbtt_entry can be inserted +/// 1) p_tbtt_entry is sorted decending by time, need to find the +/// largest possible i s.t. where p_tbtt_entry.time < list[i].time +/// 2) p_tbtt_entry should not conflict with higher priority elements +/// in the list. +/// 3) If p_tbtt_entry confilcts with elements with lower pri, +/// they should be moved in the delay list +/// they should be successive in the list +static void chan_tbtt_insert(struct chan_tbtt_tag *p_tbtt_entry) { + struct co_list *list_tbtt = &chan_env.list_tbtt; + struct chan_tbtt_tag *p_elem = (struct chan_tbtt_tag *)co_list_pick(list_tbtt); + bool insert = true; + // last item that is not conflict with p_tbtt_entry, and has smallest possible time + struct chan_tbtt_tag *p_prev_elem = NULL; + struct chan_tbtt_tag *p_delay_elem = NULL; + uint8_t nb_delayed = 0; + for (; p_elem; p_elem = (struct chan_tbtt_tag *) co_list_next(&p_elem->list_hdr)) { + ASSERT_ERR(p_elem != p_tbtt_entry); + uint32_t time2 = p_tbtt_entry->time; + uint32_t time1 = p_elem->time; + + if (p_elem->status != CHAN_TBTT_PRESENCE) { + if (chan_tbtt_detect_conflict(time2, time1) == 0){ + if (time2 < time1) break; + p_prev_elem = p_elem; + } else { + if (p_tbtt_entry->priority <= p_elem->priority) { + insert = false; + p_delay_elem = p_tbtt_entry; + nb_delayed = 1; + break; + } else { + if (!p_delay_elem) { + p_delay_elem = p_elem; + } + nb_delayed ++; + } + } + } else { + if ((time2 < time1) || chan_tbtt_detect_conflict(time2, time1)) { + insert = false; + p_delay_elem = p_tbtt_entry; + nb_delayed = 1; + } else p_prev_elem = p_elem; + } + } + + // it seems that all events in list_tbtt are sorted descending so + // it can insert a range from the first p_delay_elem + // to p_delay_elem + nb_delayed + for (int i = 0; i < nb_delayed; i++) { + ASSERT_ERR(p_delay_elem); + if (p_delay_elem != p_tbtt_entry) { + if (p_delay_elem->status == CHAN_TBTT_PROG) { + mm_timer_clear(&chan_env.tmr_tbtt_switch); + p_delay_elem->status = CHAN_TBTT_NOT_PROG; + } + co_list_extract(list_tbtt, &p_delay_elem->list_hdr); + } + // in case of event can't insert, p_tbtt_entry will be put into the delay list + // otherwise the later insert will put it into list_tbtt + co_list_push_back(&chan_env.list_tbtt_delay, &p_delay_elem->list_hdr); + p_delay_elem = (struct chan_tbtt_tag *)co_list_next(&p_delay_elem->list_hdr); + } + + if (insert) { + co_list_insert_after(&chan_env.list_tbtt, &p_prev_elem->list_hdr, &p_tbtt_entry->list_hdr); + } +} + +static void chan_tbtt_schedule(struct chan_tbtt_tag *p_tbtt_entry) { + if (p_tbtt_entry) { + chan_tbtt_insert(p_tbtt_entry); + while (!co_list_is_empty(&chan_env.list_tbtt_delay)) { + struct chan_tbtt_tag *p_delay_elem = (struct chan_tbtt_tag *)co_list_pop_front(&chan_env.list_tbtt_delay); + chan_tbtt_delay(p_delay_elem); + chan_tbtt_insert(p_delay_elem); + } + } + + struct chan_tbtt_tag *first_elem = (struct chan_tbtt_tag *)co_list_pick(&chan_env.list_tbtt); + if (first_elem && (first_elem->status == CHAN_TBTT_NOT_PROG)) { + if (hal_machw_time_cmp(first_elem->time, ke_time() + CHAN_MIN_TIMER_VALUE)) { + chan_tbtt_switch_evt(chan_env.list_tbtt.first); + } else { + chan_env.tmr_tbtt_switch.env = first_elem; + first_elem->status = CHAN_TBTT_PROG; + mm_timer_set(&chan_env.tmr_tbtt_switch, first_elem->time); + } + } +} + +static bool chan_check_chan(const struct mm_chan_ctxt_add_req *p_add_req, uint8_t *p_idx) { + for (int i = 0; i < CHAN_TRAF_CTXT_CNT; i++) { + if (chan_ctxt_pool[i].idx != CHAN_CTXT_UNUSED) { + if (!memcmp(p_add_req, &(chan_ctxt_pool[i].channel), offsetof(struct mm_chan_ctxt_add_req, tx_power))) { + *p_idx = i; + return true; + } + } + } + return false; +} + +static void chan_ctxt_init(struct chan_ctxt_tag *p_chan_entry) { + // Reset the channel information + memset(p_chan_entry, 0, sizeof(struct chan_ctxt_tag)); + + p_chan_entry->taskid = TASK_NONE; + p_chan_entry->idx = CHAN_CTXT_UNUSED; +} + +void chan_init(void) { + memset(&chan_env, 0, sizeof(chan_env)); + + for (int i = 0; i < CHAN_CHAN_CTXT_CNT; i++) { + struct chan_ctxt_tag *p_chan_entry = chan_ctxt_pool + i; + + chan_ctxt_init(p_chan_entry); + + if (i < NX_CHAN_CTXT_CNT) { + co_list_push_back(&chan_env.list_free_ctxt, &p_chan_entry->list_hdr); + } else if (i == CHAN_SCAN_CTXT_IDX) { + p_chan_entry->channel.center2_freq = 0; + p_chan_entry->channel.type = PHY_CHNL_BW_20; + } + } + + // Set TBTT Switch Timer callback + chan_env.tmr_tbtt_switch.cb = chan_tbtt_switch_evt; + // Set Channel Distribution Event Timer callback and environment + chan_env.tmr_cde.cb = chan_cde_evt; + chan_env.tmr_cde.env = 0; + // Set Channel Switch Timer callback + chan_env.tmr_ctxt_op.cb = chan_ctxt_op_evt; + // Set Connection Less Delay Time callback + chan_env.tmr_conn_less.cb = chan_conn_less_delay_evt; +} + +void chan_scan_req(uint8_t band, uint16_t freq, int8_t pwr, uint32_t duration_us, uint8_t vif_index) { + // Get channel context used for Scan + struct chan_ctxt_tag *p_scan_chan = chan_ctxt_pool + CHAN_SCAN_CTXT_IDX; + + ASSERT_ERR(p_scan_chan->idx == CHAN_CTXT_UNUSED); + + p_scan_chan->idx = CHAN_SCAN_CTXT_IDX; + p_scan_chan->taskid = TASK_NONE; + p_scan_chan->status = CHAN_NOT_PROG; + p_scan_chan->nb_rem_slots = duration_us / CHAN_SLOT_DURATION_US; + + p_scan_chan->channel.band = band; + p_scan_chan->channel.prim20_freq = freq; + p_scan_chan->channel.center1_freq = freq; + p_scan_chan->channel.tx_power = pwr; + p_scan_chan->vif_index = vif_index; + + chan_env.status |= CO_BIT(CHAN_ENV_SCAN_WAIT_BIT); + + if ((chan_env.status & CO_BIT(CHAN_ENV_DELAY_PROG_BIT)) == 0) + chan_conn_less_delay_prog(); +} + +uint8_t chan_roc_req(const struct mm_remain_on_channel_req *req, ke_task_id_t taskid) { + struct chan_ctxt_tag *p_roc_chan = chan_ctxt_pool + CHAN_ROC_CTXT_IDX; + switch (req->op_code) { + case MM_ROC_OP_START: + if (p_roc_chan->idx == CHAN_CTXT_UNUSED) { + p_roc_chan->idx = CHAN_ROC_CTXT_IDX; + p_roc_chan->channel.band = req->band; + p_roc_chan->channel.type = req->type; + p_roc_chan->channel.prim20_freq = req->prim20_freq; + p_roc_chan->channel.center1_freq = req->center1_freq; + p_roc_chan->channel.center2_freq = req->center2_freq; + p_roc_chan->status = CHAN_NOT_PROG; + p_roc_chan->nb_rem_slots = (uint16_t)(req->duration_ms * 1000 >> 10); + p_roc_chan->vif_index = req->vif_index; + p_roc_chan->channel.tx_power = req->tx_power; + p_roc_chan->taskid = taskid; + if (taskid == TASK_MM) { + chan_env.status |= CO_BIT(CHAN_ENV_ROC_BIT); + if (!chan_env.chan_switch) { + chan_switch_start(p_roc_chan); + } + } else { + chan_env.status |= CO_BIT(CHAN_ENV_ROC_WAIT_BIT); + if (!(chan_env.status & CO_BIT(CHAN_ENV_DELAY_PROG_BIT))) { + chan_conn_less_delay_prog(); + } + } + return CO_OK; + } + return CO_FAIL; + case MM_ROC_OP_CANCEL: + if (p_roc_chan->idx == CHAN_CTXT_UNUSED) + return CO_OK; // the leaked code returns CO_FAIL here + switch (p_roc_chan->status) { + case CHAN_NOT_PROG: + chan_env.status &= ~CO_BIT(CHAN_ENV_ROC_WAIT_BIT); + // leaked code use chan_send_roc_exp_ind(p_roc_chan); here + break; + case CHAN_GOTO_IDLE: + case CHAN_WAIT_NOA_CFM: + chan_env.chan_switch = NULL; + chan_env.status &= ~CO_BIT(CHAN_ENV_ROC_BIT); + case CHAN_WAITING_END: + mm_timer_clear(&chan_env.tmr_ctxt_op); + chan_ctxt_op_evt((void*) p_roc_chan); + break; + default: + break; + } + + p_roc_chan->idx = CHAN_CTXT_UNUSED; + + if (((chan_env.status & CO_BIT(CHAN_ENV_DELAY_PROG_BIT)) != 0) && + ((chan_env.status & CO_BIT(CHAN_ENV_SCAN_WAIT_BIT)) == 0)) { + chan_env.status &= ~CO_BIT(CHAN_ENV_DELAY_PROG_BIT); + mm_timer_clear(&chan_env.tmr_conn_less); + chan_env.status &= ~CO_BIT(CHAN_ENV_DELAY_PROG_BIT); + } + + return CO_OK; + default: + break; + } + + return CO_FAIL; +} + +uint8_t chan_ctxt_add(const struct mm_chan_ctxt_add_req *p_add_req, uint8_t *idx) { + if (chan_check_chan(p_add_req, idx)) + return CO_OK; + struct chan_ctxt_tag *p_chan_entry = (struct chan_ctxt_tag *)co_list_pop_front(&chan_env.list_free_ctxt); + if (!p_chan_entry) + return CO_FAIL; + *idx = p_chan_entry->idx = CO_GET_INDEX(p_chan_entry, chan_ctxt_pool); + p_chan_entry->channel.band = p_add_req->band; + p_chan_entry->channel.type = p_add_req->type; + p_chan_entry->channel.center1_freq = p_add_req->center1_freq; + p_chan_entry->channel.center2_freq = p_add_req->center2_freq; + p_chan_entry->channel.prim20_freq = p_add_req->prim20_freq; + p_chan_entry->channel.tx_power = p_add_req->tx_power; + return CO_OK; +} + +void chan_ctxt_del(uint8_t chan_idx) { + struct chan_ctxt_tag *p_chan_entry = chan_ctxt_pool + chan_idx; + + ASSERT_ERR(p_chan_entry->idx != CHAN_CTXT_UNUSED); + ASSERT_ERR(p_chan_entry->nb_linked_vif == 0); + + co_list_push_back(&chan_env.list_free_ctxt, &p_chan_entry->list_hdr); + + chan_ctxt_init(p_chan_entry); +} + +#define CHAN_ROC_SCAN_PENDING_MASK (CO_BIT(CHAN_ENV_ROC_BIT) | CO_BIT(CHAN_ENV_SCAN_BIT)) +void chan_ctxt_link(uint8_t vif_idx, uint8_t chan_idx) { + struct chan_ctxt_tag *p_chan_entry = chan_ctxt_pool + chan_idx; + struct vif_info_tag *p_vif_entry = vif_info_tab + vif_idx; + + ASSERT_ERR(p_vif_entry->chan_ctxt == NULL); + + ASSERT_ERR(p_chan_entry->idx != CHAN_CTXT_UNUSED); + + p_vif_entry->chan_ctxt = p_chan_entry; + p_chan_entry->nb_linked_vif ++; + + chan_env.cde_dur_us = chan_env.cde_dur_us + (CHAN_VIF_NB_SLOTS * CHAN_SLOT_DURATION_US); + + if (p_chan_entry->nb_linked_vif == 1) { + p_chan_entry->status = CHAN_NOT_PROG; + chan_env.nb_sched_ctxt ++; + co_list_push_back(&chan_env.list_sched_ctxt, &p_chan_entry->list_hdr); + if (!chan_env.chan_switch) { + if ((chan_env.status & CHAN_ROC_SCAN_PENDING_MASK) == 0) { + if (chan_env.nb_sched_ctxt == 1) { + chan_switch_start(p_chan_entry); + } else { + chan_cde_evt(NULL); + } + } + } else { + chan_env.chan_switch->status = CHAN_NOT_PROG; + chan_env.chan_switch = NULL; + } + } + + chan_update_tx_power(p_chan_entry); +} + +void chan_ctxt_unlink(uint8_t vif_idx) { + struct vif_info_tag *p_vif_entry = &vif_info_tab[vif_idx]; + struct chan_ctxt_tag *p_chan_entry = p_vif_entry->chan_ctxt; + ASSERT_ERR(p_chan_entry != NULL); + co_list_extract(&chan_env.list_tbtt, &(p_vif_entry->tbtt_switch.list_hdr)); + p_vif_entry->tbtt_switch.status = CHAN_TBTT_NOT_PROG; + p_vif_entry->chan_ctxt = NULL; + p_chan_entry->nb_linked_vif--; + if (p_chan_entry->status != CHAN_NOT_SCHEDULED) { + chan_env.cde_dur_us -= (CHAN_VIF_NB_SLOTS * CHAN_SLOT_DURATION_US); + if (p_chan_entry->nb_linked_vif == 0) { + co_list_extract(&chan_env.list_sched_ctxt, &p_chan_entry->list_hdr); + p_chan_entry->status = CHAN_NOT_SCHEDULED; + chan_env.nb_sched_ctxt--; + bool switch_in_prog = (chan_env.chan_switch != NULL); + bool switch_unlk = (chan_env.chan_switch == p_chan_entry); + if (chan_env.current_channel == p_chan_entry) { + chan_env.current_channel = NULL; + } else if (switch_unlk) { + // switch_unlk => switch_in_prog + chan_env.chan_switch = 0x0; + // => A + } + if (!switch_in_prog) { + if (chan_env.nb_sched_ctxt < 2) { + if (chan_env.nb_sched_ctxt == 1) { + chan_switch_start((struct chan_ctxt_tag *)co_list_pick(&chan_env.list_sched_ctxt)); + } + } else { + chan_cde_evt(NULL); + } + } else { + // A + chan_env.status |= CO_BIT(CHAN_ENV_TIMEOUT_BIT); + } + } + } + + if (p_chan_entry->nb_linked_vif == 0) { + chan_ctxt_del(p_chan_entry->idx); + } + + chan_tbtt_schedule(NULL); + + chan_update_tx_power(p_chan_entry); +} + +void chan_ctxt_update(const struct mm_chan_ctxt_update_req *p_upd_req) { + uint8_t idx = p_upd_req->chan_index; + chan_ctxt_pool[idx].channel.band = p_upd_req->band; + chan_ctxt_pool[idx].channel.type = p_upd_req->type; + chan_ctxt_pool[idx].channel.center1_freq = p_upd_req->center1_freq; + chan_ctxt_pool[idx].channel.center2_freq = p_upd_req->center2_freq; + chan_ctxt_pool[idx].channel.prim20_freq = p_upd_req->prim20_freq; + chan_ctxt_pool[idx].channel.tx_power = p_upd_req->tx_power; + struct chan_ctxt_tag *p_chan_entry = chan_env.current_channel; + if (p_chan_entry != chan_ctxt_pool + idx) { + return; + } + rxl_timer_int_handler(); + rxl_cntrl_evt(0); + phy_set_channel(p_upd_req->band, p_upd_req->type, p_upd_req->prim20_freq, p_upd_req->center1_freq, + p_upd_req->center2_freq, PHY_PRIM); + tpc_update_tx_power((p_chan_entry->channel).tx_power); +} + +void chan_tbtt_switch_update(struct vif_info_tag *p_vif_entry, uint32_t tbtt_time) { + struct chan_tbtt_tag *p_tbtt_entry = &p_vif_entry->tbtt_switch; + if (p_vif_entry->chan_ctxt) { + if (p_vif_entry->chan_ctxt->status != CHAN_TBTT_NOT_PROG) { + if (p_tbtt_entry->time != tbtt_time - CHAN_SWITCH_DELAY) { + p_tbtt_entry->time = tbtt_time - CHAN_SWITCH_DELAY; + if (chan_env.nb_sched_ctxt < 2) + return ; + if ((p_vif_entry->tbtt_switch).status != CHAN_TBTT_PRESENCE) { + p_tbtt_entry->status = CHAN_TBTT_NOT_PROG; + co_list_extract(&chan_env.list_tbtt, &(p_vif_entry->tbtt_switch).list_hdr); + chan_tbtt_schedule(p_tbtt_entry); + } + } + } + } +} + +void chan_bcn_to_evt(struct vif_info_tag *p_vif_entry) { + uint32_t current_time = ke_time(); + struct chan_tbtt_tag *p_tbtt_entry = &p_vif_entry->tbtt_switch; + if (p_tbtt_entry->status == CHAN_TBTT_PRESENCE) { + p_tbtt_entry->status = CHAN_TBTT_NOT_PROG; + co_list_extract(&chan_env.list_tbtt, &p_tbtt_entry->list_hdr); + if (chan_env.nb_sched_ctxt < 2) return ; + chan_tbtt_schedule(&p_vif_entry->tbtt_switch); + if ((chan_env.status & (CO_BIT(CHAN_ENV_ROC_BIT) | CO_BIT(CHAN_ENV_SCAN_BIT))) == 0) { + struct chan_ctxt_tag *p_chan_entry = chan_env.current_channel; + if (!chan_env.chan_switch) { + chan_upd_nb_rem_slots(p_chan_entry, current_time); + } + if (p_chan_entry->nb_res_slots) { + p_chan_entry->nb_res_slots -= co_min(chan_get_nb_slots(current_time, chan_env.cde_time), p_chan_entry->nb_res_slots); + } + chan_env.cde_time = current_time; + p_chan_entry = chan_get_next_chan(); + if (chan_env.current_channel != p_chan_entry) { + chan_switch_start(p_chan_entry); + } + } + } +} + +void chan_bcn_detect_start(struct vif_info_tag *p_vif_entry) { + struct chan_ctxt_tag * p_chan_entry = p_vif_entry->chan_ctxt; + + ASSERT_ERR(p_chan_entry); + + if (((chan_env.status & CO_BIT(CHAN_ENV_BCN_DETECT_BIT)) == 0) && (chan_env.nb_sched_ctxt > 1)) { + uint8_t ap_id = p_vif_entry->u.sta.ap_id; + struct mm_remain_on_channel_req *msg = (struct mm_remain_on_channel_req *) ke_msg_alloc(MM_REMAIN_ON_CHANNEL_REQ, TASK_MM, TASK_MM, sizeof(struct mm_remain_on_channel_req)); + msg->op_code = MM_ROC_OP_START; + msg->vif_index = p_vif_entry->index; + msg->band = (p_chan_entry->channel).band; + msg->type = (p_chan_entry->channel).type; + msg->prim20_freq = (p_chan_entry->channel).prim20_freq; + msg->center1_freq = (p_chan_entry->channel).center1_freq; + msg->center2_freq = (p_chan_entry->channel).center2_freq; + msg->duration_ms = (sta_info_tab[ap_id].bcn_int - 5000) / 1000; + msg->tx_power = (p_chan_entry->channel).tx_power; + ke_msg_send(msg); + chan_env.status = chan_env.status | CO_BIT(CHAN_ENV_BCN_DETECT_BIT); + } +} + +bool chan_is_on_channel(struct vif_info_tag *p_vif_entry) { + if (chan_env.current_channel) { + if (chan_env.current_channel->idx < CHAN_SCAN_CTXT_IDX) { + return p_vif_entry->chan_ctxt == chan_env.current_channel; + } else { + return chan_env.current_channel->vif_index == p_vif_entry->index; + } + } + return false; +} + +bool chan_is_tx_allowed(struct vif_info_tag *p_vif_entry) { + return (chan_is_on_channel(p_vif_entry)) && (!chan_env.chan_switch || chan_env.current_channel->status == CHAN_SENDING_NOA); +} + +bool chan_is_on_operational_channel(struct vif_info_tag *p_vif_entry) { + if (chan_env.current_channel) { + if (chan_env.current_channel->idx < CHAN_SCAN_CTXT_IDX) { + return p_vif_entry->chan_ctxt == chan_env.current_channel; + } + } + return false; +} + +void chan_update_tx_power(struct chan_ctxt_tag *p_chan_entry) { + if (p_chan_entry->nb_linked_vif == 0) return ; + int8_t min_pwr = VIF_UNDEF_POWER; + for (int i = 0; i < NX_VIRT_DEV_MAX; i++) { + if (p_chan_entry == vif_info_tab[0].chan_ctxt) { + if (vif_info_tab[i].user_tx_power < min_pwr) + min_pwr = vif_info_tab[i].user_tx_power; + if (vif_info_tab[i].tx_power < min_pwr) + min_pwr = vif_info_tab[i].tx_power; + } + } + if (min_pwr != VIF_UNDEF_POWER) { + p_chan_entry->channel.tx_power = min_pwr; + } +} diff --git a/src/bl602_wifi/ip/lmac/mm/mm.c b/src/bl602_wifi/ip/lmac/mm/mm.c new file mode 100644 index 0000000..4237315 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/mm/mm.c @@ -0,0 +1,954 @@ +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include + +#include +#include + +#if NX_BEACONING +#define MM_TBTT_EVT_MASK (KE_EVT_PRIMARY_TBTT_BIT | KE_EVT_SECONDARY_TBTT_BIT) +#else +#define MM_TBTT_EVT_MASK KE_EVT_PRIMARY_TBTT_BIT +#endif + +#if NX_MULTI_ROLE +/// Wake up delay before TBTT is occurring +#define TBTT_DELAY 400 ///< 400us +#endif + +/// Margin taken when checking if the computed TBTT is not in the past +/// This number was 300 on alios, but 700 (or say 3200 = 2500 + 700) in +/// bl602 +#if NX_CHNL_CTXT +#define MM_TBTT_COMPUTE_MARGIN (CHAN_SWITCH_DELAY + 700) +#else +#define MM_TBTT_COMPUTE_MARGIN 700 +#endif + +struct mm_env_tag mm_env; + +void mm_env_max_ampdu_duration_set(void) { + mm_env.ampdu_max_dur[AC_BK] = TXOP(MAC_CORE->EDCA_AC_0.txOpLimit0); + mm_env.ampdu_max_dur[AC_BE] = TXOP(MAC_CORE->EDCA_AC_1.txOpLimit1); + mm_env.ampdu_max_dur[AC_VI] = TXOP(MAC_CORE->EDCA_AC_2.txOpLimit2); + mm_env.ampdu_max_dur[AC_VO] = TXOP(MAC_CORE->EDCA_AC_3.txOpLimit3); + #if NX_BEACONING + mm_env.ampdu_max_dur[AC_BCN] = mm_env.ampdu_max_dur[AC_VO]; + #endif +} + +void mm_env_init(void) { + memset(&mm_env, 0, sizeof(struct mm_env_tag)); + + mm_env.host_idle = 0x1; + mm_env.keep_alive_status_enabled = 0x1; // new? + mm_env.prev_mm_state = MM_IDLE; + mm_env.prev_hw_state = HW_IDLE; + + mm_rx_filter_umac_set(MM_RX_FILTER_MONITOR); + + mm_env_max_ampdu_duration_set(); +} + +void mm_init(void) { + hal_machw_init(); + mm_env_init(); + vif_mgmt_init(); + sta_mgmt_init(); +#if (NX_TD) + td_init(); +#endif +#if NX_POWERSAVE + ps_init(); +#endif + txl_cntrl_init(); + rxl_init(); +#if NX_MM_TIMER + mm_timer_init(); +#endif +#if NX_HW_SCAN + scan_init(); +#endif +#if NX_CHNL_CTXT + chan_init(); +#endif +#if NX_GP_DMA + hal_dma_init(); +#endif + mm_bcn_init(); +} + +#if NX_MULTI_ROLE +static void mm_tbtt_compute(struct bcn_frame *bcn, uint16_t len, struct rx_hd *rhd, struct vif_info_tag *vif_entry, struct sta_info_tag *p_sta_entry, uint32_t tim) { + uint16_t interval; + uint32_t drift = 0; +#if NX_POWERSAVE + if (vif_entry->u.sta.listen_interval) { + interval = vif_entry->u.sta.listen_interval; + } else +#endif + { + if (tim) { + interval = co_read8p(tim + MAC_TIM_CNT_OFT); + if (interval == 0) + interval = co_read8p(tim + MAC_TIM_PERIOD_OFT); + } else { + interval = 1; // new for bl602 + } + } +#if (NX_POWERSAVE) + drift = p_sta_entry->drift * interval; +#endif //(NX_POWERSAVE) + // It seems that bl602 is using uint32_t for most thingy here + // except tbtt_tsf, tsf_start_peer + uint32_t duration_of_frame = hal_machw_rx_duration(rhd, len); + uint32_t duration_to_timestamp = hal_machw_rx_duration(rhd, MAC_BEACON_TIMESTAMP_OFT); + uint64_t tsf_start_local = ((uint64_t)rhd->tsflo) | (((uint64_t)rhd->tsfhi) << 32); + //uint32_t tsf_start_local = rhd->tsflo; // seems that bl602 use uint32_t here + // I think that's because of optimization.. + // I will use uint64_t for all of them + uint32_t bcn_int = (bcn->bcnint << 10); + + uint64_t tsf_start_peer = bcn->tsf; + uint64_t tbtt_tsf; + + uint64_t next_tbtt_tsf; // this is uint32_t in bl602 assembly + + tsf_start_local -= (duration_of_frame - duration_to_timestamp); + + tbtt_tsf = (tsf_start_peer / bcn_int) * bcn_int; + int64_t tsf_offset = tsf_start_peer - tsf_start_local; + + if (tbtt_tsf < (tsf_start_peer - duration_to_timestamp)) + tbtt_tsf = tsf_start_peer - duration_to_timestamp; + + next_tbtt_tsf = tbtt_tsf + interval * bcn_int; + + uint32_t next_tbtt = (uint32_t)(next_tbtt_tsf - tsf_offset) - TBTT_DELAY - drift; + + if (hal_machw_time_past(next_tbtt - MM_TBTT_COMPUTE_MARGIN)) { + next_tbtt += bcn_int; + } + + next_tbtt += ke_time() - MAC_PL->TSF_LO.value; + + if (next_tbtt != (vif_entry->tbtt_timer).time) { + mm_timer_set(&vif_entry->tbtt_timer, next_tbtt); + } +} +#endif + +static void mm_ap_probe_cfm(void *env, uint32_t status) { + struct vif_info_tag *vif_entry = (struct vif_info_tag *) env; + if (status & FRAME_SUCCESSFUL_TX_BIT) { + vif_entry->u.sta.beacon_loss_cnt = 0; + return ; + } + mm_send_connection_loss_ind(env); +} + +static uint32_t mm_compute_beacon_crc(struct bcn_frame *bcn, uint16_t len, uint32_t *tim) { + uint32_t bcn_addr = CPU2HW(bcn); + uint32_t crc = co_crc32(bcn_addr + MAC_BEACON_INTERVAL_OFT, 4, 0); + uint32_t addr = bcn_addr + MAC_BEACON_VARIABLE_PART_OFT; + len -= MAC_BEACON_VARIABLE_PART_OFT; + while (len >= MAC_INFOELT_INFO_OFT) { + uint8_t ie_id = co_read8p(addr++); + uint8_t ie_len = co_read8p(addr++); + if ((ie_len + MAC_INFOELT_INFO_OFT) > len) // len <= ie_len + 1 + break; + if (ie_id == MAC_ELTID_TIM) { + *tim = addr - MAC_INFOELT_INFO_OFT; + } else { + crc = co_crc32(addr, ie_len, crc); + } + len -= ie_len + MAC_INFOELT_INFO_OFT; + addr += ie_len; + } + return crc; +} + +#if NX_CONNECTION_MONITOR || NX_MULTI_ROLE +bool mm_check_beacon(struct rx_hd *rhd, struct vif_info_tag *vif_entry, + struct sta_info_tag *p_sta_entry, uint32_t *tim) +{ + static uint32_t beacon_rx_count = 0; + beacon_rx_count++; + uint16_t len = rhd->frmlen; + struct rx_pbd *pbd = HW2CPU(rhd->first_pbd_ptr); + struct bcn_frame *bcn = HW2CPU(pbd->datastartptr); + #if NX_CONNECTION_MONITOR + uint32_t crc_prev = vif_entry->u.sta.mon_last_crc; + vif_entry->u.sta.beacon_loss_cnt = 0; + + if (vif_entry->u.sta.csa_occured) { + mm_send_csa_traffic_ind(vif_entry->index, true); + vif_entry->u.sta.csa_occured = false; + } + + if (ke_time_past(vif_entry->u.sta.mon_last_tx + MM_KEEP_ALIVE_PERIOD)) { + if (mm_env.keep_alive_status_enabled) { + if (txl_frame_send_null_frame(vif_entry->u.sta.ap_id, 0, 0) == CO_OK) { + vif_entry->u.sta.mon_last_tx = ke_time(); + } + } + } + + int8_t rssi = (rhd->recvec1c >> 24) & 0xFF; // ((rvec_t *)&(rhd->recvec1a))->rssi1 + + mm_check_rssi(vif_entry, rssi); + + vif_entry->u.sta.mon_last_crc = mm_compute_beacon_crc(bcn, len, tim); + #endif +#if NX_MULTI_ROLE + // Compute the time of the next TBTT + mm_tbtt_compute(bcn, len, rhd, vif_entry, p_sta_entry, *tim); +#endif +#if NX_CONNECTION_MONITOR + return (crc_prev != vif_entry->u.sta.mon_last_crc); +#else + return (true); +#endif +} +#endif + +void mm_reset(void) { + if (ke_state_get(TASK_MM) == MM_ACTIVE) { + mm_active(); + } else { + ke_state_set(TASK_MM, MM_IDLE); + } +} + +void mm_active(void) { + PACK(MAC_CORE->STATE_CNTRL, cntrl) { + cntrl.value = 0; + cntrl.nextState = HW_ACTIVE; + } + ke_state_set(TASK_MM, MM_ACTIVE); +} + +#if NX_POWERSAVE || NX_CONNECTION_MONITOR || NX_MULTI_ROLE +void mm_sta_tbtt(void *env) { + struct vif_info_tag *vif_entry = (struct vif_info_tag *)env; + +#if (NX_MULTI_ROLE || NX_CHNL_CTXT) + // TBTT Time + uint32_t tbtt_time; +#endif //(NX_MULTI_ROLE || NX_CHAN_CTXT) + if (!vif_entry->active) + return ; + + if (vif_entry->u.sta.csa_count != 0){ + vif_entry->u.sta.csa_count--; + if (vif_entry->u.sta.csa_count <= 1) { + vif_mgmt_switch_channel(vif_entry); + return ; + } else if (vif_entry->u.sta.csa_count == 2) { + mm_send_csa_traffic_ind(vif_entry->index, false); + } + } +#if (NX_MULTI_ROLE || NX_CHNL_CTXT) + tbtt_time = sta_info_tab[(vif_entry->u).sta.ap_id].bcn_int + (vif_entry->tbtt_timer).time; +#endif +#if NX_MULTI_ROLE + mm_timer_set(&vif_entry->tbtt_timer, tbtt_time); +#endif +#if (NX_P2P || NX_CHNL_CTXT) + vif_mgmt_bcn_to_prog(vif_entry); +#endif +#if (NX_CHNL_CTXT) + chan_tbtt_switch_update(vif_entry,tbtt_time); + if (!chan_is_on_channel(vif_entry)) { + return; + } +#endif +#if NX_POWERSAVE + vif_entry->prevent_sleep = vif_entry->prevent_sleep | PS_VIF_WAITING_BCN; +#endif +#if NX_CONNECTION_MONITOR + (vif_entry->u).sta.beacon_loss_cnt++; + if (vif_entry->u.sta.beacon_loss_cnt > MM_BEACON_LOSS_THD) { + // vif_entry->u.sta.beacon_loss_cnt = 0; // reversed code doesn't have this line + // bl602 only set this to zero if the null frame send succeed and mm_ap_probe_cfm is called + // but the alios one set this to zero here + txl_frame_send_null_frame(vif_entry->u.sta.ap_id, mm_ap_probe_cfm, vif_entry); + } +#if (NX_CHNL_CTXT) + else if (vif_entry->u.sta.beacon_loss_cnt == MM_BEACON_LOSS_THD) { + chan_bcn_detect_start(vif_entry); + } +#endif +#endif +} +#endif + +void mm_ap_tbtt(uint32_t evt) { + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + __disable_irq(); + txl_cntrl_halt_ac(AC_BCN); + txl_cntrl_flush_ac(AC_BCN, DESC_DONE_SW_TX_BIT); + + for (; p_vif_entry; p_vif_entry = (struct vif_info_tag *)co_list_next(&(p_vif_entry->list_hdr))) { + if (p_vif_entry->type == VIF_AP) { + p_vif_entry->u.ap.bcn_tbtt_cnt--; + if (p_vif_entry->u.ap.bcn_tbtt_cnt == 0) { + p_vif_entry->u.ap.bcn_tbtt_cnt = p_vif_entry->u.ap.bcn_tbtt_ratio; + vif_mgmt_bcn_to_prog(p_vif_entry); + #if (NX_CHNL_CTXT || NX_P2P_GO) + uint32_t beacon_int = (uint32_t)p_vif_entry->u.ap.bcn_int << 10; + uint32_t next_tbtt = ke_time() + ((uint32_t)MAC_PL->NEXT_TBTT.nextTBTT << 5) + beacon_int; + #endif //(NX_CHNL_CTXT || NX_P2P_GO) + #if (NX_CHNL_CTXT) + if (p_vif_entry->chan_ctxt != NULL) { + chan_tbtt_switch_update(p_vif_entry, next_tbtt); + } + #endif //(NX_CHNL_CTXT) + + } + } + } +#if NX_BCN_AUTONOMOUS_TX + // Transmit the beacon(s) + mm_bcn_transmit(); +#endif + __enable_irq(); +} + +#if NX_BEACONING && (!NX_MULTI_ROLE) +void mm_tbtt_evt(int dummy) { + // ... + uint32_t evt = ke_evt_get() & MM_TBTT_EVT_MASK; + ASSERT_ERR(evt != MM_TBTT_EVT_MASK); + ke_evt_clear(evt); + + if (vif_entry->type == VIF_STA) + mm_sta_tbtt(vif_entry); + else if (mm_env.beaconing) + mm_ap_tbtt(evt); +} +#elif (!NX_MULTI_ROLE) +void mm_tbtt_evt(int dummy) { + uint32_t evt = ke_evt_get() & MM_TBTT_EVT_MASK; + ASSERT_ERR(evt != MM_TBTT_EVT_MASK); + ke_evt_clear(evt); + + mm_sta_tbtt(evt); +} +#elif NX_BEACONING +void mm_tbtt_evt(int dummy) { + uint32_t evt = ke_evt_get() & MM_TBTT_EVT_MASK; + ASSERT_ERR(evt != MM_TBTT_EVT_MASK); + ke_evt_clear(evt); + mm_ap_tbtt(evt); +} +#endif + +uint8_t mm_sec_machwaddr_wr(uint8_t sta_idx, uint8_t inst_nbr) { + uint8_t hw_sta_idx; + struct sta_info_tag *sta = sta_info_tab + sta_idx; + + // Compute the HW STA index + hw_sta_idx = MM_SEC_DEFAULT_KEY_COUNT + sta_idx; // 8 + sta_idx + + MAC_CORE->ENCR_MAC_ADDR_LOW.macAddrRAMLow = *((uint32_t*)sta->mac_addr.array); + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = sta->mac_addr.array[2]; + + MAC_CORE->ENCR_KEY_0.value = 0; + MAC_CORE->ENCR_KEY_1.value = 0; + MAC_CORE->ENCR_KEY_2.value = 0; + MAC_CORE->ENCR_KEY_3.value = 0; + + PACK0(MAC_CORE->ENCR_CNTRL, encr_cntrl) { + // (uint8_t newread,uint8_t newwrite,uint16_t keyindexram,uint8_t ctyperam, + // uint8_t vlanidram,uint8_t sppram,uint8_t usedefkeyram,uint8_t clenram, + // uint8_t searcherror,uint8_t newsearch) + encr_cntrl.newRead = 0; + encr_cntrl.newWrite = 1; + encr_cntrl.keyIndexRAM = hw_sta_idx; + encr_cntrl.cTypeRAM = 0; + encr_cntrl.vlanIDRAM = inst_nbr; + encr_cntrl.sppRAM = 0; + encr_cntrl.useDefKeyRAM = 1; + encr_cntrl.cLenRAM = 0; + } + + for (;MAC_CORE->ENCR_CNTRL.newWrite;); + + return hw_sta_idx; +} + +static void dump_keyram_config(uint32_t val) { + puts("========================== Keyram Config ========================\r\n"); + printf(" start %02u -->> end %02u; nVAP %02u; max %02u\r\n",val & 0xff,val >> 8 & 0xff, + val >> 0x10 & 0xff,val >> 0x18); + puts("========================== Keyram Dump =========================\r\n"); + puts("[id] MAC Address Key Len VLan ID Default \tKey Hexdump(16Bytes MAX)\r\n"); +} + +static void dump_mac_like(const char* format, uint32_t a, uint16_t b) { + union { + struct { + uint32_t a; + uint16_t b; + }; + uint8_t c[6]; + } mac_addr = { + .a = a, + .b = b + }; + printf("%s%02X:%02X:%02X:%02X:%02X:%02X", format, + mac_addr.c[0], mac_addr.c[1], mac_addr.c[2], + mac_addr.c[3], mac_addr.c[4], mac_addr.c[5]); +} + +void mm_sec_keydump(void) { + static const char* bits[] = {"128-Bit", " 64-Bit"}; + dump_keyram_config(MAC_CORE->encr_ram_config.value); + int end = MAC_CORE->encr_ram_config.end; + for (int i = 0; i < end; i++) { + PACK0(MAC_CORE->ENCR_CNTRL, encr_cntrl) { + encr_cntrl.newRead = 1; + encr_cntrl.newWrite = 0; + encr_cntrl.keyIndexRAM = i; + encr_cntrl.cTypeRAM = 0; + encr_cntrl.vlanIDRAM = 0; + encr_cntrl.sppRAM = 0; + encr_cntrl.useDefKeyRAM = 0; + encr_cntrl.cLenRAM = 0; + } + for (;MAC_CORE->ENCR_CNTRL.newRead;); + struct mac_addr mac; + *((uint32_t*)mac.array) = MAC_CORE->ENCR_MAC_ADDR_LOW.macAddrRAMLow; + mac.array[2] = MAC_CORE->ENCR_MAC_ADDR_HIGH.macAddrRAMHigh; + mac_addr_unpack* unpack_mac = (mac_addr_unpack*)&mac; + printf("[%02d] %02X:%02X:%02X:%02X:%02X:%02X", i, + unpack_mac->array[0], unpack_mac->array[1], unpack_mac->array[2], + unpack_mac->array[3], unpack_mac->array[4], unpack_mac->array[5]); + const char *keyLen = bits[0]; + if (MAC_CORE->ENCR_CNTRL.cLenRAM == 0) { + keyLen = bits[1]; + } + printf(" %s", keyLen); + printf(" %02u", MAC_CORE->ENCR_CNTRL.vlanIDRAM); + printf(" %u", MAC_CORE->ENCR_CNTRL.useDefKeyRAM); + union { + uint32_t keys[4]; + uint8_t keys8[4 * 4]; + } key = { + .keys = { + MAC_CORE->ENCR_KEY_0.value, + MAC_CORE->ENCR_KEY_1.value, + MAC_CORE->ENCR_KEY_2.value, + MAC_CORE->ENCR_KEY_3.value, + } + }; + + printf(" %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X", + key.keys8[0],key.keys8[1],key.keys8[2],key.keys8[3], + key.keys8[4],key.keys8[5],key.keys8[6],key.keys8[7], + key.keys8[8],key.keys8[9],key.keys8[10],key.keys8[11], + key.keys8[12],key.keys8[13],key.keys8[14],key.keys8[15]); + puts("\r\n"); + } + puts("========================== MAC Address =========================\r\n"); + dump_mac_like(" MAC ", MAC_CORE->MAC_ADDR_LOW.value, MAC_CORE->MAC_ADDR_HI.value); + dump_mac_like(" Mask ", MAC_CORE->MAC_ADDR_LOW_MASK.value, MAC_CORE->MAC_ADDR_HI_MASK.value); + puts("\r\n"); + dump_mac_like(" MAC ", MAC_CORE->BSS_ID_LOW.value, MAC_CORE->BSS_ID_HI.value); + dump_mac_like(" Mask ", MAC_CORE->BSS_ID_LOW_MASK.value, MAC_CORE->BSS_ID_HI_MASK.value); + puts("\r\n"); +} + +uint8_t mm_sec_machwkey_wr(const struct mm_key_add_req *param) { + uint8_t sta_idx = param->sta_idx; + uint8_t vlan_idx = param->inst_nbr; + uint8_t key_idx_hw; + if (sta_idx == INVALID_STA_IDX) { + key_idx_hw = MM_VIF_TO_KEY(param->key_idx, param->inst_nbr); + + MAC_CORE->ENCR_MAC_ADDR_LOW.value = 0xffffffff; + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = 0xffffffff; + + vif_mgmt_add_key(param, key_idx_hw); + } else { + struct sta_info_tag *sta = &sta_info_tab[sta_idx]; + ASSERT_ERR(sta_idx < STA_MAX); + + key_idx_hw = MM_STA_TO_KEY(sta_idx); + sta_mgmt_add_key(param, key_idx_hw); + MAC_CORE->ENCR_MAC_ADDR_LOW.value = sta->mac_addr.array[0] | (((uint32_t)sta->mac_addr.array[1]) << 16); + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = sta->mac_addr.array[2]; + } + + uint8_t clen = 1; + uint8_t ctype = MM_SEC_CTYPE_NULL; + struct mac_sec_key const *key = ¶m->key; + ASSERT_ERR(param->cipher_suite <= 3); + if (param->cipher_suite == 0) { + clen = 0; + } else if (param->cipher_suite <= 2) { + uint8_t types[] = {MM_SEC_CTYPE_NULL, MM_SEC_CTYPE_TKIP, MM_SEC_CTYPE_CCMP, MM_SEC_CTYPE_WEP}; + ctype = types[param->cipher_suite]; + } + + MAC_CORE->ENCR_KEY_0.value = key->array[0]; + MAC_CORE->ENCR_KEY_1.value = key->array[1]; + MAC_CORE->ENCR_KEY_2.value = key->array[2]; + MAC_CORE->ENCR_KEY_3.value = key->array[3]; + + PACK0(MAC_CORE->ENCR_CNTRL, encr_cntrl) { + encr_cntrl.newRead = 0; + encr_cntrl.newWrite = 1; + encr_cntrl.keyIndexRAM = key_idx_hw; + encr_cntrl.cTypeRAM = ctype; + encr_cntrl.vlanIDRAM = vlan_idx; + encr_cntrl.sppRAM = param->spp; + encr_cntrl.useDefKeyRAM = 0; + encr_cntrl.cLenRAM = clen; + } + + for (;MAC_CORE->ENCR_CNTRL.newWrite;); + + return key_idx_hw; +} + +void mm_sec_machwkey_del(uint8_t hw_key_idx) { + if (hw_key_idx < MM_SEC_DEFAULT_KEY_COUNT) { + MAC_CORE->ENCR_MAC_ADDR_LOW.value = 0xffffffff; + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = 0xffffffff; + + vif_mgmt_del_key(vif_info_tab + (MM_KEY_TO_VIF(hw_key_idx)), MM_KEY_TO_KEYID(hw_key_idx)); + } else { + struct sta_info_tag* p_sta_info = sta_info_tab + (MM_KEY_TO_STA(hw_key_idx)); + MAC_CORE->ENCR_MAC_ADDR_LOW.value = *(uint32_t*) (p_sta_info->mac_addr.array); + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = p_sta_info->mac_addr.array[2]; + sta_mgmt_del_key(p_sta_info); + } + MAC_CORE->ENCR_KEY_0.value = 0; + MAC_CORE->ENCR_KEY_1.value = 0; + MAC_CORE->ENCR_KEY_2.value = 0; + MAC_CORE->ENCR_KEY_3.value = 0; + + PACK0(MAC_CORE->ENCR_CNTRL, encr_cntrl) { + encr_cntrl.newRead = 0; + encr_cntrl.newWrite = 1; + encr_cntrl.keyIndexRAM = hw_key_idx; + } + for (;MAC_CORE->ENCR_CNTRL.newWrite;); +} + +void mm_sec_machwaddr_del(uint8_t sta_idx) { + MAC_CORE->ENCR_MAC_ADDR_LOW.value = 0xffffffff; + MAC_CORE->ENCR_MAC_ADDR_HIGH.value = 0xffffffff; + MAC_CORE->ENCR_KEY_0.value = 0; + MAC_CORE->ENCR_KEY_1.value = 0; + MAC_CORE->ENCR_KEY_2.value = 0; + MAC_CORE->ENCR_KEY_3.value = 0; + PACK0(MAC_CORE->ENCR_CNTRL, encr_cntrl) { + encr_cntrl.newRead = 0; + encr_cntrl.newWrite = 1; + encr_cntrl.keyIndexRAM = MM_STA_TO_KEY(sta_idx); + } + for (;MAC_CORE->ENCR_CNTRL.newWrite;); +} + +void mm_hw_idle_evt(int dummy) { + ke_evt_clear(KE_EVT_HW_IDLE_BIT); + ke_state_set(TASK_MM, MM_IDLE); +} + +void mm_hw_info_set(const struct mac_addr *mac_addr) { + MAC_CORE->MAC_CNTRL_1.ap = 0; + MAC_CORE->MAC_CNTRL_1.bssType = 1; + MAC_CORE->MAC_ADDR_HI_MASK.value = 0x100; + MAC_PL->TSF_LO.value = 0; + MAC_PL->TSF_HI.value = 0; + MAC_CORE->MAC_ADDR_LOW.value = *(uint32_t*) mac_addr->array; + MAC_CORE->MAC_ADDR_HI.value = mac_addr->array[2]; + PACK(MAC_CORE->MAC_CNTRL_1, cntrl) { + cntrl.disableACKResp = 0; + cntrl.disableCTSResp = 0; + cntrl.disableBAResp = 0; + } + mm_env.rx_filter_umac = MM_RX_FILTER_ACTIVE; + mm_rx_filter_set(); +} + +void mm_hw_ap_info_set(void) { + MAC_CORE->MAC_CNTRL_1.ap = 1; + mm_env.rx_filter_umac = (MM_RX_FILTER_ACTIVE | NXMAC_ACCEPT_PS_POLL_BIT | NXMAC_ACCEPT_ALL_BEACON_BIT); // bl602 has one mroe NXMAC_ACCEPT_ALL_BEACON_BIT + mm_rx_filter_set(); + PACK0(MAC_PL->GEN_INT_ACK, int_ack) { + int_ack.impPriDTIM = 1; + int_ack.impPriTBTT = 1; + } + PACK(MAC_PL->GEN_INT_ENABLE, int_en) { + int_en.impPriTBTT = 1; + int_en.impPriDTIM = 1; + } +} + +void mm_hw_ap_info_reset(void) { + MAC_CORE->MAC_CNTRL_1.ap = 0; + mm_env.rx_filter_umac = (MM_RX_FILTER_ACTIVE); + mm_rx_filter_set(); + PACK0(MAC_PL->GEN_INT_ACK, int_ack) { + int_ack.impPriDTIM = 1; + int_ack.impPriTBTT = 1; + } + PACK(MAC_PL->GEN_INT_ENABLE, int_en) { + int_en.impPriTBTT = 0; + int_en.impPriDTIM = 0; + } +} + +void mm_back_to_host_idle(void) { + ASSERT_ERR(ke_state_get(TASK_MM) == MM_HOST_BYPASSED); + if (mm_env.host_idle == 0) { + mm_active(); + } else { + ke_state_set(TASK_MM, MM_IDLE); + } +} + +void mm_force_idle_req(void) { + __disable_irq(); + hal_machw_reset(); + rxl_reset(); + txl_reset(); + ke_state_set(TASK_MM, MM_HOST_BYPASSED); + mm_env.prev_mm_state = MM_IDLE; + mm_env.prev_hw_state = HW_IDLE; + __enable_irq(); +} + +static unsigned char ascii_to_hex(char asccode) { + if (asccode >= '0' && asccode <= '9') + return asccode - '0'; + if (asccode >= 'a' && asccode <= 'f') + return asccode - 'a' + 10; + if (asccode >= 'A' && asccode <= 'F') + return asccode - 'A' + 10; + return 0; +} + +void ascii_str_to_hex(unsigned char *hex, unsigned char *ascs, int srclen) { + srclen &= 0xff; + if (srclen & 1){ + srclen = srclen & 0xfe; + } + for (int i = 0; i < srclen; i += 2) { + hex[i/2] = ascii_to_hex(ascs[i]) * 16 + ascii_to_hex(ascs[i + 1]); + } +} + +uint8_t wep_hw_keyid = 0xff; + +uint8_t mm_sta_add(const struct mm_sta_add_req *param, uint8_t *sta_idx, uint8_t *hw_sta_idx) { + uint8_t status; + + // Register the new station + status = sta_mgmt_register(param, sta_idx); + struct vif_info_tag *p_vif_entry; + if (status == CO_OK) { + p_vif_entry = vif_info_tab + param->inst_nbr; + *hw_sta_idx = mm_sec_machwaddr_wr(*sta_idx, param->inst_nbr); + if (p_vif_entry->type != VIF_STA) + return status; + } else return status; + // bl602 has bunch of supplicant related code here + // also access the phrase from sm.. ? + // p_vif_entry->u.sta.ap_id = *sta_idx; is delayed to + // the end.. if supplicant goes well + struct mm_key_add_req key_add_req; + if (p_vif_entry->bss_info.is_supplicant_enabled != false) { + sta_conn_info.staId = *sta_idx; + if ((p_vif_entry->bss_info.wpa_wpa2_wep.wpa == 0) && + (p_vif_entry->bss_info.wpa_wpa2_wep.wpa2 == 0) && + (p_vif_entry->bss_info.wpa_wpa2_wep.wpa3 == 0) + ) { + if (p_vif_entry->bss_info.wpa_wpa2_wep.wepStatic) { + /*((*(byte *)&vif_info_tab[uVar1].bss_info.wpa_wpa2_wep & 2) != 0)*/ + int32_t lend = strlen((char *)(sm_env.connect_param)->phrase); + uint8_t len = lend; + printf("wep:len:%d,password:%s\n",len, (sm_env.connect_param)->phrase); + memset(&key_add_req, 0, sizeof(struct mm_key_add_req)); + key_add_req.inst_nbr = param->inst_nbr; + key_add_req.key_idx = 0; + key_add_req.sta_idx = 0xff; + key_add_req.key.length = len; + if (len == 5) { + key_add_req.cipher_suite = MAC_RSNIE_CIPHER_WEP40; + memcpy(key_add_req.key.array, (sm_env.connect_param)->phrase, len); + } else { + if (len == 13) { + key_add_req.cipher_suite = MAC_RSNIE_CIPHER_WEP104; + memcpy(key_add_req.key.array, (sm_env.connect_param)->phrase, len); + } else { + if (len == 10) { + key_add_req.cipher_suite = MAC_RSNIE_CIPHER_WEP40; + key_add_req.key.length = 5; + } else { + if (len != 26) { + printf("password length is not correct for wep\n"); + sta_mgmt_unregister(*sta_idx); + return CO_FAIL; + } + key_add_req.cipher_suite = MAC_RSNIE_CIPHER_WEP104; + key_add_req.key.length = 13; + } + ascii_str_to_hex((unsigned char*)key_add_req.key.array, (unsigned char*)(sm_env.connect_param)->phrase, len); + } + } + wep_hw_keyid = mm_sec_machwkey_wr(&key_add_req); + } + } else { + char* phrase; + if ((sm_env.connect_param)->phrase_pmk[0] == 0) { + phrase = (char*)((sm_env.connect_param)->phrase); + } else { + phrase = (char*)((sm_env.connect_param)->phrase_pmk); + } + set_psk((char *)p_vif_entry->bss_info.ssid.array, + p_vif_entry->bss_info.ssid.length, phrase); + } + } + if ((p_vif_entry->bss_info.wpa_wpa2_wep.wpa2 == 0) && + (p_vif_entry->bss_info.wpa_wpa2_wep.wpa3 == 0) + ) { + if (p_vif_entry->bss_info.wpa_wpa2_wep.wpa) { + supplicantEnable(&sta_conn_info, 3, + (void*)(&(p_vif_entry->bss_info.wpa_mcstCipher)), + (void*)(&(p_vif_entry->bss_info.wpa_ucstCipher)), + p_vif_entry->bss_info.is_pmf_required + ); + } + } else { + supplicantEnable(&sta_conn_info, 4, + (void*)(&(p_vif_entry->bss_info.rsn_mcstCipher)), + (void*)(&(p_vif_entry->bss_info.rsn_ucstCipher)), + p_vif_entry->bss_info.is_pmf_required + ); + } + + p_vif_entry->u.sta.ap_id = *sta_idx; + return CO_OK; +} + +void mm_sta_del(uint8_t sta_idx) { + struct sta_info_tag *sta_entry = sta_info_tab + sta_idx; + struct vif_info_tag *vif_entry = vif_info_tab + sta_entry->inst_nbr; + + if (vif_entry->type == VIF_STA) { + vif_entry->u.sta.ap_id = 0xff; + if (vif_entry->bss_info.is_supplicant_enabled) { + if ((vif_entry->bss_info.wpa_wpa2_wep.wpa == 0) && + (vif_entry->bss_info.wpa_wpa2_wep.wpa2 == 0) && + (vif_entry->bss_info.wpa_wpa2_wep.wpa3 == 0) + ) { + if (vif_entry->bss_info.wpa_wpa2_wep.wepStatic && (wep_hw_keyid != 0xff)) { + mm_sec_machwkey_del(wep_hw_keyid); + // I assume we should set wep_hw_keyid to 0xff?? + } + } else { + mm_sec_machwkey_del(sta_conn_info.ptkHwKeyId); + mm_sec_machwkey_del(sta_conn_info.gtkHwKeyId); + mm_sec_machwkey_del(sta_conn_info.mfpHwKeyId); + supplicantDisable(&sta_conn_info); + memset(&(sta_conn_info.suppData)->hashSsId, 0, sizeof(IEEEtypes_SsIdElement_t)); + remove_psk((char *)vif_entry->bss_info.ssid.array, vif_entry->bss_info.ssid.length); + } + vif_entry->bss_info.is_supplicant_enabled = false; + } + } else { + if (sta_entry->ps_state == PS_MODE_ON) { + vif_entry->u.ap.ps_sta_cnt--; + if (!vif_entry->u.ap.ps_sta_cnt) { + mm_ps_change_ind(VIF_TO_BCMC_IDX(vif_entry->index), PS_MODE_OFF); + apm_tx_int_ps_clear(vif_entry, VIF_TO_BCMC_IDX(vif_entry->index)); + } + } + } + + mm_sec_machwaddr_del(sta_idx); + sta_mgmt_unregister(sta_idx); +} + +void mm_cfg_element_keepalive_timestamp_update(void) { + mm_env.keep_alive_time_last_received = xTaskGetTickCount(); + mm_env.keep_alive_packet_counter++; +} + +#if (NX_CONNECTION_MONITOR) +void mm_send_connection_loss_ind(struct vif_info_tag *p_vif_entry) { + struct mm_connection_loss_ind *ind = ke_msg_alloc(MM_CONNECTION_LOSS_IND, TASK_IND, TASK_MM, sizeof(struct mm_connection_loss_ind)); + ind->inst_nbr = p_vif_entry->index; + ke_msg_send(ind); +} +#endif //(NX_CONNECTION_MONITOR) + +long long int last_us; +#define RSSI_PERIOD (2000000) +void mm_check_rssi(struct vif_info_tag *vif_entry, int8_t rssi) { + int8_t rssi_old = vif_entry->u.sta.rssi; + int8_t rssi_thold = vif_entry->u.sta.rssi_thold; + int8_t rssi_hyst = vif_entry->u.sta.rssi_hyst; + bool rssi_status = vif_entry->u.sta.rssi_status; + + vif_entry->u.sta.rssi = rssi; + + /* this chunk is added by bl602 */ + long long int cur_us = 0; + bl60x_current_time_us(&cur_us); + + // if (cur_us - last_id < RSSI_PERIOD+1){;}else + // if (cur_us <= last_id + RSSI_PERIOD){;}else + // if (cur_us >= last_id + RSSI_PERIOD){;} + if ((rssi_old == 0) || (cur_us - last_us >= RSSI_PERIOD)) { + struct mm_rssi_status_ind *ind = + ke_msg_alloc(MM_RSSI_STATUS_IND, TASK_API, TASK_MM, sizeof(struct mm_rssi_status_ind)); + + ind->vif_index = vif_entry->index; + ind->rssi_status = rssi_status; + ind->rssi = rssi; + last_us = cur_us; + ke_msg_send(ind); + } + + if (rssi_thold == 0) + return; + + if ((rssi_status == 0) && (rssi < rssi_old) && (rssi < (rssi_thold - rssi_hyst))) { + rssi_status = 1; + } else if ((rssi_status == 1) && (rssi > rssi_old) && (rssi > (rssi_thold + rssi_hyst))) { + rssi_status = 0; + } + + if (rssi_status != vif_entry->u.sta.rssi_status) { + struct mm_rssi_status_ind *ind = + ke_msg_alloc(MM_RSSI_STATUS_IND, TASK_API, TASK_MM, sizeof(struct mm_rssi_status_ind)); + + ind->vif_index = vif_entry->index; + ind->rssi_status = rssi_status; + + ke_msg_send(ind); + } + + vif_entry->u.sta.rssi_status = rssi_status; +} + +void mm_send_csa_traffic_ind(uint8_t vif_index, bool enable) { + struct mm_csa_traffic_ind* ind = (struct mm_csa_traffic_ind *)ke_msg_alloc(MM_CSA_TRAFFIC_IND,TASK_API,TASK_MM,sizeof(struct mm_csa_traffic_ind)); + ind->vif_index = vif_index; + ind->enable = enable; + ke_msg_send((void*) ind); +} + +uint16_t mm_get_rsn_wpa_ie(uint8_t sta_id, uint8_t *wpa_ie) { + struct sta_info_tag *sta_entry = sta_info_tab + sta_id; + struct vif_info_tag *vif_entry = vif_info_tab + sta_entry->inst_nbr; + memcpy(wpa_ie, vif_entry->bss_info.rsn_wpa_ie, vif_entry->bss_info.rsn_wpa_ie_len); + return vif_entry->bss_info.rsn_wpa_ie_len; +} + +static int element_notify_status_enabled(struct cfg_element_entry *entry, void *arg1, void *arg2, enum CFG_ELEMENT_TYPE_OPS ops) { + return 0; +} + +static int element_notify_time_last_received_set(struct cfg_element_entry *entry, void *arg1, void *arg2, enum CFG_ELEMENT_TYPE_OPS ops) { + return 0; +} + +static int element_notify_keepalive_received(struct cfg_element_entry *entry, void *arg1, void *arg2, enum CFG_ELEMENT_TYPE_OPS ops) { + return 0; +} + +void mm_rx_filter_set(void) { + MAC_CORE->RX_CNTRL.value = mm_env.rx_filter_lmac_enable | mm_env.rx_filter_umac; +} + +void mm_ps_change_ind(uint8_t sta_idx, uint8_t ps_state) { + struct mm_ps_change_ind *ind = KE_MSG_ALLOC(MM_PS_CHANGE_IND, TASK_API, TASK_MM, mm_ps_change_ind); + sta_info_tab[sta_idx].ps_state = ps_state; + ind->sta_idx = sta_idx; + ind->ps_state = ps_state; + ke_msg_send(ind); +} + +__attribute__((section(".wifi.cfg.entry"))) const struct cfg_element_entry cfg_entrys_mm[3] = { + { + .task = 0, + .element = 0, + .type = CFG_ELEMENT_TYPE_BOOLEAN, + .name = "Keep Alive On/Off Status", + .val = (void*)&mm_env.keep_alive_status_enabled, + .set = cfg_api_element_general_set, + .get = cfg_api_element_general_get, + .notify = element_notify_status_enabled + }, + { + .task = 0, + .element = 1, + .type = CFG_ELEMENT_TYPE_UINT32, + .name = "Keep Alive Frame last received", + .val = (void*)&mm_env.keep_alive_time_last_received, + .set = cfg_api_element_general_set, + .get = cfg_api_element_general_get, + .notify = element_notify_time_last_received_set + }, + { + .task = 0, + .element = 2, + .type = CFG_ELEMENT_TYPE_UINT32, + .name = "Keep Alive Frame Counter", + .val = (void*)&mm_env.keep_alive_packet_counter, + .set = cfg_api_element_general_set, + .get = cfg_api_element_general_get, + .notify = element_notify_keepalive_received + }, +}; + diff --git a/src/bl602_wifi/ip/lmac/mm/mm_bcn.c b/src/bl602_wifi/ip/lmac/mm/mm_bcn.c new file mode 100644 index 0000000..a8346cf --- /dev/null +++ b/src/bl602_wifi/ip/lmac/mm/mm_bcn.c @@ -0,0 +1,438 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +struct mm_bcn_env_tag mm_bcn_env; + +static void mm_tim_update_proceed(const struct mm_tim_update_req *param) { + /// TODO: verify this function.. + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + // No beacon transmission ongoing, proceed immediately to the update + if (param->aid == 0) { + if (param->tx_avail == 0) + vif_entry->u.ap.bc_mc_status = param->tx_avail; + else + vif_entry->u.ap.bc_mc_status = 1; + } else { + struct tx_pbd *pbd_tim = &txl_tim_desc[0]; //&txl_tim_desc[param->inst_nbr][0]; + uint32_t tim_ie = CPU2HW(txl_tim_ie_pool + 0); // CPU2HW(&txl_tim_ie_pool[param->inst_nbr][0]); + struct tx_pbd *pbd_bmp = &txl_tim_desc[1]; // &txl_tim_desc[param->inst_nbr][1]; + uint32_t tim_bmp = CPU2HW(txl_tim_bitmap_pool + 0); // CPU2HW(&txl_tim_bitmap_pool[param->inst_nbr][0]); + + // Compute the byte and bit numbers for this AID + uint8_t n = param->aid / 8; + uint8_t mask = CO_BIT(param->aid % 8); + uint8_t val = co_read8p(tim_bmp + n); + uint8_t pass = (val & mask); + if ((param->tx_avail) && (pass == 0)) { + co_write8p(tim_bmp + n, val | mask); + + vif_entry->u.ap.tim_bitmap_set++; + + // Check if Lower limit of the partial virtual bitmap needs to be updated + if (n < vif_entry->u.ap.tim_n1) { + // Lower limit shall be an even number + vif_entry->u.ap.tim_n1 = n & 0xFE; + // Update the start pointer in the TBD + pbd_bmp->datastartptr = tim_bmp + vif_entry->u.ap.tim_n1; + } + + // Check if Upper limit of the partial virtual bitmap needs to be updated + if (n > vif_entry->u.ap.tim_n2) { + // Update Upper limit + vif_entry->u.ap.tim_n2 = n; + + // Update the end pointer in the TBD + pbd_bmp->dataendptr = tim_bmp + vif_entry->u.ap.tim_n2; + } + + // Update the TIM length + vif_entry->u.ap.tim_len = vif_entry->u.ap.tim_n2 - vif_entry->u.ap.tim_n1 + 6; + + // Update the TIM PBD + co_write8p(tim_ie + MAC_TIM_LEN_OFT, vif_entry->u.ap.tim_len - 2); + co_write8p(tim_ie + MAC_TIM_BMPC_OFT, vif_entry->u.ap.tim_n1); + + pbd_tim->dataendptr = tim_ie + MAC_TIM_BMPC_OFT; + pbd_tim->next = CPU2HW(pbd_bmp); + } else if ((param->tx_avail != 0) && pass) { + // Reset the bit in the bitmap + co_write8p(tim_bmp + n, val & ~mask); + + // One more bit is reset + vif_entry->u.ap.tim_bitmap_set--; + + // Check if the bitmap has still some bits set + if (vif_entry->u.ap.tim_bitmap_set) { + // Check if we need to update the Lower Limit + if ((n & 0xFE) == vif_entry->u.ap.tim_n1) { + // Search for the new Lower Limit + while ((vif_entry->u.ap.tim_n1 != MAC_TIM_SIZE) && + (co_read8p(tim_bmp + vif_entry->u.ap.tim_n1) == 0)) { + vif_entry->u.ap.tim_n1++; + } + + // Lower Limit shall be an even number + vif_entry->u.ap.tim_n1 &= 0xFE; + + // Update the start pointer in the TBD + pbd_bmp->datastartptr = tim_bmp + vif_entry->u.ap.tim_n1; + } + + // Check if we need to update the Upper Limit + if (n == vif_entry->u.ap.tim_n2) { + // Search for the new Upper Limit + while ((vif_entry->u.ap.tim_n2 != 0) && + (co_read8p(tim_bmp + vif_entry->u.ap.tim_n2) == 0)) { + vif_entry->u.ap.tim_n2--; + } + + // Update the end pointer in the TBD + pbd_bmp->dataendptr = tim_bmp + vif_entry->u.ap.tim_n2; + } + + // Update the TIM length + vif_entry->u.ap.tim_len = vif_entry->u.ap.tim_n2 - vif_entry->u.ap.tim_n1 + 6; + + // Update the TIM PBD + co_write8p(tim_ie + MAC_TIM_LEN_OFT, vif_entry->u.ap.tim_len - 2); + co_write8p(tim_ie + MAC_TIM_BMPC_OFT, vif_entry->u.ap.tim_n1); + } else { + // Update the TIM + vif_entry->u.ap.tim_len = MAC_TIM_BMP_OFT + 1; + vif_entry->u.ap.tim_n1 = (uint8_t)-1; + vif_entry->u.ap.tim_n2 = 0; + co_write8p(tim_ie + MAC_TIM_LEN_OFT, vif_entry->u.ap.tim_len - 2); + co_write8p(tim_ie + MAC_TIM_BMPC_OFT, 0); + // Update the TIM PBD + pbd_tim->dataendptr = tim_ie + MAC_TIM_BMP_OFT; + pbd_tim->next = CPU2HW(&txl_bcn_end_desc);//[param->inst_nbr]); + // Update the end pointer in the TBD + pbd_bmp->dataendptr = tim_bmp + vif_entry->u.ap.tim_n2; + } + } + } + + ke_msg_send_basic(MM_TIM_UPDATE_CFM, ke_param2msg(param)->src_id, TASK_MM); + ke_msg_free(ke_param2msg(param)); +} + +static void mm_bcn_desc_prep(struct vif_info_tag *vif_entry, const struct mm_bcn_change_req *param) { + struct txl_frame_desc_tag *frame = &vif_entry->u.ap.bcn_desc; + uint32_t vif_index = vif_entry->index; + struct tx_hd *thd = &frame->txdesc.lmac.hw_desc->thd; + struct tx_pbd *pbd_bcn = &txl_bcn_end_desc; //+ vif_index; + uint32_t tim_bcn = thd->datastartptr + param->tim_oft; + uint32_t tim_ie = CPU2HW(&txl_tim_ie_pool[0]); // CPU2HW(&txl_tim_ie_pool[vif_index][0]); + struct tx_policy_tbl *pol; + uint8_t band; + uint32_t bcn_len = param->bcn_len - param->tim_len; + + vif_entry->u.ap.bcn_len = bcn_len; + + // Verify the protection and bandwidth status + me_beacon_check(vif_index, param->bcn_len, thd->datastartptr); + + // Fill-up the TX header descriptor + thd->dataendptr = thd->datastartptr + param->tim_oft - 1; + pbd_bcn->datastartptr = thd->dataendptr + param->tim_len + 1; + pbd_bcn->dataendptr = pbd_bcn->datastartptr + bcn_len - param->tim_oft - 1; + pbd_bcn->bufctrlinfo = 0; + + // Get band + #if NX_CHNL_CTXT + band = vif_entry->chan_ctxt->channel.band; + #else + phy_get_channel(&info, PHY_PRIM); + band = info.info1 & 0xFF; + #endif + + { + pol = (band == PHY_BAND_2G4) ? &txl_buffer_control_24G.policy_tbl : &txl_buffer_control_5G.policy_tbl; + } + + // Set TX power + pol->powercntrlinfo[0] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; + thd->policyentryaddr = CPU2HW(pol); + thd->phyctrlinfo = 0; + thd->macctrlinfo2 = 0; + thd->first_pbd_ptr = CPU2HW(&txl_tim_desc[0]); // CPU2HW(&txl_tim_desc[vif_index][0]); + + // The beacon is now configured for this VIF + vif_entry->u.ap.bcn_configured = true; + co_write8p(tim_ie + MAC_TIM_PERIOD_OFT, co_read8p(tim_bcn + MAC_TIM_PERIOD_OFT)); +} + +static void mm_bcn_csa_init(struct vif_info_tag *vif_entry, const struct mm_bcn_change_req *param) { + struct txl_frame_desc_tag *frame = &vif_entry->u.ap.bcn_desc; + struct tx_hd *thd = &frame->txdesc.lmac.hw_desc->thd; + + // reset value + vif_entry->u.ap.csa_count = 0; + for (int i = 0; i < BCN_MAX_CSA_CPT; i++) + vif_entry->u.ap.csa_oft[i] = param->csa_oft[i]; + + if (param->csa_oft[0] > 0) + vif_entry->u.ap.csa_count = co_read8p(thd->datastartptr + param->csa_oft[0]) + 1; +} + +static void mm_bcn_send_csa_counter_ind(uint8_t vif_index, uint8_t csa_count) { + struct mm_csa_counter_ind *ind = KE_MSG_ALLOC(MM_CSA_COUNTER_IND, TASK_API, TASK_MM, mm_csa_counter_ind); + ind->vif_index = vif_index; + ind->csa_count = csa_count; + + ke_msg_send(ind); +} + +static uint8_t mm_bcn_build(struct vif_info_tag *vif_entry) { + struct txl_frame_desc_tag *frame = &vif_entry->u.ap.bcn_desc; + struct tx_hd *thd = &frame->txdesc.lmac.hw_desc->thd; + uint32_t tim_ie = CPU2HW(&txl_tim_ie_pool[0]); // CPU2HW(&txl_tim_ie_pool[vif_entry->index][0]); + uint8_t bmpc = co_read8p(tim_ie + MAC_TIM_BMPC_OFT); + + thd->frmlen = vif_entry->u.ap.bcn_len + vif_entry->u.ap.tim_len + MAC_FCS_LEN; + + co_write16(HW2CPU(thd->datastartptr + MAC_HEAD_CTRL_OFT), txl_get_seq_ctrl()); + + co_write8p(tim_ie + MAC_TIM_CNT_OFT, vif_entry->u.ap.dtim_count); + + // Update DTIM count for next beacon + if (vif_entry->u.ap.dtim_count == 0) { + // alios one only has (vif_entry->u.ap.bc_mc_status) + if ((vif_entry->u.ap.bc_mc_status) || ipc_emb_tx_q_has_data(0)) + bmpc |= MAC_TIM_BCMC_PRESENT; + else + bmpc &= ~MAC_TIM_BCMC_PRESENT; + vif_entry->u.ap.dtim_count = co_read8p(tim_ie + MAC_TIM_PERIOD_OFT); + } else { + // alios only does bmpc &= ~MAC_TIM_BCMC_PRESENT + bmpc &= ~MAC_TIM_BCMC_PRESENT; + if (vif_entry->u.ap.bc_mc_status & 2) + bmpc |= MAC_TIM_BCMC_PRESENT; + + } + // I've no idea, but the bl602 always write bmpc | MAC_TIM_BCMC_PRESENT here + // TODO: verify me + co_write8p(tim_ie + MAC_TIM_BMPC_OFT, bmpc | MAC_TIM_BCMC_PRESENT); + vif_entry->u.ap.dtim_count--; + + // Update CSA counter in the beacon + if (vif_entry->u.ap.csa_count) { + vif_entry->u.ap.csa_count --; + for (int i = 0; i < BCN_MAX_CSA_CPT; i++) { + if (vif_entry->u.ap.csa_oft[i] == 0) + break; + co_write8p((uint32_t)HW2CPU(thd->datastartptr) + vif_entry->u.ap.csa_oft[i], + vif_entry->u.ap.csa_count); + } + if (vif_entry->u.ap.csa_count) + mm_bcn_send_csa_counter_ind(vif_entry->index, vif_entry->u.ap.csa_count); + // keep csa_count to 1 until beacon is successfully transmistted + if (vif_entry->u.ap.csa_count == 0) + vif_entry->u.ap.csa_count = 1; + } + + tpc_update_frame_tx_power(vif_entry, frame); + + return bmpc & MAC_TIM_BCMC_PRESENT; +} + +static void mm_bcn_updated(void *env, int dma_queue) { + struct vif_info_tag *vif_entry = (struct vif_info_tag *) env; + struct ke_msg *msg = ke_param2msg(mm_bcn_env.param); + + ke_msg_send_basic(MM_BCN_CHANGE_CFM, msg->src_id, TASK_MM); + + mm_bcn_desc_prep(vif_entry, mm_bcn_env.param); + + mm_bcn_csa_init(vif_entry, mm_bcn_env.param); + + mm_bcn_env.update_ongoing = false; + if (mm_bcn_env.tx_pending) + mm_bcn_transmit(); + + mm_bcn_env.param = NULL; + ke_msg_free(msg); +} + +static void mm_bcn_update(const struct mm_bcn_change_req *param) { + // param->inst_nbr <= 2? + //struct txl_buffer_tag *buffer = (struct txl_buffer_tag *)&txl_bcn_pool[param->inst_nbr]; + struct txl_buffer_tag *buffer = (struct txl_buffer_tag *)&txl_bcn_pool; + memcpy(buffer->payload, param->bcn_buf, param->bcn_len); + mm_bcn_env.update_pending = false; + mm_bcn_env.update_ongoing = true; + mm_bcn_updated(vif_info_tab + param->inst_nbr, 0); +} + +static void mm_bcn_transmitted(void *env, uint32_t status) { + ASSERT_ERR(mm_bcn_env.tx_cfm); + + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)env; + if (--mm_bcn_env.tx_cfm == 0) { + if (mm_bcn_env.update_pending != false) { + mm_bcn_update(mm_bcn_env.param); + } + } + + while (! co_list_is_empty(&mm_bcn_env.tim_list)) { + struct ke_msg *msg = (struct ke_msg*) co_list_pop_front(&mm_bcn_env.tim_list); + mm_tim_update_proceed((struct mm_tim_update_req *)ke_msg2param(msg)); + } + + if (p_vif_entry->u.ap.csa_count == 1) { + vif_mgmt_switch_channel(p_vif_entry); + } + +} + +static void mm_bcn_init_tim(struct vif_info_tag *vif_entry) { + uint8_t inst_nbr = vif_entry->index; + struct tx_pbd *pbd = &txl_tim_desc[0]; // &txl_tim_desc[inst_nbr][0]; + uint32_t tim_ie = CPU2HW(&txl_tim_ie_pool[0]); // CPU2HW(&txl_tim_ie_pool[inst_nbr][0]); + uint32_t tim_bmp = CPU2HW(&txl_tim_bitmap_pool[0]); // CPU2HW(&txl_tim_bitmap_pool[inst_nbr][0]); + + // Initialize the DTIM count + vif_entry->u.ap.dtim_count = 0; + vif_entry->u.ap.tim_len = MAC_TIM_BMP_OFT + 1; + vif_entry->u.ap.tim_bitmap_set = 0; + vif_entry->u.ap.tim_n1 = (uint8_t)-1; + vif_entry->u.ap.tim_n2 = 0; + vif_entry->u.ap.bc_mc_status = 0; + + // First part of the TIM + pbd->upatterntx = TX_PAYLOAD_DESC_PATTERN; + pbd->datastartptr = tim_ie + MAC_TIM_ID_OFT; + pbd->dataendptr = tim_ie + MAC_TIM_BMP_OFT; + pbd->next = CPU2HW(&txl_bcn_end_desc);///[inst_nbr]); + pbd->bufctrlinfo = 0; + co_write8p(tim_ie + MAC_TIM_ID_OFT, MAC_ELTID_TIM); + co_write8p(tim_ie + MAC_TIM_LEN_OFT, 4); + co_write8p(tim_ie + MAC_TIM_CNT_OFT, vif_entry->u.ap.dtim_count); + co_write8p(tim_ie + MAC_TIM_PERIOD_OFT, 1); // Will be updated when receiving the beacon from host + co_write8p(tim_ie + MAC_TIM_BMPC_OFT, 0); + co_write8p(tim_ie + MAC_TIM_BMP_OFT, 0xff); // 0xff instead of 0 + + // Reset the TIM virtual bitmap + pbd = &txl_tim_desc[1]; // &txl_tim_desc[inst_nbr][1]; + pbd->upatterntx = TX_PAYLOAD_DESC_PATTERN; + pbd->dataendptr = tim_bmp + vif_entry->u.ap.tim_n2; + pbd->next = CPU2HW(&txl_bcn_end_desc);//[inst_nbr]); + //memset(txl_tim_bitmap_pool[inst_nbr], 0, sizeof(txl_tim_bitmap_pool[inst_nbr])); + memset(txl_tim_bitmap_pool, 0, sizeof(txl_tim_bitmap_pool)); + + // Initialize post-TIM TX PBD + pbd = &txl_bcn_end_desc;//[inst_nbr]; + pbd->upatterntx = TX_PAYLOAD_DESC_PATTERN; + pbd->next = 0; + pbd->bufctrlinfo = 0; +} + +void mm_bcn_init(void) { + memset(&mm_bcn_env, 0, sizeof(struct mm_bcn_env_tag)); + mm_bcn_env.dma.dma_desc = &bcn_dwnld_desc; + mm_bcn_env.dma.cb = mm_bcn_updated; + co_list_init(&mm_bcn_env.tim_list); +} + +void mm_bcn_init_vif(struct vif_info_tag *vif_entry) { + struct txl_frame_desc_tag *frame = &vif_entry->u.ap.bcn_desc; + struct txl_buffer_tag *buffer = (struct txl_buffer_tag *)&txl_bcn_pool; //(struct txl_buffer_tag *)&txl_bcn_pool[vif_entry->index][0]; + struct tx_hw_desc *hwdesc = &txl_bcn_hwdesc_pool //&txl_bcn_hwdesc_pool[vif_entry->index]; + struct txl_buffer_control *bufctrl = &txl_bcn_buf_ctrl;//[vif_entry->index]; + struct tx_hd *thd; + + // Initialize the frame descriptor + txl_frame_init_desc(frame, buffer, hwdesc, bufctrl); + + // Initialize the TIM buffer + mm_bcn_init_tim(vif_entry); + + // Initialize some static fields of the THD + thd = &frame->txdesc.lmac.hw_desc->thd; + thd->phyctrlinfo = 0; + thd->macctrlinfo2 = 0; + thd->first_pbd_ptr = 0; + + // Initialize callback function + frame->cfm.cfm_func = mm_bcn_transmitted; + frame->cfm.env = vif_entry; +} + +void mm_bcn_change(const struct mm_bcn_change_req *param) { + if (mm_bcn_env.tx_cfm != 0) { + mm_bcn_env.param = param; + mm_bcn_env.update_pending = true; + return; + } else { + mm_bcn_env.param = param; + mm_bcn_update(param); + } +} + +void mm_tim_update(const struct mm_tim_update_req *param) { + if (mm_bcn_env.tx_cfm != 0) { + co_list_push_back(&mm_bcn_env.tim_list, &ke_param2msg(param)->hdr); + } + mm_tim_update_proceed(param); +} + +void mm_bcn_transmit(void) { + ASSERT_ERR(!mm_bcn_env.tx_cfm); + if (mm_bcn_env.update_ongoing == false) { + mm_bcn_env.tx_pending = false; + for (struct vif_info_tag * vif = vif_mgmt_first_used(); vif; vif = vif_mgmt_next(vif)) { + if ((vif->type == VIF_AP) && (vif->u.ap.bcn_configured) && (vif->u.ap.bcn_tbtt_cnt == vif->u.ap.bcn_tbtt_ratio)) { + mm_bcn_build(vif); + // bl602 put all the code inside chan_is_on_operational_channel(vif), + // alios check the return value of mm_bcn_build and only does + // mm_traffic_req_ind(VIF_TO_BCMC_IDX(vif->index), 0, false); + if (chan_is_on_operational_channel(vif)) { + mm_traffic_req_ind(VIF_TO_BCMC_IDX(vif->index), 0, false); + #if (NX_CHNL_CTXT || NX_P2P_GO) + // Set VIF and STA indexes + vif->u.ap.bcn_desc.txdesc.host.vif_idx = vif->index; + vif->u.ap.bcn_desc.txdesc.host.staid = 0xff; + + if (txl_frame_push(&vif->u.ap.bcn_desc, AC_BCN)) { + mm_bcn_env.tx_cfm++; + } + #else + txl_frame_push(&vif->u.ap.bcn_desc, AC_BCN); + mm_bcn_env.tx_cfm++; + #endif //(NX_CHNL_CTXT || NX_P2P_GO) + struct sta_info_tag* p_sta_info = sta_info_tab + VIF_TO_BCMC_IDX(vif->index); + if ((p_sta_info->traffic_avail & PS_TRAFFIC_INT) != 0) { + p_sta_info->ps_service_period = PS_SERVICE_PERIOD | BCN_SERVICE_PERIOD; + sta_mgmt_send_postponed_frame(vif, p_sta_info, 0); + p_sta_info->ps_service_period = NO_SERVICE_PERIOD; + } + } + } + } + } else mm_bcn_env.tx_pending = true; +} diff --git a/src/bl602_wifi/ip/lmac/mm/mm_task.c b/src/bl602_wifi/ip/lmac/mm/mm_task.c new file mode 100644 index 0000000..132d8db --- /dev/null +++ b/src/bl602_wifi/ip/lmac/mm/mm_task.c @@ -0,0 +1,925 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include +#include + + +int bl60x_edca_get(int ac, uint8_t *aifs, uint8_t *cwmin, uint8_t *cwmax, uint16_t *txop) { + switch (ac) { + case 0: + EXTRACT(MAC_CORE->EDCA_AC_0, edca_ac) { + *aifs = edca_ac.aifsn0; + *cwmin = edca_ac.cwMin0; + *cwmax = edca_ac.cwMax0; + *txop = edca_ac.txOpLimit0; + } + break; + case 1: + EXTRACT(MAC_CORE->EDCA_AC_1, edca_ac) { + *aifs = edca_ac.aifsn1; + *cwmin = edca_ac.cwMin1; + *cwmax = edca_ac.cwMax1; + *txop = edca_ac.txOpLimit1; + } + break; + case 2: + EXTRACT(MAC_CORE->EDCA_AC_2, edca_ac) { + *aifs = edca_ac.aifsn2; + *cwmin = edca_ac.cwMin2; + *cwmax = edca_ac.cwMax2; + *txop = edca_ac.txOpLimit2; + } + break; + case 3: + EXTRACT(MAC_CORE->EDCA_AC_3, edca_ac) { + *aifs = edca_ac.aifsn3; + *cwmin = edca_ac.cwMin3; + *cwmax = edca_ac.cwMax3; + *txop = edca_ac.txOpLimit3; + } + break; + default: + return -1; + } + return 0; +} + +static int mm_version_req_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_version_cfm *msg = (struct mm_version_cfm *)ke_msg_alloc(MM_VERSION_CFM, src_id, dest_id, sizeof(struct mm_version_cfm)); + msg->version_lmac = NX_VERSION; + msg->version_machw_1 = MAC_CORE->VERSION_1.value; + msg->version_machw_2 = MAC_CORE->VERSION_2.value; + phy_get_version(&msg->version_phy_1, &msg->version_phy_2); + msg->features = (0 + #if (NX_BEACONING) + | CO_BIT(MM_FEAT_BCN_BIT) + #endif //(NX_BEACONING) + #if (NX_BCN_AUTONOMOUS_TX) + | CO_BIT(MM_FEAT_AUTOBCN_BIT) + #endif //(NX_BCN_AUTONOMOUS_TX) + #if (NX_HW_SCAN) + | CO_BIT(MM_FEAT_HWSCAN_BIT) + #endif //(NX_HW_SCAN) + #if (NX_CONNECTION_MONITOR) + | CO_BIT(MM_FEAT_CMON_BIT) + #endif //(NX_CONNECTION_MONITOR) + #if (NX_MULTI_ROLE) + | CO_BIT(MM_FEAT_MROLE_BIT) + #endif //(NX_MULTI_ROLE) + #if (NX_RADAR_DETECT) + | CO_BIT(MM_FEAT_RADAR_BIT) + #endif //(NX_RADAR_DETECT) + #if (NX_POWERSAVE) + | CO_BIT(MM_FEAT_PS_BIT) + #endif //(NX_POWERSAVE) + #if (NX_UAPSD) + | CO_BIT(MM_FEAT_UAPSD_BIT) + #endif //(NX_UAPSD) + #if (NX_DPSM) + | CO_BIT(MM_FEAT_DPSM_BIT) + #endif //(NX_DPSM) + #if (NX_AMPDU_TX) + | CO_BIT(MM_FEAT_AMPDU_BIT) + #endif //(NX_AMPDU_TX) + #if (NX_AMSDU_TX) + | CO_BIT(MM_FEAT_AMSDU_BIT) + #endif //(NX_AMSDU_TX) + #if (NX_CHNL_CTXT) + | CO_BIT(MM_FEAT_CHNL_CTXT_BIT) + #endif //(NX_CHNL_CTXT) + #if (NX_P2P) + | CO_BIT(MM_FEAT_P2P_BIT) + #endif //(NX_P2P) + #if (NX_P2P_GO) + | CO_BIT(MM_FEAT_P2P_GO_BIT) + #endif //(NX_P2P_GO) + | CO_BIT(MM_FEAT_UMAC_BIT) + #if (NX_REORD) + | CO_BIT(MM_FEAT_REORD_BIT) + #endif //(NX_REORD) + #if (NX_MFP) + | CO_BIT(MM_FEAT_MFP_BIT) + #endif //(NX_MFP) + #if (RW_MESH_EN) + | CO_BIT(MM_FEAT_MESH_BIT) + #endif //(RW_MESH_EN) + #if (TDLS_ENABLE) + | CO_BIT(MM_FEAT_TDLS_BIT) + #endif //(TDLS_ENABLE) + ); + + #if (RW_BFMEE_EN) + if (hal_machw_bfmee_support()) + msg->features |= CO_BIT(MM_FEAT_BFMEE_BIT); + #endif //(RW_BFMEE_EN) + + #if (RW_BFMER_EN) + msg->features |= CO_BIT(MM_FEAT_BFMER_BIT); + #endif //(RW_BFMER_EN) + + #if (RW_MUMIMO_RX_EN) + if (hal_machw_mu_mimo_rx_support()) + msg->features |= CO_BIT(MM_FEAT_MU_MIMO_RX_BIT); + #endif //(RW_MUMIMO_RX_EN) + + #if (RW_MUMIMO_TX_EN) + msg->features |= CO_BIT(MM_FEAT_MU_MIMO_TX_BIT); + #endif //(RW_MUMIMO_TX_EN) + + #if (RW_WAPI_EN) + if (nxmac_wapi_getf()) + msg->features |= CO_BIT(MM_FEAT_WAPI_BIT); + #endif //(RW_WAPI_EN) + + #if (NX_VHT) + msg->features |= CO_BIT(MM_FEAT_UMAC_VHT_BIT); + #endif + + ke_msg_send((void*) msg); + + return KE_MSG_CONSUMED; +} + +static int mm_reset_req_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + __disable_irq(); + hal_machw_stop(); + phy_stop(); + me_init(); + mm_init(); + __enable_irq(); + ke_msg_send_basic(MM_RESET_CFM, src_id, dest_id); + ke_state_set(TASK_MM, MM_IDLE); + return KE_MSG_CONSUMED; +} + +static int mm_start_req_handler(const ke_msg_id_t msgid, const struct mm_start_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + ASSERT_ERR(ke_state_get(dest_id) == MM_IDLE); + + phy_init(¶m->phy_cfg); + + phy_set_channel(PHY_BAND_2G4, PHY_CHNL_BW_20, 2412, 2412, 0, PHY_PRIM); + tpc_update_tx_power(15); + + #if NX_UAPSD + ps_env.uapsd_timeout = param->uapsd_timeout * MILLI2MICRO; + #endif + + #if NX_POWERSAVE + mm_env.lp_clk_accuracy = param->lp_clk_accuracy; + #endif + + ke_msg_send_basic(MM_START_CFM, src_id, dest_id); + + mm_active(); + hal_machw_idle_req(); + + ke_state_set(dest_id, MM_GOING_TO_IDLE); + + return KE_MSG_CONSUMED; +} +#if (!NX_CHNL_CTXT) +static int mm_set_channel_req_handler(const ke_msg_id_t msgid, const struct mm_set_channel_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + // not used +} +#else +static int mm_set_channel_req_handler(const ke_msg_id_t msgid, const struct mm_set_channel_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_set_channel_cfm *cfm; + cfm = KE_MSG_ALLOC(MM_SET_CHANNEL_CFM, src_id, dest_id, mm_set_channel_cfm); + if (param->index != PHY_PRIM) { + phy_set_channel(param->band, param->type, param->prim20_freq, param->center1_freq, param->center2_freq, param->index); + } + ke_msg_send((void*) cfm); + return KE_MSG_CONSUMED; +} +#endif + +static int mm_set_dtim_req_handler(const ke_msg_id_t msgid, const struct mm_set_dtim_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + MAC_CORE->DTIM_CFP_1.dtimPeriod = param->dtim_period; + MAC_CORE->DTIM_CFP_1.dtimUpdatedBySW = 1; + + ke_msg_send_basic(MM_SET_DTIM_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_beacon_int_req_handler(const ke_msg_id_t msgid, const struct mm_set_beacon_int_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + if (vif_entry->type == VIF_STA) { + #if (NX_MULTI_ROLE) + { + struct sta_info_tag *p_sta_entry = sta_info_tab + vif_entry->u.sta.ap_id; + p_sta_entry->bcn_int = param->beacon_int * TU_DURATION; + } + #else //(NX_MULTI_ROLE) + MAC_CORE->BCN_CNTRL_1.beaconInt = param->beacon_int * TU_DURATION; + #endif //(NX_MULTI_ROLE) + } else { + vif_mgmt_set_ap_bcn_int(vif_entry, param->beacon_int); + } + + ke_msg_send_basic(MM_SET_BEACON_INT_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_basic_rates_req_handler(const ke_msg_id_t msgid, const struct mm_set_basic_rates_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + #if NX_CHNL_CTXT + struct chan_ctxt_tag *chan = chan_env.current_channel; + mm_env.basic_rates[param->band] = param->rates; + + if (chan && (chan->channel.band == param->band)) + MAC_CORE->RATES.value = 0x10; // bl602 always set this value to 0x10 + #else + MAC_CORE->RATES.value = param->rates; + #endif + + ke_msg_send_basic(MM_SET_BASIC_RATES_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_filter_req_handler(const ke_msg_id_t msgid, const struct mm_set_filter_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + mm_env.rx_filter_umac = param->filter; + MAC_CORE->RX_CNTRL.value = mm_env.rx_filter_umac | mm_env.rx_filter_lmac_enable; + + ke_msg_send_basic(MM_SET_FILTER_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_bssid_req_handler(const ke_msg_id_t msgid, const struct mm_set_bssid_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + #if NX_MULTI_ROLE + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + memcpy(&vif_entry->bssid, ¶m->bssid, sizeof(param->bssid)); + + if (vif_mgmt_used_cnt() == 1) + #endif + { + MAC_CORE->BSS_ID_LOW.value = *(uint32_t*) &(param->bssid.array); + MAC_CORE->BSS_ID_HI.value = param->bssid.array[2]; + } + + ke_msg_send_basic(MM_SET_BSSID_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_edca_req_handler(const ke_msg_id_t msgid, const struct mm_set_edca_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + vif_entry->txq_params[param->hw_queue] = param->ac_param; + + if (vif_entry->active) { + switch (param->hw_queue) { + case AC_BK: + MAC_CORE->EDCA_AC_0.value = param->ac_param; + break; + case AC_BE: + MAC_CORE->EDCA_AC_1.value = param->ac_param; + break; + case AC_VI: + MAC_CORE->EDCA_AC_2.value = param->ac_param; + break; + default: + MAC_CORE->EDCA_AC_3.value = param->ac_param; + break; + } + + mm_env_max_ampdu_duration_set(); + } + + #if NX_UAPSD + if (vif_entry->type == VIF_STA) { + ps_uapsd_set(vif_entry, param->hw_queue, param->uapsd); + } + #endif + + ke_msg_send_basic(MM_SET_EDCA_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_slottime_req_handler(const ke_msg_id_t msgid, const struct mm_set_slottime_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + uint16_t mac_core_clk = MAC_CORE->TIMINGS_1.macCoreClkFreq; + + PACK0(MAC_CORE->TIMINGS_2, timings2) { + timings2.slotTimeInMACClk = mac_core_clk * param->slottime; + timings2.slotTime = param->slottime; + } + + ke_msg_send_basic(MM_SET_SLOTTIME_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_mode_req_handler(const ke_msg_id_t msgid, const struct mm_set_mode_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + MAC_CORE->MAC_CNTRL_1.abgnMode = param->abgnmode; + + ke_msg_send_basic(MM_SET_MODE_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_vif_state_req_handler(const ke_msg_id_t msgid, const struct mm_set_vif_state_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + if (vif_entry->type == VIF_STA) { + if (param->active) { + struct sta_info_tag *p_sta_entry = &sta_info_tab[vif_entry->u.sta.ap_id]; + #if NX_POWERSAVE + uint32_t drift; + #endif + #if NX_MULTI_ROLE + uint32_t next_tbtt = ke_time() + p_sta_entry->bcn_int; + mm_timer_set(&vif_entry->tbtt_timer, next_tbtt); + #endif + + p_sta_entry->aid = param->aid; + + #if NX_POWERSAVE + vif_entry->u.sta.listen_interval = 0; + vif_entry->u.sta.dont_wait_bcmc = false; + + drift = ((uint32_t)(mm_env.lp_clk_accuracy + MM_AP_CLK_ACCURACY) * + (uint32_t)p_sta_entry->bcn_int) / 1000000; + p_sta_entry->drift = (uint16_t)drift; + + #if NX_UAPSD + vif_entry->u.sta.uapsd_last_rxtx = ke_time(); + #endif + vif_entry->prevent_sleep |= PS_VIF_WAITING_BCN; + #endif + + #if NX_CONNECTION_MONITOR + // Reset the beacon loss count and keep-alive frame time + vif_entry->u.sta.beacon_loss_cnt = 0; + vif_entry->u.sta.mon_last_crc = 0; + vif_entry->u.sta.mon_last_tx = ke_time(); + #endif + + #if (NX_CHNL_CTXT) + chan_bcn_detect_start(vif_entry); + #endif //(NX_CHNL_CTXT) + } else { + #if NX_MULTI_ROLE + // Clear the TBTT timer + mm_timer_clear(&vif_entry->tbtt_timer); + #endif + } + } + + vif_entry->active = param->active; + + if (param->active) { + MAC_CORE->EDCA_AC_0.value = vif_entry->txq_params[AC_BK]; + MAC_CORE->EDCA_AC_1.value = vif_entry->txq_params[AC_BE]; + MAC_CORE->EDCA_AC_2.value = vif_entry->txq_params[AC_VI]; + MAC_CORE->EDCA_AC_3.value = vif_entry->txq_params[AC_VO]; + + mm_env_max_ampdu_duration_set(); + } + + ke_msg_send_basic(MM_SET_VIF_STATE_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_power_req_handler(const ke_msg_id_t msgid, const struct mm_set_power_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_set_power_cfm *cfm; + struct vif_info_tag *vif_entry = vif_info_tab + param->inst_nbr; + + cfm = KE_MSG_ALLOC(MM_SET_POWER_CFM, src_id, dest_id, mm_set_power_cfm); + vif_entry->user_tx_power = param->power; + cfm->power = vif_entry->tx_power; + vif_entry->tx_power = VIF_UNDEF_POWER; + tpc_update_vif_tx_power(vif_entry, &cfm->power, &cfm->radio_idx); + + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + +static int mm_add_if_req_handler(const ke_msg_id_t msgid, const struct mm_add_if_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_add_if_cfm *cfm; + + cfm = KE_MSG_ALLOC(MM_ADD_IF_CFM, src_id, dest_id, mm_add_if_cfm); + + cfm->status = vif_mgmt_register(¶m->addr, param->type, param->p2p, &cfm->inst_nbr); + + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + +static int mm_remove_if_req_handler(const ke_msg_id_t msgid, const struct mm_remove_if_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + if (param->inst_nbr < NX_VIRT_DEV_MAX) + vif_mgmt_unregister(param->inst_nbr); + + if (co_list_is_empty(&vif_mgmt_env.used_list)) + hal_machw_monitor_mode(); // not hal_machw_enter_monitor_mode(); + + ke_msg_send_basic(MM_REMOVE_IF_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_set_idle_req_handler(const ke_msg_id_t msgid, const struct mm_set_idle_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + if (ke_state_get(dest_id) == MM_HOST_BYPASSED) { + return KE_MSG_SAVED; + } + + mm_env.host_idle = param->hw_idle; + + if (param->hw_idle) { + switch (ke_state_get(dest_id)) { + case MM_IDLE: + ASSERT_ERR(MAC_CORE->STATE_CNTRL.currentState == HW_IDLE); + mm_env.prev_mm_state = MM_IDLE; + mm_env.prev_hw_state = HW_IDLE; + break; + case MM_GOING_TO_IDLE: + return KE_MSG_SAVED; + + default: + hal_machw_idle_req(); + ke_state_set(dest_id, MM_GOING_TO_IDLE); + + return KE_MSG_SAVED; + } + } else { + if (ke_state_get(dest_id) == MM_GOING_TO_IDLE) + return KE_MSG_SAVED; + mm_active(); + } + + ke_msg_send_basic(MM_SET_IDLE_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_force_idle_req_handler(const ke_msg_id_t msgid, const struct mm_force_idle_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + switch (ke_state_get(dest_id)){ + case MM_IDLE: + ASSERT_ERR(MAC_CORE->STATE_CNTRL.currentState == HW_IDLE); + break; + + case MM_GOING_TO_IDLE: + return KE_MSG_SAVED; + + default: + hal_machw_idle_req(); + ke_state_set(dest_id, MM_GOING_TO_IDLE); + + return KE_MSG_SAVED; + } + + ke_state_set(dest_id, MM_HOST_BYPASSED); + + param->cb(); + + return KE_MSG_CONSUMED; +} + +static int mm_sta_add_req_handler(const ke_msg_id_t msgid, const struct mm_sta_add_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_sta_add_cfm *rsp = KE_MSG_ALLOC(MM_STA_ADD_CFM, src_id, dest_id, mm_sta_add_cfm); + + rsp->status = mm_sta_add(param, &rsp->sta_idx, &rsp->hw_sta_idx); + + ke_msg_send((void*) rsp); + + return KE_MSG_CONSUMED; +} + +static int mm_sta_del_req_handler(const ke_msg_id_t msgid, const struct mm_sta_del_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id){ + mm_sta_del(param->sta_idx); + ke_msg_send_basic(MM_STA_DEL_CFM, src_id, dest_id); + return KE_MSG_CONSUMED; +} + +static int mm_key_add_req_handler(const ke_msg_id_t msgid, const struct mm_key_add_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + uint8_t hw_key_idx; + struct mm_key_add_cfm *cfm = + KE_MSG_ALLOC(MM_KEY_ADD_CFM, src_id, dest_id, mm_key_add_cfm); + + #if NX_MFP + ASSERT_ERR(param->key_idx < MAC_DEFAULT_MFP_KEY_COUNT); + #else + ASSERT_ERR(param->key_idx < MAC_DEFAULT_KEY_COUNT); + #endif + + ASSERT_ERR(param->key.length <= MAC_SEC_KEY_LEN); + + ASSERT_ERR(param->cipher_suite <= MAC_RSNIE_CIPHER_AES_CMAC); + + hw_key_idx = mm_sec_machwkey_wr(param); + + cfm->hw_key_idx = hw_key_idx; + cfm->status = CO_OK; + + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + +static int mm_key_del_req_handler(const ke_msg_id_t msgid, const struct mm_key_del_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + ASSERT_ERR(param->hw_key_idx <= MM_SEC_MAX_KEY_NBR); + + mm_sec_machwkey_del(param->hw_key_idx); + ke_msg_send_basic(MM_KEY_DEL_CFM, src_id, dest_id); + return KE_MSG_CONSUMED; +} + +int mm_ba_add_req_handler(const ke_msg_id_t msgid, const struct mm_ba_add_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + uint8_t status = BA_AGMT_ESTABLISHED; + + + if (param->type == BA_AGMT_TX) { + #if (NX_AMPDU_TX) + #else + status = BA_AGMT_NOT_SUPPORTED; + #endif + } else { + #if (NX_REORD) + #endif + MAC_CORE->MAC_ERR_REC_CNTRL.baPSBitmapReset = 1; + } + + struct mm_ba_add_cfm *cfm = KE_MSG_ALLOC(MM_BA_ADD_CFM, src_id, dest_id, mm_ba_add_cfm); + + cfm->sta_idx = param->sta_idx; + cfm->tid = param->tid; + cfm->status = status; + + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + +int mm_chan_ctxt_update_req_handler(const ke_msg_id_t msgid, const struct mm_chan_ctxt_update_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + chan_ctxt_update(param); + + ke_msg_send_basic(MM_CHAN_CTXT_UPDATE_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} + +static int mm_remain_on_channel_req_handler(const ke_msg_id_t msgid, const struct mm_remain_on_channel_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + uint8_t status = chan_roc_req(param, src_id); + #if (TDLS_ENABLE) + if ((src_id != TASK_MM) && (src_id != TASK_TDLS)) + #else + if (src_id != TASK_MM) + #endif + { + // Send back the confirmation + struct mm_remain_on_channel_cfm *cfm = KE_MSG_ALLOC(MM_REMAIN_ON_CHANNEL_CFM, src_id, dest_id, mm_remain_on_channel_cfm); + + cfm->op_code = param->op_code; + cfm->status = status; + cfm->chan_ctxt_index = CHAN_ROC_CTXT_IDX; + + ke_msg_send((void*) cfm); + } + return KE_MSG_CONSUMED; +} + +static int mm_bcn_change_req_handler(const ke_msg_id_t msgid, const struct mm_bcn_change_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + mm_bcn_change(param); + return KE_MSG_CONSUMED; +} + +static int mm_tim_update_req_handler(const ke_msg_id_t msgid, const struct mm_tim_update_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + mm_tim_update(param); + return KE_MSG_CONSUMED; +} + +static int mm_hw_config_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + int status = KE_MSG_SAVED; + + switch (ke_state_get(dest_id)) { + case MM_IDLE: + ASSERT_ERR(MAC_CORE->STATE_CNTRL.currentState == HW_IDLE); + switch (msgid) { + case MM_SET_CHANNEL_REQ: // + status = mm_set_channel_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_FILTER_REQ: // + status = mm_set_filter_req_handler(msgid, param, dest_id, src_id); + break; + case MM_ADD_IF_REQ: // + status = mm_add_if_req_handler(msgid, param, dest_id, src_id); + break; + case MM_REMOVE_IF_REQ: // + status = mm_remove_if_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_BASIC_RATES_REQ: // + status = mm_set_basic_rates_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_BEACON_INT_REQ: // + status = mm_set_beacon_int_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_DTIM_REQ: // + status = mm_set_dtim_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_BSSID_REQ: // + status = mm_set_bssid_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_EDCA_REQ: // + status = mm_set_edca_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_SLOTTIME_REQ: // + status = mm_set_slottime_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_MODE_REQ: // + status = mm_set_mode_req_handler(msgid, param, dest_id, src_id); + break; + case MM_SET_VIF_STATE_REQ: // + status = mm_set_vif_state_req_handler(msgid, param, dest_id, src_id); + break; + case MM_BA_ADD_REQ: // + status = mm_ba_add_req_handler(msgid, param, dest_id, src_id); + break; + #if (NX_CHNL_CTXT) + case MM_CHAN_CTXT_UPDATE_REQ: // + status = mm_chan_ctxt_update_req_handler(msgid, param, dest_id, src_id); + break; + #endif //(NX_CHNL_CTXT) + default: + ASSERT_ERR(0); + break; + } + + PACK0(MAC_CORE->STATE_CNTRL, state) { + state.nextState = mm_env.prev_hw_state; + } + + ke_state_set(dest_id, mm_env.prev_mm_state); + break; + + case MM_GOING_TO_IDLE: + case MM_HOST_BYPASSED: + // MAC is currently going to IDLE, so simply save the message. It will be + // rescheduled once the MAC has switched to IDLE. + break; + + default: + // Store the current HW and MM states for later restoring + mm_env.prev_hw_state = MAC_CORE->STATE_CNTRL.currentState; + mm_env.prev_mm_state = ke_state_get(dest_id); + + // Request to MAC HW to switch to IDLE state + hal_machw_idle_req(); + + // Adjust the MM state accordingly + ke_state_set(dest_id, MM_GOING_TO_IDLE); + break; + } + + return (status); +} + +#if NX_POWERSAVE +void ps_polling_frame(struct vif_info_tag *vif_entry); +static int mm_set_ps_mode_req_handler(const ke_msg_id_t msgid, const struct mm_set_ps_mode_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_mgmt_first_used(); + + if (param->new_state == PS_DENOISE) { + // Unknown PS_MODE + for (; vif_entry; vif_entry = vif_mgmt_next(vif_entry)) { + if (vif_entry->type == VIF_STA) { + if (vif_entry->active != false) { + ps_polling_frame(vif_entry); + } + } + } + ke_msg_send_basic(MM_SET_PS_MODE_CFM, ps_env.taskid, TASK_MM); + } else { + ps_set_mode(param->new_state, src_id); + } + + return KE_MSG_CONSUMED; +} + + +static int mm_set_ps_options_req_handler(const ke_msg_id_t msgid, const struct mm_set_ps_options_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_info_tab + param->vif_index; + + ASSERT_ERR(vif_entry->type == VIF_STA); + + vif_entry->u.sta.listen_interval = param->listen_interval; + vif_entry->u.sta.dont_wait_bcmc = param->dont_listen_bc_mc; + + ke_msg_send_basic(MM_SET_PS_OPTIONS_CFM, src_id, dest_id); + + return KE_MSG_CONSUMED; +} +#endif + +static int mm_cfg_rssi_req_handler(const ke_msg_id_t msgid, const struct mm_cfg_rssi_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct vif_info_tag *vif_entry = vif_info_tab + param->vif_index; + + ASSERT_ERR(vif_entry->type == VIF_STA); + + vif_entry->u.sta.rssi_thold = param->rssi_thold; + vif_entry->u.sta.rssi_hyst = param->rssi_hyst; + vif_entry->u.sta.rssi_status = 0; + + return KE_MSG_CONSUMED; +} + +static int mm_monitor_enable_req_handler(const ke_msg_id_t msgid, const struct mm_monitor_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_monitor_cfm *cfm = KE_MSG_ALLOC(MM_MONITOR_CFM, src_id, dest_id, mm_monitor_cfm); + cfm->status = 1; + cfm->data[0] = 0; + cfm->data[1] = 0x11111111; + cfm->data[2] = 0x22222222; + cfm->data[3] = 0x33333333; + cfm->data[4] = 0x44444444; + cfm->data[5] = 0x55555555; + cfm->data[6] = 0x66666666; + cfm->data[7] = 0x77777777; + cfm->enable = param->enable; + struct phy_cfg_tag config; + memset(&config, 0, sizeof(struct phy_cfg_tag)); + config.parameters[0] = 0; + phy_init(&config); + phy_set_channel('\0','\0',0x985,0x985,0,'\0'); + mm_active(); + cfm->status = 0; + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + +static int mm_monitor_channel_req_handler(const ke_msg_id_t msgid, const struct mm_monitor_channel_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct mm_monitor_channel_cfm *cfm = KE_MSG_ALLOC(MM_MONITOR_CHANNEL_CFM, src_id, dest_id, mm_monitor_channel_cfm); + cfm->status = 1; + cfm->data[1] = 0x11111111; + cfm->data[2] = 0x22222222; + cfm->data[3] = 0x33333333; + cfm->data[4] = 0x44444444; + cfm->data[5] = 0x55555555; + cfm->data[6] = 0x66666666; + cfm->data[0] = 0; + cfm->data[7] = 0x77777777; + cfm->freq = param->freq; + + uint16_t center1_freq = (uint16_t)param->freq; + uint16_t prim20_freq = (uint16_t)param->freq; + if ((param->use_40Mhz != 0) && param->higher_band == 0) { + if (param->higher_band == 0) + center1_freq = prim20_freq - 10; + else + center1_freq = prim20_freq + 10; + } + phy_set_channel(0, param->use_40Mhz != 0, prim20_freq, center1_freq, 0, 0); + cfm->status = CO_OK; + ke_msg_send((void*) cfm); + + return KE_MSG_CONSUMED; +} + + +// TODO: verify this table +const struct ke_msg_handler mm_default_state[33] = { + + // From UMAC + {MM_START_REQ, (ke_msg_func_t)mm_start_req_handler}, + // From UMAC + {MM_VERSION_REQ, (ke_msg_func_t)mm_version_req_handler}, + + // From UMAC + {MM_ADD_IF_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_REMOVE_IF_REQ, (ke_msg_func_t)mm_hw_config_handler}, + + // From UMAC + {MM_RESET_REQ, (ke_msg_func_t)mm_reset_req_handler}, + + // From UMAC + {MM_SET_CHANNEL_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_BASIC_RATES_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_BEACON_INT_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_DTIM_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_FILTER_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_BSSID_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_EDCA_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_SLOTTIME_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_MODE_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_SET_VIF_STATE_REQ, (ke_msg_func_t)mm_hw_config_handler}, + + // From UMAC + {MM_SET_IDLE_REQ, (ke_msg_func_t)mm_set_idle_req_handler}, + // From internal + {MM_FORCE_IDLE_REQ, (ke_msg_func_t)mm_force_idle_req_handler}, + + // From UMAC + {MM_SET_POWER_REQ, (ke_msg_func_t)mm_set_power_req_handler}, + // From UMAC + {MM_KEY_ADD_REQ, (ke_msg_func_t)mm_key_add_req_handler}, + // From UMAC + {MM_KEY_DEL_REQ, (ke_msg_func_t)mm_key_del_req_handler}, + // From UMAC + {MM_STA_ADD_REQ, (ke_msg_func_t)mm_sta_add_req_handler}, + // From UMAC + {MM_STA_DEL_REQ, (ke_msg_func_t)mm_sta_del_req_handler}, + + // From UMAC + {MM_BA_ADD_REQ, (ke_msg_func_t)mm_hw_config_handler}, + #if (NX_AMPDU_TX || NX_REORD) + // From UMAC + {MM_BA_DEL_REQ, (ke_msg_func_t)mm_ba_del_req_handler}, + #endif + + #if (NX_CHNL_CTXT) + // From UMAC + {MM_CHAN_CTXT_UPDATE_REQ, (ke_msg_func_t)mm_hw_config_handler}, + // From UMAC + {MM_REMAIN_ON_CHANNEL_REQ, (ke_msg_func_t)mm_remain_on_channel_req_handler}, + #endif //(NX_CHNL_CTXT) + + #if NX_BCN_AUTONOMOUS_TX + // From UMAC + {MM_BCN_CHANGE_REQ, (ke_msg_func_t)mm_bcn_change_req_handler}, + // From UMAC + {MM_TIM_UPDATE_REQ, (ke_msg_func_t)mm_tim_update_req_handler}, + #endif + + #if NX_POWERSAVE + // From UMAC + {MM_DENOISE_REQ, (ke_msg_func_t)mm_set_ps_mode_req_handler}, + {MM_SET_PS_MODE_REQ, (ke_msg_func_t)mm_set_ps_mode_req_handler}, + // From UMAC + {MM_SET_PS_OPTIONS_REQ, (ke_msg_func_t)mm_set_ps_options_req_handler}, + #endif + + #if (NX_P2P_GO) + // From UMAC + {MM_SET_P2P_NOA_REQ, (ke_msg_func_t)mm_set_p2p_noa_req_handler}, + // From UMAC + {MM_SET_P2P_OPPPS_REQ, (ke_msg_func_t)mm_set_p2p_oppps_req_handler}, + #endif //(NX_P2P_GO) + + #if (RW_BFMER_EN) + // From UMAC + {MM_BFMER_ENABLE_REQ, (ke_msg_func_t)mm_bfmer_enable_req_handler}, + #endif //(RW_BFMER_EN) + #if (RW_MUMIMO_TX_EN) + // From UMAC + {MM_MU_GROUP_UPDATE_REQ, (ke_msg_func_t)mm_mu_group_update_req_handler}, + #endif //(RW_MUMIMO_TX_EN) + + {MM_CFG_RSSI_REQ, (ke_msg_func_t)mm_cfg_rssi_req_handler}, + + {MM_MONITOR_REQ, (ke_msg_func_t)mm_monitor_enable_req_handler}, + {MM_MONITOR_CHANNEL_REQ, (ke_msg_func_t)mm_monitor_channel_req_handler}, +}; + +const struct ke_state_handler mm_state_handler[MM_STATE_MAX] = { + /// IDLE State message handlers. + KE_STATE_HANDLER_NONE, // [MM_IDLE] = + /// JOIN State message handlers. + KE_STATE_HANDLER_NONE // [MM_ACTIVE] = +}; + +const struct ke_state_handler mm_default_handler = KE_STATE_HANDLER(mm_default_state); + +ke_state_t mm_state[MM_IDX_MAX]; diff --git a/src/bl602_wifi/ip/lmac/mm/mm_timer.c b/src/bl602_wifi/ip/lmac/mm/mm_timer.c new file mode 100644 index 0000000..2c36d58 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/mm/mm_timer.c @@ -0,0 +1,102 @@ +#include + +#include + +#include +#include + +#include + +#include + +#include + +#include +#include + +#include + +#include + +struct mm_timer_env_tag mm_timer_env; + +void mm_timer_init(void) { + co_list_init(&mm_timer_env.prog); +} + +static void mm_timer_hw_set(struct mm_timer_tag *timer) { + __disable_irq(); + if (!timer) { + MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers7 = 0; + } else { + MAC_CORE->ABS_TIMER[7] = timer->time; + if (MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers7 == 0) { + MAC_PL->TIMERS_INT_EVENT_CLEAR.value = 0x80; + MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers7 = 1; + } + } + __enable_irq(); +} + +static bool cmp_abs_time(const struct co_list_hdr *timerA, const struct co_list_hdr *timerB) { + uint32_t timeA = ((struct mm_timer_tag*)timerA)->time; + uint32_t timeB = ((struct mm_timer_tag*)timerB)->time; + + return (hal_machw_time_cmp(timeA, timeB)); +} + +// this 3 functions have no irq disable + +void mm_timer_set(struct mm_timer_tag *timer, uint32_t value) { + bool hw_prog = false; + if (hal_machw_time_past(value)) { + puts("\r\n-------------------[FW] Timer is past due to flash operation. Try to fix\r\n"); + value = hal_machw_time() + 3000; + } + if (co_list_pick(&mm_timer_env.prog) == (struct co_list_hdr*) timer) { + // pop the timer from the list + co_list_pop_front(&mm_timer_env.prog); + // force the HW timer to be reprogrammed + hw_prog = true; + } else { + co_list_extract(&mm_timer_env.prog, &timer->list_hdr); + } + timer->time = value; + co_list_insert(&mm_timer_env.prog, &timer->list_hdr, cmp_abs_time); + if (hw_prog || (co_list_pick(&mm_timer_env.prog) == &timer->list_hdr)) { + mm_timer_hw_set((struct mm_timer_tag *)co_list_pick(&mm_timer_env.prog)); + } + if (hal_machw_time_past(value)) { + ke_evt_set(KE_EVT_MM_TIMER_BIT); + } +} + +void mm_timer_clear(struct mm_timer_tag *timer) { + if (co_list_pick(&mm_timer_env.prog) == &timer->list_hdr) { + co_list_pop_front(&mm_timer_env.prog); + mm_timer_hw_set((struct mm_timer_tag *)co_list_pick(&mm_timer_env.prog)); + } else { + co_list_extract(&mm_timer_env.prog, &timer->list_hdr); + } +} + +void mm_timer_schedule(int dummy) { + while (true) { + ke_evt_clear(KE_EVT_MM_TIMER_BIT); + struct mm_timer_tag *timer = (struct mm_timer_tag *)co_list_pick(&mm_timer_env.prog); + if (!timer) { + mm_timer_hw_set((struct mm_timer_tag *)NULL); + break ; + } + + if (!hal_machw_time_past(timer->time - 50)) { + mm_timer_hw_set(timer); + if (!hal_machw_time_past(timer->time)) + break ; + } + + co_list_pop_front(&mm_timer_env.prog); + ASSERT_ERR(timer->cb); + timer->cb(timer->env); + } +} diff --git a/src/bl602_wifi/ip/lmac/ps/ps.c b/src/bl602_wifi/ip/lmac/ps/ps.c new file mode 100644 index 0000000..7cc412c --- /dev/null +++ b/src/bl602_wifi/ip/lmac/ps/ps.c @@ -0,0 +1,407 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +struct ps_env_tag ps_env; + +static uint8_t ps_send_pspoll(struct vif_info_tag *vif_entry) { + uint8_t sta_idx = vif_entry->u.sta.ap_id; + struct phy_channel_info info; + phy_get_channel(&info, 0); + struct txl_frame_desc_tag *frame = txl_frame_get((uint8)info.info1 != 0, 16); + if (frame) { + tpc_update_frame_tx_power(vif_entry, frame); + struct txl_buffer_tag * pBuffer = frame->txdesc.lmac.buffer; + uint8_t* payload = &(pBuffer->payload); + uint32_t aid = sta_info_tab[sta_idx].aid; + payload[0] = 0xa4; + payload[1] = 0; + payload[2] = (uint8_t)aid; + payload[3] = (aid >> 8) | 0xc0; + memcpy(payload + 4, &(sta_info_tab[sta_idx].mac_addr), 6); + memcpy(payload + 10, &(vif_entry->mac_addr), 6); + struct tx_hw_desc *hw_desc = frame->txdesc.lmac.hw_desc; + (hw_desc->thd).macctrlinfo2 = (hw_desc->thd).macctrlinfo2 | 0x10000053; + frame->txdesc.host.vif_idx = sta_info_tab[sta_idx].inst_nbr; + frame->txdesc.host.staid = sta_info_tab[sta_idx].staid; + txl_frame_push(frame, 0x3); + } + return frame == 0; +} + +//bool ps_check_tx_status(struct vif_info_tag *p_vif_entry, uint32_t status, cfm_func_ptr cfm) { +// __builtin_trap(); +//} + +static void ps_enable_cfm(void *env, uint32_t status) { + // (-1 < (int)(status << 8)) + // 31 - 8 + struct vif_info_tag* vif = env; + if (!(status & FRAME_SUCCESSFUL_TX_BIT)) { + uint8_t retry = vif->u.sta.ps_retry + 1; + vif->u.sta.ps_retry = retry; + if (retry != 3) { + txl_frame_send_null_frame(vif->u.sta.ap_id, ps_enable_cfm, env); + return ; + } + mm_send_connection_loss_ind(env); + } + + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + if (ps_env.cfm_cnt != 0) { + ps_env.cfm_cnt--; + } + if (ps_env.cfm_cnt == 0) { + if (ps_env.uapsd_on != false) { + uint32_t counter = MAC_CORE->MONOTONIC_COUNTER_2_LO.value; + mm_timer_set(&ps_env.uapsd_timer, counter + ps_env.uapsd_timeout); + ps_env.uapsd_tmr_on = true; + for (; p_vif_entry; p_vif_entry = (struct vif_info_tag *)co_list_next(&p_vif_entry.list_hdr)) { + if ((p_vif_entry->type == VIF_STA) && + (p_vif_entry->active != false) && + (p_vif_entry->u.sta.uapsd_queues != 0)) + { + p_vif_entry->prevent_sleep &= ~PS_VIF_WAITING_EOSP; + } + } + } + uint8_t state_resume = (CO_BIT(PS_DPSM_STATE_ON) | CO_BIT(PS_DPSM_STATE_RESUMING)); + if ((ps_env.dpsm_state & state_resume) == state_resume) { + ps_env.dpsm_state &= ~(CO_BIT(PS_DPSM_STATE_RESUMING) | CO_BIT(PS_DPSM_STATE_PAUSE)); + } else { + ps_env.ps_on = true; + ke_msg_send_basic(MM_SET_PS_MODE_CFM, ps_env.taskid, TASK_MM); + } + if ((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_SET_MODE_REQ)) != 0) { + ps_env.dpsm_state &= ~CO_BIT(PS_DPSM_STATE_SET_MODE_REQ); + ps_set_mode(ps_env.next_mode, ps_env.taskid); + } + } +} + +static void ps_disable_cfm(void *env, uint32_t status) { + // (-1 < (int)(status << 8)) + // 31 - 8 + struct vif_info_tag* vif = env; + if (!(status & FRAME_SUCCESSFUL_TX_BIT)) { + uint8_t retry = vif->u.sta.ps_retry + 1; + vif->u.sta.ps_retry = retry; + if (retry != 3) { + txl_frame_send_null_frame(vif->u.sta.ap_id, ps_enable_cfm, env); + return ; + } + mm_send_connection_loss_ind(env); + } + if (ps_env.cfm_cnt != 0) { + ps_env.cfm_cnt--; + } + if (ps_env.cfm_cnt == 0) { + mm_timer_clear(&ps_env.uapsd_timer); + ps_env.uapsd_tmr_on = false; + uint8_t status_pause = CO_BIT(PS_DPSM_STATE_ON) | CO_BIT(PS_DPSM_STATE_PAUSING); + if ((ps_env.dpsm_state & status_pause) == status_pause) { + ps_env.dpsm_state = ps_env.dpsm_state & ~CO_BIT(PS_DPSM_STATE_PAUSING) | CO_BIT(PS_DPSM_STATE_PAUSE); + } else { + ps_env.ps_on = false; + ke_msg_send_basic(MM_SET_PS_MODE_CFM, ps_env.taskid, TASK_MM); + } + if ((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_SET_MODE_REQ)) != 0) { + ps_env.dpsm_state = ps_env.dpsm_state & ~CO_BIT(PS_DPSM_STATE_SET_MODE_REQ); + ps_set_mode(ps_env.next_mode, ps_env.taskid); + } + } +} + +static void ps_dpsm_update(bool pause) { + cfm_func_ptr ps_cfm_func = NULL; + if (pause == 0) { + ps_env.dpsm_state = ps_env.dpsm_state | CO_BIT(PS_DPSM_STATE_RESUMING); + ps_env.prevent_sleep = ps_env.prevent_sleep & ~PS_VIF_WAITING_EOSP; + ps_cfm_func = ps_enable_cfm; + } else { + ps_env.dpsm_state = ps_env.dpsm_state | CO_BIT(PS_DPSM_STATE_PAUSING); + ps_env.prevent_sleep = ps_env.prevent_sleep | PS_VIF_WAITING_EOSP; + ps_cfm_func = ps_disable_cfm; + } + MAC_CORE->MAC_CNTRL_1.pwrMgt = pause ^ 1; + ps_env.cfm_cnt = 0; + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry; p_vif_entry = co_list_next(&(p_vif_entry->list_hdr))) { + if ((p_vif_entry->type == VIF_STA) && (p_vif_entry->active != false) && (chan_is_on_channel(p_vif_entry))) { + p_vif_entry->u.sta.ps_retry = 0; + ps_env.cfm_cnt++; + txl_frame_send_null_frame(p_vif_entry->u.sta.ap_id, ps_cfm_func, p_vif_entry); + } + } + + if (ps_env.cfm_cnt == 0) { + ps_cfm_func(NULL, FRAME_SUCCESSFUL_TX_BIT); + } +} + +static void ps_uapsd_timer_handle(void *env) { + bool updated = false; + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry; p_vif_entry = co_list_next(&(p_vif_entry->list_hdr))) { + if ((p_vif_entry->type == VIF_STA) && (p_vif_entry->active != false) && (p_vif_entry->u.sta.uapsd_queues != 0)) { + if (chan_is_on_channel(p_vif_entry)) { + updated = true; + int32_t counter = MAC_CORE->MONOTONIC_COUNTER_2_LO.value; + if (((int32_t)(ps_env.uapsd_timeout >> 1) - counter + p_vif_entry->u.sta.uapsd_last_rxtx) < 0) { + p_vif_entry->prevent_sleep = p_vif_entry->prevent_sleep | PS_VIF_WAITING_EOSP; + txl_frame_send_qosnull_frame(p_vif_entry->u.sta.ap_id, 7, 0, 0); + p_vif_entry->u.sta.uapsd_last_rxtx = MAC_CORE->MONOTONIC_COUNTER_2_LO.value; + } + } + } + } + + if (updated) { + mm_timer_set(&ps_env.uapsd_timer, ps_env.uapsd_timeout + MAC_CORE->MONOTONIC_COUNTER_2_LO.value); + return ; + } + ps_env.uapsd_tmr_on = false; +} + +void ps_init(void) { + memset(&ps_env, 0, sizeof(ps_env)); + ps_env.uapsd_timer.cb = ps_uapsd_timer_handle; +} + +void ps_set_mode(uint8_t mode, ke_task_id_t taskid) { + cfm_func_ptr ps_cfm_func = NULL; + ps_env.taskid = taskid; + if (((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_ON)) == 0) || ((ps_env.dpsm_state & (CO_BIT(PS_DPSM_STATE_PAUSING) | CO_BIT(PS_DPSM_STATE_RESUMING))) == 0)) { + if (mode == PS_MODE_OFF) { + ps_env.dpsm_state = 0; + ps_cfm_func = ps_disable_cfm; + MAC_CORE->MAC_CNTRL_1.pwrMgt = mode; + } else { + if (mode == PS_MODE_ON_DYN) { + ps_env.dpsm_state |= CO_BIT(PS_DPSM_STATE_ON); + } + MAC_CORE->MAC_CNTRL_1.pwrMgt = 1; + ps_cfm_func = ps_enable_cfm; + } + + ps_env.cfm_cnt = 0; + ps_env.uapsd_on = false; + + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry; p_vif_entry = co_list_next(&(p_vif_entry->list_hdr))) { + if ((p_vif_entry->type == VIF_STA) && (p_vif_entry->active != false) && (chan_is_on_channel(p_vif_entry) != 0)) { + p_vif_entry->u.sta.ps_retry = 0; + ps_env.cfm_cnt = ps_env.cfm_cnt ++; + if (p_vif_entry->u.sta.uapsd_queues != 0) { + ps_env.uapsd_on = true; + } + txl_frame_send_null_frame(p_vif_entry->u.sta.ap_id, ps_cfm_func, p_vif_entry); + } + } + if (ps_env.cfm_cnt == 0) { + ps_cfm_func(NULL, FRAME_SUCCESSFUL_TX_BIT); + return ; + } + } else { + ps_env.dpsm_state = ps_env.dpsm_state | CO_BIT(PS_DPSM_STATE_SET_MODE_REQ); + ps_env.next_mode = mode; + } +} + +void ps_polling_frame(struct vif_info_tag *vif_entry) { + return ps_send_pspoll(vif_entry); +} + +bool ps_check_tim(uint32_t a_tim, uint16_t aid) { + /* + aidshift = (uint)(aid >> 3); + bmpc = *(byte *)(tim + 4) & 0xfe; + // bVar4 = *(byte *)&(vif_entry->u).field_0xc & 0xf; + if (((bmpc <= aidshift) && (aidshift <= (*(byte *)(tim + 1) - 4) + bmpc)) && + (((uint)*(byte *)(((aidshift + tim) - bmpc) + 5) & 1 << (aid & 7)) != 0)) { + */ + uint16_t aid_shift = (aid >> 3); + uint8_t bmpc = co_read8p(a_tim + MAC_TIM_BMPC_OFT) & ~MAC_TIM_BCMC_PRESENT; + if ((bmpc <= aid_shift) && + (aid_shift <= co_read8p(a_tim + MAC_TIM_LEN_OFT) - 4 + bmpc) && + (co_read8p(aidshift + a_tim - bmpc + MAC_TIM_BMP_OFT) & (CO_BIT(aid & 7)) != 0) + ) { + return true; + } + return false; +} + +void ps_check_beacon(uint32_t tim, uint16_t len, struct vif_info_tag *vif_entry) { + bool pson = ps_env.ps_on; + uint8_t sta_idx = vif_entry->u.sta.ap_id; + uint16_t aid = sta_info_tab[sta_idx].aid; + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_BCN; + if (((pson == false) || ((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_PAUSE)) != 0)) || (tim == 0)) { + return 0; + } + if (!(vif_entry->u.sta.dont_wait_bcmc)) { + if ((co_read8p(tim + MAC_TIM_BMPC_OFT) & MAC_TIM_BCMC_PRESENT) == 0) { + vif_entry->prevent_sleep &= ~(PS_VIF_WAITING_BCN | PS_VIF_WAITING_BCMC) + } else { + vif_entry->prevent_sleep = vif_entry->prevent_sleep | PS_VIF_WAITING_BCMC; + } + } + if (ps_check_tim(tim, aid)) { + if (vif_entry->u.sta.uapsd_queues == 15) { + if (txl_frame_send_qosnull_frame(sta_idx, 7, 0, 0)) { + return ; + } + vif_entry->prevent_sleep |= PS_VIF_WAITING_EOSP; + } else { + if (ps_send_pspoll(vif_entry)) { + return ; + } + vif_entry->prevent_sleep = vif_entry->prevent_sleep | PS_VIF_WAITING_UC; + } + } else { + if (vif_entry->u.sta.uapsd_queues == 15) { + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_EOSP; + } else { + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_UC; + } + } +} + +void ps_check_frame(uint8_t *frame, uint32_t statinfo, struct vif_info_tag *vif_entry) { + uint8_t uapsdon = ps_env.uapsd_on; + if (ps_env.ps_on == false) { + return ; + } + struct mac_hdr *machdr = (struct mac_hdr *)frame; + uint16_t framectrl = machdr->fctl; + if (MAC_ADDR_GROUP(&machdr->addr1)) { + // 31- 18 + if (((framectrl >> 13) & 1) && !(vif_entry->u.sta.dont_wait_bcmc)) { + return ; + } + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_BCMC; + return ; + } + if (statinfo & RX_HD_ADDRMIS) + return ; + if (uapsdon != false) { + if ((framectrl & MAC_FCTRL_QOS_DATA) == MAC_FCTRL_QOS_DATA) { + uint16_t qos = 0; + if ((framectrl & MAC_FCTRL_TODS_FROMDS) == MAC_FCTRL_TODS_FROMDS) { + struct mac_hdr_long_qos *hdr = (struct mac_hdr_long_qos *)machdr; + qos = hdr->qos; + } else { + struct mac_hdr_qos *hdr = (struct mac_hdr_qos *)machdr; + qos = hdr->qos; + } + if (vif_entry->u.sta.uapsd_queues & (CO_BIT(mac_tid2ac[qos & 7]))) { + vif_entry->u.sta.uapsd_last_rxtx = ke_time(); + if (qos & MAC_QOSCTRL_EOSP) { + return ; + } + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_EOSP; + return ; + } + uapsdon = false; + } else { + // MAC_FCTRL_RSV_T? + if (((framectrl & MAC_FCTRL_RSV_T) == 0) && ((((vif_entry->u.sta.uapsd_queues)) & 8) != 0)) { + vif_entry->u.sta.uapsd_last_rxtx = ke_time(); + } else { + uapsdon = false; + } + } + } + + td_pck_ps_ind(vif_entry->index, true); + if (uapsdon == 0) { + if (framectrl & MAC_FCTRL_MOREDATA) { + if ((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_PAUSE)) == 0) { + if (ps_send_pspoll(vif_entry) != 0) { + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_UC; + } + } + } else { + vif_entry->prevent_sleep &= ~PS_VIF_WAITING_UC; + } + } + +} + +void ps_check_tx_frame(uint8_t staid, uint8_t tid) { + if ((ps_env.ps_on != false) && (staid != 0xff) && (tid != 0xff)) { + struct sta_info_tag* = sta_entry = sta_info_tab + staid; + struct vif_info_tag* vif_entry = vif_info_tab + sta_entry->inst_nbr; + if ((vif_entry->type == VIF_STA) && (vif_entry->active)) { + if ((vif_entry->u.sta.uapsd_queues >> mac_tid2ac[tid]) & 1) { + vif_entry->prevent_sleep |= PS_VIF_WAITING_EOSP; + vif_entry->u.sta.uapsd_last_rxtx = ke_time(); + return ; + } + td_pck_ps_ind(vif_entry->index, false); + } + } +} + +void ps_uapsd_set(struct vif_info_tag *vif_entry, uint8_t hw_queue, bool uapsd) { + if (!uapsd) { + vif_entry->u.sta.uapsd_last_rxtx &= ~CO_BIT(hw_queue); + } else { + vif_entry->u.sta.uapsd_last_rxtx |= CO_BIT(hw_queue); + if (ps_env.ps_on) { + if (ps_env.uapsd_on == false) { + ps_env.uapsd_on = true; + mm_timer_set(&ps_env.uapsd_timer, ke_time() + ps_env.uapsd_timeout); + ps_env.uapsd_tmr_on = true; + } + } + } +} + +void ps_traffic_status_update(uint8_t vif_index, uint8_t new_status) { + /// TODO: verify me + if ((ps_env.ps_on != false) && + ((ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_ON)) != 0) && + ((ps_env.dpsm_state & (CO_BIT(PS_DPSM_STATE_PAUSING) | CO_BIT(PS_DPSM_STATE_RESUMING))) == 0) + ) { + bool pause = (ps_env.dpsm_state & CO_BIT(PS_DPSM_STATE_PAUSE) != 0); + if (new_status == 0) { + bool find = false; + struct vif_info_tag *p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry; p_vif_entry = co_list_next(&(p_vif_entry->list_hdr))) { + if (p_vif_entry->index != vif_index) { + if ((p_vif_entry->active) && (p_vif_entry->type == VIF_STA)) { + if (td_get_ps_status(p_vif_entry->index)) { + find = true; + break; + } + } + } + } + if (!find) { + if (pause) { + ps_dpsm_update(false); + return ; + } else { + return ; + } + } + } + /// find == true + if (!pause) { + ps_dpsm_update(true); + } + } +} diff --git a/src/bl602_wifi/ip/lmac/rx/rx_swdesc.c b/src/bl602_wifi/ip/lmac/rx/rx_swdesc.c new file mode 100644 index 0000000..cbca680 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/rx/rx_swdesc.c @@ -0,0 +1,12 @@ +#include + +#include +#include + +struct rx_swdesc rx_swdesc_tab[NX_RXDESC_CNT]; + +void rx_swdesc_init(void) { + for (int i = 0; i < NX_RXDESC_CNT; i++) { + rx_swdesc_tab[i].dma_hdrdesc = rx_dma_hdrdesc + i; + } +} diff --git a/src/bl602_wifi/ip/lmac/rx/rxl/rxl_cntrl.c b/src/bl602_wifi/ip/lmac/rx/rxl/rxl_cntrl.c new file mode 100644 index 0000000..73360a6 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/rx/rxl/rxl_cntrl.c @@ -0,0 +1,396 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +struct rxl_cntrl_env_tag rxl_cntrl_env; + + +void rxl_mpdu_transfer(struct rx_swdesc *swdesc) { + struct rx_dmadesc *desc = swdesc->dma_hdrdesc; + struct rx_pbd *pd = HW2CPU(desc->hd.first_pbd_ptr); + phy_get_channel(&desc->phy_info, PHY_PRIM); + desc->payl_offset = mac_payload_offset; + swdesc->pbd_count = 0; + + for (struct rx_pbd * prev = NULL; pd; pd = HW2CPU(pd->next)) { + if (pd->bufstatinfo & RX_PD_LASTBUF) { + swdesc->spare_pbd = pd; + swdesc->last_pbd = prev; + // rx_hwdesc_env.first = HW2CPU(swdesc->spare_pbd->next); + return ; + } + swdesc->pbd_count++; + prev = pd; + } + ASSERT_REC(pd != NULL); +} + +/// TODO: verify me +static bool rxl_rxcntrl_frame(struct rx_swdesc *swdesc) { + struct rx_dmadesc *dma_hdrdesc = swdesc->dma_hdrdesc; + if ((dma_hdrdesc->hd).frmlen == 0) { + ASSERT_REC_VAL(dma_hdrdesc->hd.first_pbd_ptr == 0, true); + } else { + struct rx_payloaddesc *pd = HW2CPU((dma_hdrdesc->hd).first_pbd_ptr); + ASSERT_REC_VAL(pd != NULL, true); + return false; // co_list_push_back(&rxl_cntrl_env.ready,&list_hdr->list_hdr); + } + swdesc->spare_pbd = NULL; + swdesc->last_pbd = NULL; + rxl_hd_append(swdesc->dma_hdrdesc); + return true; +} + +#if (NX_RX_FRAME_HANDLING) +/** + **************************************************************************************** + * @brief This function processes the received frames that could carry useful information + * for some LMAC features (connection monitoring, power-save mode, etc.) + * + * @param[in] swdesc SW header descriptor of the frame + **************************************************************************************** + */ +static void rxl_pm_check(uint8_t *frame, uint8_t sta_idx, uint8_t vif_idx) { + struct vif_info_tag *vif = vif_info_tab + vif_idx; + struct sta_info_tag *sta = sta_info_tab + sta_idx; + uint16_t frame_ctrl; + + frame_ctrl = co_read16(frame); + + if (vif->type != VIF_AP) + return ; + if (sta->ps_state == 1) { + // 140C + /// TODO: not sure the macro name. + if ((frame_ctrl & (MAC_FCTRL_PWRMGT | MAC_FCTRL_MOREFRAG | MAC_FCTRL_DATA_T | MAC_FCTRL_CTRL_T)) == MAC_FCTRL_DATA_T) { + mm_ps_change_ind(sta_idx, 0); + apm_tx_int_ps_clear(vif, sta_idx); + /* + cVar9 = *(char *)&vif_info_tab[uVar12].u.field_0xee + -1; + *(char *)&vif_info_tab[uVar12].u.field_0xee = cVar9; + */ + vif->u.ap.ps_sta_cnt--; + if (vif->u.ap.ps_sta_cnt == 0) { + mm_ps_change_ind(VIF_TO_BCMC_IDX(vif_idx), PS_MODE_OFF); + apm_tx_int_ps_clear(vif, vif_idx + 3); + } + } else { + // & 0xfc == 0xa4 + /// TODO: not sure the macro name. + if ((frame_ctrl & MAC_FCTRL_TYPESUBTYPE_MASK) == 0xa4) { + if ((sta->traffic_avail & PS_TRAFFIC_INT) == 0) { + mm_traffic_req_ind(sta_idx, 1, 0); + } else { + sta->ps_service_period |= PS_SERVICE_PERIOD; + sta_mgmt_send_postponed_frame(vif, sta, 1); + sta->ps_service_period &= ~PS_SERVICE_PERIOD; + } + } + // 0x8c == 0x88 + if ((frame_ctrl & (MAC_FCTRL_BEACON_ST | MAC_FCTRL_TYPE_MASK)) == (MAC_FCTRL_BEACON_ST | MAC_FCTRL_DATA_T)) { + // & 0x300 == 0x300 + uint8_t tid = 0; + if ((frame_ctrl & MAC_FCTRL_TODS_FROMDS) == MAC_FCTRL_TODS_FROMDS) { + /// TODO: what is frame + 0xf? + tid = co_read8p(frame + 0xf) & 7; + } else { + tid = co_read8p(frame + 0xc) & 7; + } + if (mac_ac2uapsd[mac_tid2ac[val]] & sta->info.uapsd_queues != 0) { + int period = sta->ps_service_period & UAPSD_SERVICE_PERIOD; + if ((sta->traffic_avail & UAPSD_TRAFFIC) == 0) { + if (period == 0) { + sta->ps_service_period = UAPSD_SERVICE_PERIOD_INT; + txl_frame_send_qosnull_frame(sta->staid, (tid & 7) | 0x10, 0, 0); + sta->ps_service_period = NO_SERVICE_PERIOD; + return ; + } + } else { + if (period == 0) { + uint8_t maxsplen = sta->info.max_sp_len; + if ((sta->traffic_avail & UAPSD_TRAFFIC_INT) != 0) { + sta->ps_service_period = UAPSD_SERVICE_PERIOD_INT; + int len = sta_mgmt_send_postponed_frame(vif, sta, maxsplen); + if (maxsplen != 0) { + if (maxsplen - len < 1) { + txl_frame_send_qosnull_frame(sta->staid, (tid & 7) | 0x10, 0, 0); + sta->ps_service_period = NO_SERVICE_PERIOD; + return ; + } + } + } + if ((sta->traffic_avail & UAPSD_TRAFFIC_HOST) == 0) { + txl_frame_send_qosnull_frame(sta->staid, (tid & 7) | 0x10, 0, 0); + sta->ps_service_period = NO_SERVICE_PERIOD; + return ; + } + sta->ps_service_period = UAPSD_SERVICE_PERIOD_HOST; + mm_traffic_req_ind(sta_idx, maxsplen, 1); + } + } + } + } + } + } else { + /// TODO: get macro + if ((frame_ctrl & (0x1400)) == 0x1000) { + mm_ps_change_ind(sta_idx, PS_MODE_ON); + if (vif->u.ap.ps_sta_cnt == 0) { + mm_ps_change_ind(VIF_TO_BCMC_IDX(vif_idx), PS_MODE_OFF); + } + vif->u.ap.ps_sta_cnt++; + } + } + +} +#endif + +static uint8_t rxl_frame_handle(struct rx_swdesc *swdesc, bool *dont_free) { + struct rx_dmadesc *dma_hdrdesc = swdesc->dma_hdrdesc; + struct rx_hd *rhd = &dma_hdrdesc->hd; + bool upload = true; + + ASSERT_REC_VAL(rhd->first_pbd_ptr != 0, false); + + struct rx_pbd *pd = HW2CPU(rhd->first_pbd_ptr); + + uint32_t statinfo; + statinfo = rhd->statinfo; + if ((statinfo & (RX_HD_KEYIDV | RX_HD_SUCCESS)) != (RX_HD_KEYIDV | RX_HD_SUCCESS)) { + return upload; + } + // ((statinfo & (RX_HD_KEYIDV | RX_HD_SUCCESS)) == (RX_HD_KEYIDV | RX_HD_SUCCESS)) + + // Get the HW key index + uint16_t key_idx_hw = (uint16_t)RX_HD_KEYID_GET(statinfo); + ASSERT_REC_VAL(key_idx_hw >= MM_SEC_DEFAULT_KEY_COUNT, false); + uint8_t sta_idx = ((key_idx_hw) - MM_SEC_DEFAULT_KEY_COUNT); + if (!sta_mgmt_is_valid(sta_idx)) { + rhd->statinfo = statinfo & ~RX_HD_KEYIDV; + return upload; + } + // else + struct sta_info_tag *p_sta_entry = sta_info_tab + sta_idx; + struct vif_info_tag *vif_entry = vif_info_tab + p_sta_entry->inst_nbr; + TickType_t now = xTaskGetTickCount(); + p_sta_entry->time_last_seen = now; + uint8_t *frame = HW2CPU(pd->datastartptr); + uint16_t framectrl = co_read16(frame); + + rxl_pm_check(frame, sta_idx, vif_entry->index); + + if (!vif_entry->active) + return upload; + // (vif_info_tab[uVar4].active != false) + + #if (NX_TD) + if (((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_DATA_T) || + ((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_MGT_T)) { + td_pck_ind(vif_entry->index, sta_idx, true); + } + #endif //(NX_TD) + + if (vif_entry->type == VIF_STA) { + if (MAC_FCTRL_IS(framectrl, BEACON)) { + #if NX_POWERSAVE || NX_CONNECTION_MONITOR || NX_MULTI_ROLE + uint32_t tim = 0; + #endif + pa_input(0, rhd); + pa_adapt(0); + #if NX_CONNECTION_MONITOR || NX_MULTI_ROLE + // Let the MM handle the connection monitoring procedures + upload = mm_check_beacon(rhd, vif_entry, p_sta_entry, &tim); + #elif NX_POWERSAVE + tim = mac_ie_find(pd->datastartptr + MAC_BEACON_VARIABLE_PART_OFT, + dma_hdrdesc->hd.frmlen - MAC_BEACON_VARIABLE_PART_OFT, + MAC_ELTID_TIM); + #endif + #if NX_POWERSAVE + // Let the PS module check if it has something to do with this beacon + ps_check_beacon(tim, dma_hdrdesc->hd.frmlen, vif_entry); + #endif + #if (NX_P2P || NX_CHNL_CTXT) + vif_mgmt_bcn_recv(vif_entry); + #endif + #if (NX_CHNL_CTXT) + if (vif_entry->chan_ctxt) + { + chan_tbtt_switch_update(vif_entry, vif_entry->tbtt_timer.time); + } + #endif //(NX_CHNL_CTXT) + } else if ( + ((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_DATA_T) || + ((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_MGT_T) + ) { + #if NX_POWERSAVE + ps_check_frame((uint8_t *)frame, statinfo, vif_entry); + #endif + } + } + return upload; +} + +static void rxl_cntrl_init(void) { + co_list_init(&rxl_cntrl_env.ready); +} + +void rxl_init(void) { + rxl_hwdesc_init(1); + rx_swdesc_init(); + rxl_cntrl_init(); + rxu_cntrl_init(); +} + +void rxl_cntrl_evt(int dummy) { + int tim = RX_FRAME_PREP_THD + 1; + struct rx_swdesc *swdesc; + uint8_t upload; + while (true) { + swdesc = (struct rx_swdesc *)co_list_pick(&rxl_cntrl_env.ready); + ke_evt_clear(KE_EVT_RXLREADY_BIT); + if (!swdesc) + return ; + tim--; + if (!tim) { + // 4 times + ke_evt_set(KE_EVT_RXLREADY_BIT); + break; + } + __disable_irq(); + co_list_pop_front(&rxl_cntrl_env.ready); + __enable_irq(); + #if (NX_RX_FRAME_HANDLING) + bool dont_free = false; + upload = rxl_frame_handle(swdesc, &dont_free); + if (!upload) { + if (!dont_free) + rxl_mpdu_free(swdesc); + } else + #endif //(NX_RX_FRAME_HANDLING) + { + upload = rxu_cntrl_frame_handle(swdesc); + if (!upload) { // bk_wlan_is_monitor_mode ? + rxl_mpdu_free(swdesc); + } + } + } +} + +void rxl_cntrl_dump(void) { + // empty function + return ; +} + +void rxl_timer_int_handler(void) { + PACK0(MAC_PL->TX_RX_INT_ACK, int_ack) { + int_ack.timerRxTrigger = 1; + int_ack.counterRxTrigger = 1; + } + while (true) { + if ((rxl_cntrl_env.first == NULL) || + (!RX_HD_DONE_GET(rxl_cntrl_env.first->hd.statinfo))) + break; + struct rx_dmadesc *dma_hdrdesc = rxl_cntrl_env.first; + struct rx_swdesc *swdesc = (dma_hdrdesc->hd).swdesc; + rxl_cntrl_env.first = (struct rx_dmadesc*)HW2CPU(dma_hdrdesc->hd.next); + swdesc->pd = (struct rx_payloaddesc *)dma_hdrdesc->hd.first_pbd_ptr; + // check if it is a control frame and handle it if necessary + if (!rxl_rxcntrl_frame(swdesc)) { + co_list_push_back(&rxl_cntrl_env.ready, &swdesc->list_hdr); + } + } + if (!co_list_is_empty(&rxl_cntrl_env.ready)) + ke_evt_set(KE_EVT_RXLREADY_BIT); +} + +void rxl_timeout_int_handler(void) { + MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers6 = 0; +} + +void rxl_dma_int_handler(void) { + // forever ? + for (;;); +} + +void rxl_dma_evt(int dummy) { + ke_evt_clear(KE_EVT_RX_DMA_BIT); + DMA->int_ack.value = 0x20; +} + +void rxl_frame_release(struct rx_swdesc *swdesc) { + // release the payload descriptors associated with this SW descriptor + rxl_pd_append(HW2CPU(swdesc->dma_hdrdesc->hd.first_pbd_ptr), swdesc->last_pbd, swdesc->spare_pbd); + // release the HW DMA descriptors + rxl_hd_append(swdesc->dma_hdrdesc); +} + +void rxl_mpdu_free(struct rx_swdesc *swdesc) { + struct rx_pbd *pd = (struct rx_pbd *)(swdesc->dma_hdrdesc->hd).first_pbd_ptr; + vTaskEnterCritical(); + swdesc->use_in_tcpip = false; + swdesc->dma_hdrdesc->use_in_tcpip = false; + for (struct rx_pbd * prev = NULL; pd; pd = HW2CPU(pd->next)) { + if (pd->bufstatinfo & RX_PD_LASTBUF) { + swdesc->spare_pbd = pd; + swdesc->last_pbd = prev; + rxl_frame_release(swdesc); + // rx_hwdesc_env.first = HW2CPU(swdesc->spare_pbd->next); + vTaskExitCritical(); + return ; + } + swdesc->pbd_count++; + prev = pd; + } + ASSERT_REC(pd != NULL); + vTaskExitCritical(); +} + +void bl60x_firmwre_mpdu_free(void *swdesc_ptr) { + vTaskEnterCritical(); + struct rx_swdesc* swdesc = swdesc_ptr; + rxl_cntrl_env.packet_stack_cnt -= swdesc->pbd_count; + vTaskExitCritical(); + rxl_mpdu_free(swdesc); +} + +void rxl_current_desc_get(struct rx_hd **rhd, struct rx_pbd **rbd) { + *rhd = &(rxl_cntrl_env.free)->hd; + *rbd = rx_hwdesc_env.free; +} + +void rxl_reset(void) { + rxl_hwdesc_init(0); + co_list_init(&rxl_cntrl_env.ready); + co_list_init(&rxu_cntrl_env.rxdesc_ready); +} diff --git a/src/bl602_wifi/ip/lmac/rx/rxl/rxl_hwdesc.c b/src/bl602_wifi/ip/lmac/rx/rxl/rxl_hwdesc.c new file mode 100644 index 0000000..625ec2e --- /dev/null +++ b/src/bl602_wifi/ip/lmac/rx/rxl/rxl_hwdesc.c @@ -0,0 +1,214 @@ +#include + +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +#include +#include + +struct rxl_hwdesc_env_tag rx_hwdesc_env; + + +void rxl_hwdesc_dump(void){ + puts("---------- rxl_hwdesc_dump -------\r\n"); + printf("rx_dma_hdrdesc: %d\r\n", NX_RXDESC_CNT); + for (int i = 0; i < NX_RXDESC_CNT; i++) { + struct rx_dmadesc *desc = rx_dma_hdrdesc + i; + printf(" [%2d]@%08lx: upatternrx %08lx next %08lx first_pbd_ptr %08lx, swdesc %p\r\n", i, + (unsigned long)(desc), (unsigned long)((desc->hd).upatternrx), (unsigned long)((desc->hd).next), (unsigned long)((desc->hd).first_pbd_ptr), (desc->hd).swdesc); + printf(" datastartptr %08lx dataendptr %08lx, headerctrlinfo %08lx frmlen %4u ampdu_stat_info %04x\r\n", + (unsigned long)((desc->hd).datastartptr), (unsigned long)((desc->hd).dataendptr), (unsigned long)((desc->hd).headerctrlinfo), + (uint32_t)(desc->hd).frmlen, (uint32_t)(desc->hd).ampdu_stat_info); + printf(" tsflo %08lx tsfhi %08lx recvec1b %08lx recvec1c %08lx recvec1d %08lx recvec2a %08lx recvec2b %08lx statinfo %08lx\r\n", + (unsigned long)((desc->hd).tsflo), (unsigned long)((desc->hd).tsfhi), (unsigned long)((desc->hd).recvec1b), (unsigned long)((desc->hd).recvec1c), + (unsigned long)((desc->hd).recvec1d), (unsigned long)((desc->hd).recvec2a), (unsigned long)((desc->hd).recvec2b), (unsigned long)((desc->hd).statinfo)); + } + printf("rx_payload_desc: %d\r\n", NX_RX_PAYLOAD_DESC_CNT); + for (int i = 0; i < NX_RX_PAYLOAD_DESC_CNT; i++) { + struct rx_payloaddesc* desc = rx_payload_desc + i; + uint32_t ptr_end = (desc->pbd).dataendptr; + uint32_t sz = 0; + if (ptr_end) { + sz = ptr_end + 1 - (desc->pbd).datastartptr; + } + printf(" [%2d]@%08lx %3lu Bytes: upatternrx %08lx next %08lx datastartptr %08lx dataendptr %08lx bufstatinfo %04x reserved %04X\r\n", i, + (unsigned long)(desc), (unsigned long)(sz), (unsigned long)((desc->pbd).upattern), (unsigned long)((desc->pbd).next), (unsigned long)((desc->pbd).dataendptr), (unsigned long)((desc->pbd).dataendptr), (unsigned int)((desc->pbd).bufstatinfo), (desc->pbd).reserved); + } +} + +void rxl_hwdesc_init(int init) { + vTaskEnterCritical(); + struct rx_dmadesc *free_dma = NULL, *first_dma = NULL, *cur_dma = NULL; + { + struct rx_dmadesc* prev = NULL; + struct rx_dmadesc* cur = NULL; + int cnt_avail = 0; + for (int i = 0; i < NX_RXDESC_CNT; i++) { + cur = rx_dma_hdrdesc + i; + if (!init && (rx_dma_hdrdesc[i].use_in_tcpip == 1)) { + cur = prev; + if (prev) { + prev->hd.next = 0; + } + } else { + if (prev) { + prev->hd.next = CPU2HW(cur); + } + (cur->hd).datastartptr = 0; + (cur->hd).dataendptr = 0; + (cur->hd).upatternrx = RX_HEADER_DESC_PATTERN; + (cur->hd).statinfo = 0; + (cur->hd).headerctrlinfo = 0; + (cur->hd).next = (uint32_t)(rx_dma_hdrdesc + i + 1); + (cur->hd).first_pbd_ptr = 0; + (cur->hd).swdesc = rx_swdesc_tab + i; + (cur->hd).frmlen = 0; + if (cnt_avail == 0) { + free_dma = cur; + } // else free_dma = free_dma; + if (cnt_avail == 1) + first_dma = cur; + + cnt_avail++; + } + prev = cur; + } + + if (cnt_avail < 4) { + printf("No enough DESC %d(%d)\r\n", NX_RXDESC_CNT, cnt_avail); + } + + if (cur) { + cur->hd.next = 0; + } + + // write the buffer descriptor into the receive header head pointer register + MAC_PL->RX_HEADER_HEAD_PTR.value = CPU2HW(first_dma); + // set new head bit in DMA control register + MAC_PL->DMA_CNTRL_SET.value = 0x4000000; // rxHeaderNewHead + cur_dma = cur; + } + + struct rx_payloaddesc *free_pl = NULL, *first_pl = NULL, *cur_pl = NULL; + { + struct rx_payloaddesc *cur = NULL, *prev = NULL; + int cnt_avail = 0; + for (int i = 0 ; i < NX_RX_PAYLOAD_DESC_CNT ; i++) { + cur = (struct rx_payloaddesc *)(rx_payload_desc + i); + if (!init && (cur->pd_status == 1)) { + cur = prev; + if (prev) { + prev->pbd.next = 0; + } + } else { + if (prev) { + prev->pbd.next = CPU2HW(cur); + } + (cur->pbd).next = (uint32_t)(rx_payload_desc + i + 1); + (cur->pbd).upattern = RX_PAYLOAD_DESC_PATTERN; + (cur->pbd).bufstatinfo = 0; + (cur->pbd).datastartptr = CPU2HW(&rx_payload_desc_buffer[i][0]); + (cur->pbd).dataendptr = cur->pbd.datastartptr + NX_RX_PAYLOAD_LEN - 1; + cur->buffer_rx = (uint32_t*) &rx_payload_desc_buffer[i][0]; + if (cnt_avail == 0) { + free_pl = cur; + } + if (cnt_avail == 1) { + first_pl = cur; + } + cnt_avail++; + } + } + if (cnt_avail < 4) { + printf("No enough PBD DESC, %d(%d)\r\n", NX_RX_PAYLOAD_DESC_CNT, cnt_avail); + } + // Reset the next pointer on the last one + if (cur) cur->pbd.next = 0; + // program new buffer desc header in list for the MAC HW + MAC_PL->RX_PAYLOAD_HEAD_PTR.value = CPU2HW(first_pl); + // set the new head bit in the DMA control register + MAC_PL->DMA_CNTRL_SET.value = 0x8000000; // rxPayloadNewHead + cur_pl = cur; + } + if ((((free_dma == NULL) || (first_dma == NULL)) || (cur_dma == NULL)) || ((free_pl == NULL || (first_pl == NULL)))) { + printf("%p:%p%p vs %p:%p:%p\r\n", free_dma, first_dma, cur_dma, free_pl, first_pl, cur_pl); + } + rxl_cntrl_env.first = first_dma; + rxl_cntrl_env.last = cur_dma; + rxl_cntrl_env.free = free_dma; + rx_hwdesc_env.last = &cur_pl->pbd; + rx_hwdesc_env.free = &free_pl->pbd; + vTaskExitCritical(); +} + +// alios disable int, bl602 not + +void rxl_hd_append(struct rx_dmadesc *desc) { + ASSERT_ERR(desc != NULL); + struct rx_dmadesc *mac_ptr = HW2CPU(MAC_PL->DEBUG_RX_HDR_C_PTR.value); + struct rx_dmadesc *free_desc = desc; + if (rxl_cntrl_env.free != mac_ptr) { + free_desc = rxl_cntrl_env.free; + rxl_cntrl_env.free = desc; + } + (free_desc->hd).next = 0; + (free_desc->hd).first_pbd_ptr = 0; + (free_desc->hd).statinfo = 0; + (free_desc->hd).frmlen = 0; + ((rxl_cntrl_env.last)->hd).next = CPU2HW(&(free_desc->hd)); + MAC_PL->DMA_CNTRL_SET.value = 0x01000000; // rxHeaderNewTail + if (rxl_cntrl_env.first == NULL) { + rxl_cntrl_env.first = free_desc; + } + rxl_cntrl_env.last = free_desc; +} + +/// Input: chained list: first ... last ->next-> spare (guess?) +/// it tried free rx_hwdesc_env.free and put spare there, +/// if failed, it free entire free...last...spare and left +/// rx_hwdesc_env.free unchanged +void rxl_pd_append(struct rx_pbd *first, struct rx_pbd *last, struct rx_pbd *spare) { + ASSERT_ERR(spare != NULL); + struct rx_pbd *mac_ptr = HW2CPU(MAC_PL->DEBUG_RX_PAY_C_PTR.value); + if (mac_ptr == rx_hwdesc_env.free) { + // The HW is still pointing to the spare descriptor, therefore we cannot release + // it now. Instead we release the current descriptor. + // Add the free element at the end of the list + if (last == NULL) { + // No element in the list + first = spare; + } + last = spare; + // Reset the stat info + spare->bufstatinfo = 0; + } else { + // Otherwise we free the spare descriptor + struct rx_pbd *free = rx_hwdesc_env.free; + // Save the new free descriptor + rx_hwdesc_env.free = spare; + // Add the free element at the end of the list + if (last == NULL) { + // No element in the list + first = last = free; + } else { + free->next = CPU2HW(first); + first = free; + } + // Reset the stat info + first->bufstatinfo = 0; + } + last->next = 0; + (rx_hwdesc_env.last)->next = CPU2HW(first); + MAC_PL->DMA_CNTRL_SET.value = 0x2000000; // rxPayloadNewTail + rx_hwdesc_env.last = last; +} diff --git a/src/bl602_wifi/ip/lmac/scan/scan.c b/src/bl602_wifi/ip/lmac/scan/scan.c new file mode 100644 index 0000000..e624b55 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/scan/scan.c @@ -0,0 +1,153 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +struct scan_env_tag scan_env; + + +/** scan_search_ds + */ +void scan_search_ds(void) { + scan_env.ds_ie = mac_ie_find(CPU2HW(scan_probe_req_ie.buf), scan_env.param->add_ie_len, MAC_ELTID_DS); +} + +/** dma_cb + */ +void dma_cb(void* env, int dma_queue) { + scan_search_ds(); + scan_set_channel_request(); +} + +/** scan_init + */ +void scan_init(void) { + memset(&scan_env, 0, sizeof(scan_env)); + + scan_env.duration_scan_passive = SCAN_PASSIVE_DURATION; + scan_env.duration_scan_active = SCAN_ACTIVE_DURATION; + + ke_state_set(TASK_SCAN, SCAN_IDLE); + + scan_env.dma_desc.dma_desc = (dma_desc *)&scan_probe_req_ie; + scan_env.dma_desc.cb = dma_cb; + scan_env.dma_desc.env = (void *)0x0; + + scan_probe_req_ie.dma_desc.dest = CPU2HW(ie_desc->buf); + scan_probe_req_ie.pbd.upatterntx = TX_PAYLOAD_DESC_PATTERN; + scan_probe_req_ie.pbd.next = 0; + scan_probe_req_ie.pbd.datastartptr = CPU2HW(ie_desc->buf); + scan_probe_req_ie.pbd.bufctrlinfo = 0; +} + +/** scan_ie_download + */ +void scan_ie_download(const struct scan_start_req *param) { + scan_search_ds(); + scan_set_channel_request(); + scan_probe_req_ie.pbd.dataendptr = (scan_probe_req_ie.pbd.datastartptr - 1) + (uint)param->add_ie_len; + scan_probe_req_ie.pbd.bufctrlinfo = 0; +} + +/** scan_set_channel_request + */ +void scan_set_channel_request(void) { + struct scan_chan_tag *chan = scan_env.param->chan + scan_env.chan_idx; + uint32_t duration_us = scan_env.duration_scan_active; + if (chan->flags & SCAN_PASSIVE_BIT) { + duration_us = scan_env.duration_scan_passive; + } + chan_scan_req(chan->band, chan->freq, chan->tx_power, duration_us, (scan_env.param)->vif_idx); + if (scan_env.ds_ie == 0) { + ke_state_set(TASK_SCAN, SCAN_WAIT_CHANNEL); + return ; + } + co_write8p(scan_env.ds_ie + MAC_DS_CHANNEL_OFT, phy_freq_to_channel(chan->band, chan->freq)); + ke_state_set(TASK_SCAN, SCAN_WAIT_CHANNEL); +} + +/** scan_probe_req_tx + */ +void scan_probe_req_tx(void) { + struct scan_start_req *parma = scan_env.param; + uint8_t chan_idx = scan_env.chan_idx; + uint8_t vif_idx = (scan_env.param)->vif_idx; + struct scan_chan_tag *chan = param->chan + chan_idx; + struct vif_info_tag *vif = vif_info_tab + vif_idx; + + for (int i = 0; i < param->ssid_cnt; i++) { + struct mac_ssid* ssid = &((scan_env.param)->ssid[i]);//.array; + int tx_parma = TX_DEFAULT_5G; + if (chan->band == PHY_BAND_2G4) { + if (!parma->no_cck) { + tx_parma = TX_DEFAULT_24G; + } + } + + struct txl_frame_desc_tag* frame = txl_frame_get(tx_parma, (uint)parma->add_ie_len + (scan_env.param)->ssid[0].length + MAC_SHORT_MAC_HDR_LEN + MAC_SSID_SSID_OFT); + if (!frame) + return ; + + struct preq_frame *buf = (frame->txdesc).lmac.buffer->payload; + struct tx_hw_desc * hwdesc = (frame->txdesc).lmac.hw_desc; + + buf->h.fctl = MAC_FCTRL_PROBEREQ; + buf->h.durid = 0; + + // offset = 0x150 + memcpy(buf->h.addr1, &mac_addr_bcst, sizeof(struct mac_addr)); + // offset = 0x156 + memcpy(buf->h.addr2, &(vif->mac_addr), sizeof(struct mac_addr)); + // offset = 0x15c + memcpy(buf->h.addr3, &(parma->bssid), sizeof(struct mac_addr)); + // offset = 0x164 - 332 = 24 + buf->h.seq = txl_get_seq_ctrl(); + + uint32_t payload = CPU2HW(&(buf->payload)); + + co_write8p(ssid_addr++, MAC_ELTID_SSID); + co_write8p(ssid_addr++, ssid->length); + co_pack8p(ssid_addr, ssid->array, ssid->length); + + hwdesc->thd->first_pbd_ptr = CPU2HW(&(scan_probe_req_ie.pbd)); + hwdesc->thd->dataendptr -= param->add_ie_len; + + frame->cfm.cfm_func = NULL; + frame->cfm.env = NULL; + + #if (NX_CHNL_CTXT || NX_P2P) + (frame->txdesc).host.vif_idx = parma->vif_idx; + (frame->txdesc).host.staid = 0xff; + #endif + + txl_frame_push(frame, AC_VO); + } +} + +/** scan_send_cancel_cfm + */ +void scan_send_cancel_cfm(uint8_t status, ke_task_id_t dest_id) { + // 0x804 + struct scan_cancel_cfm *cfm = KE_MSG_ALLOC(SCAN_CANCEL_CFM, dest_id, TASK_SCAN, scan_cancel_cfm); + cfm->status = status; + ke_msg_send(cfm); +} + +/** scan_get_chan + */ +const struct scan_chan_tag *scan_get_chan(void) { + return (scan_env.param)->chan + scan_env.chan_idx; +} diff --git a/src/bl602_wifi/ip/lmac/scan/scan_shared.c b/src/bl602_wifi/ip/lmac/scan/scan_shared.c new file mode 100644 index 0000000..7f7d483 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/scan/scan_shared.c @@ -0,0 +1,6 @@ +#include +#include + +#if NX_HW_SCAN +struct scan_probe_req_ie_tag scan_probe_req_ie; +#endif diff --git a/src/bl602_wifi/ip/lmac/scan/scan_task.c b/src/bl602_wifi/ip/lmac/scan/scan_task.c new file mode 100644 index 0000000..c2571b9 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/scan/scan_task.c @@ -0,0 +1,105 @@ +#include + +#include +#include + +#include +#include + +#include +#include + +ke_state_t scan_state[SCAN_IDX_MAX]; + +/** scan_start_req_handler + */ +static int scan_start_req_handler(const ke_msg_id_t msgid, const struct scan_start_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct scan_start_cfm *msg = KE_MSG_ALLOC(SCAN_START_CFM, src_id, dest_id, scan_start_cfm); + if (ke_state_get(TASK_SCAN) == SCAN_IDLE) { + ASSERT_ERR(param->chan_cnt > 0); + + msg->status = CO_OK; + scan_env.chan_idx = 0; + scan_env.param = param; + scan_env.req_id = src_id; + scan_ie_download(param); + + ke_msg_send(msg); + return KE_MSG_NO_FREE; + } else { + msg->status = CO_BUSY; + ke_msg_send(msg); + return KE_MSG_CONSUMED; + } +} + +/** scan_cancel_req_handler + */ +static int scan_cancel_req_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + if (ke_state_get(TASK_SCAN) == SCAN_IDLE) { + scan_send_cancel_cfm(CO_FAIL, src_id); + } else { + scan_env.abort = true; + } + return KE_MSG_CONSUMED; +} + +/** mm_scan_channel_start_ind_handler + */ +static int mm_scan_channel_start_ind_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + ASSERT_ERR(ke_state_get(TASK_SCAN) == SCAN_WAIT_CHANNEL); + // 0x2200 + mm_rx_filter_lmac_enable_set(NXMAC_ACCEPT_PROBE_RESP_BIT | NXMAC_ACCEPT_ALL_BEACON_BIT); + if ((scan_env.param->chan[scan_env.chan_idx].flags & SCAN_PASSIVE_BIT) == 0) { + scan_probe_req_tx(); + } + + ke_state_set(TASK_SCAN, SCAN_WAIT_BEACON_PROBE_RSP) + + return KE_MSG_CONSUMED; +} + +/** mm_scan_channel_end_ind_handler + */ +static int mm_scan_channel_end_ind_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + ASSERT_ERR(ke_state_get(TASK_SCAN) == SCAN_WAIT_BEACON_PROBE_RSP); + // ffffddff + mm_rx_filter_lmac_enable_clear(NXMAC_ACCEPT_PROBE_RESP_BIT | NXMAC_ACCEPT_ALL_BEACON_BIT); + + scan_env.chan_idx = scan_env.chan_idx + 1; + if ((scan_env.chan_idx < (scan_env.param)->chan_cnt) && (scan_env.abort == false)) { + scan_set_channel_request(); + } else { + ke_msg_free(ke_param2msg(scan_env.param)); + if (scan_env.abort == false) { + ke_msg_send_basic(SCAN_DONE_IND, scan_env.req_id, TASK_SCAN); + } else { + scan_send_cancel_cfm(CO_OK, scan_env.req_id); + } + ke_state_set(TASK_SCAN, SCAN_IDLE); + } + + return KE_MSG_CONSUMED; +} + + +const struct ke_msg_handler scan_default_state[4] = { + [0] = { + .id = SCAN_START_REQ, // 0x800 + .func = scan_start_req_handler, + }, + [1] = { + .id = MM_SCAN_CHANNEL_START_IND, // 0x61 + .func = mm_scan_channel_start_ind_handler, + }, + [2] = { + .id = MM_SCAN_CHANNEL_END_IND, // 0x62, + .func = mm_scan_channel_end_ind_handler + }, + [3] = { + .id = SCAN_CANCEL_REQ, // 0x803, + .func = scan_cancel_req_handler + } +}; + +const struct ke_state_handler scan_default_handler = KE_STATE_HANDLER(scan_default_state); diff --git a/src/bl602_wifi/ip/lmac/sta/sta_mgmt.c b/src/bl602_wifi/ip/lmac/sta/sta_mgmt.c new file mode 100644 index 0000000..119437c --- /dev/null +++ b/src/bl602_wifi/ip/lmac/sta/sta_mgmt.c @@ -0,0 +1,164 @@ +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +struct sta_info_env_tag sta_info_env; +struct sta_info_tag sta_info_tab[STA_MAX]; + +static void sta_mgmt_entry_init(struct sta_info_tag *sta_entry) { + while (!co_list_is_empty(&sta_entry->tx_desc_post)) { + struct txdesc *p_txdesc = (struct txdesc *)co_list_pop_front(&sta_entry->tx_desc_post); + txl_frame_release(p_txdesc, true); + } + memset(sta_entry, 0, sizeof(struct sta_info_tag)); + sta_entry->inst_nbr = 0xff; +} + +void sta_mgmt_init(void) { + co_list_init(&sta_info_env.free_sta_list); + for (int i = 0; i < NX_REMOTE_STA_MAX; i++) { + sta_mgmt_entry_init(sta_info_tab + i); + co_list_push_back(&sta_info_env.free_sta_list, &sta_info_tab[i].list_hdr); + } + + for (int i = 0; i < NX_VIRT_DEV_MAX; i++) { + uint8_t idx = VIF_TO_BCMC_IDX(i); + sta_mgmt_entry_init(sta_info_tab + idx); + sta_info_tab[idx].pol_tbl.buf_ctrl = txl_buffer_control_desc_bcmc + i; + sta_info_tab[idx].sta_sec_info.cur_key = &(vif_info_tab[i].default_key); + sta_info_tab[idx].inst_nbr = i; + sta_info_tab[idx].ctrl_port_state = PORT_CLOSED; + printf("------ set default key %p, key ptr %p\r\n", &(vif_info_tab[i].default_key), vif_info_tab[i].default_key); + } +} + +uint8_t sta_mgmt_register(const struct mm_sta_add_req *param, uint8_t *sta_idx) { + int inst_nbr = param->inst_nbr; + struct sta_info_tag* sta_entry = (struct sta_info_tag *)co_list_pop_front(&sta_info_env.free_sta_list); + if (!sta_entry) { + return 1; + } + + memcpy(&sta_entry->mac_addr, ¶m->mac_addr,6); + int ampdu_spacing_min = param->ampdu_spacing_min; + if (ampdu_spacing_min < 0x10) { + ampdu_spacing_min = 0x10; + } + + sta_entry->ampdu_spacing_min = ampdu_spacing_min; + sta_entry->ampdu_size_max_ht = param->ampdu_size_max_ht; + sta_entry->ampdu_size_max_vht = param->ampdu_size_max_vht; + sta_entry->paid_gid = param->paid_gid; + sta_entry->inst_nbr = param->inst_nbr; + sta_entry->rssi = param->rssi; + sta_entry->tsflo = param->tsflo; + sta_entry->tsfhi = param->tsfhi; + sta_entry->data_rate = param->data_rate; + + *sta_idx = CO_GET_INDEX(sta_entry, sta_info_tab); + sta_entry->staid = *sta_idx; + + sta_entry->bcn_int = 100 * TU_DURATION; // 0x19000; + sta_entry->rx_nqos_last_seqcntl = 0xffff; + for (int i = 0; i < TID_MAX; i++) { + sta_entry->rx_qos_last_seqcntl[i] = 0xffff; + } + + sta_entry->ctrl_port_state = PORT_CLOSED; + sta_entry->pol_tbl.buf_ctrl = txl_buffer_control_desc + *sta_idx; + + if (!(vif_info_tag[inst_nbr].flags & WPA_WPA2_IN_USE)) { + (sta_entry->sta_sec_info).cur_key = &vif_info_tab[insn_nbr].default_key; + printf("------ %d set default key %p, ptr %p\r\n", 0x102, &(vif_info_tab[insn_nbr].default_key), vif_info_tab[insn_nbr].default_key); + } else { + (sta_entry->sta_sec_info).cur_key = &(sta_entry->sta_sec_info).pairwise_key; + printf("------ %d set default key %p, ptr %p\r\n", 0xf7, &(vif_info_tab[insn_nbr].default_key), vif_info_tab[insn_nbr].default_key); + } + + co_list_push_back(&vif_info_tab[insn_nbr].sta_list, (struct co_list_hdr *)sta_entry); + sta_entry->valid = true; + + return 0; +} + +void sta_mgmt_unregister(uint8_t sta_idx) { + struct sta_info_tag *sta_entry = &sta_info_tab[sta_idx]; + co_list_extract(&vif_info_tab[sta_entry->inst_nbr].sta_list, &sta_entry->list_hdr); + sta_mgmt_entry_init(sta_entry); + co_list_push_back(&sta_info_env.free_sta_list, &sta_entry->list_hdr); +} + +void sta_mgmt_add_key(const struct mm_key_add_req *param, uint8_t hw_key_idx) { + int sta_idx = param->sta_idx; + struct key_info_tag* key_info = &sta_info_tab[sta_idx].sta_sec_info.key_info; + key_info->hw_key_idx = hw_key_idx; + key_info->cipher = param->cipher_suite; + key_info->key_idx = param->key_idx; + // clear 0x48 bytes + memset(&(key_info->rx_pn), 0, sizeof(key_info->rx_pn)); + int cipher = param->cipher_suite; + if (cipher == MAC_RSNIE_CIPHER_TKIP) { + key_info->tx_pn = 0; + key_info->u.mic.tx_key[0] = param->key.array[4]; + key_info->u.mic.tx_key[1] = param->key.array[5]; + key_info->u.mic.rx_key[0] = param->key.array[6]; + key_info->u.mic.rx_key[1] = param->key.array[7]; + } else { + if ((cipher == MAC_RSNIE_CIPHER_WEP40) || (cipher == MAC_RSNIE_CIPHER_WEP104)) { + key_info->tx_pn = co_rand_word() & 0xFFFFFF; + } else { + key_info->tx_pn = 0; + } + } + key_info->valid = true; + sta_info_tab[sta_idx].sta_sec_info.pairwise_key = key_info; +} + +void sta_mgmt_del_key(struct sta_info_tag *sta) { + (sta->sta_sec_info).key_info.valid = false; + (sta->sta_sec_info).pairwise_key = NULL; + sta->ctrl_port_state = PORT_CONTROLED; +} + +int sta_mgmt_send_postponed_frame(struct vif_info_tag *p_vif_entry, struct sta_info_tag *p_sta_entry, int limit) { + int cnt = 0; + while (!co_list_is_empty(&(p_sta_entry->tx_desc_post))) { + struct txdesc* desc = co_list_pick(&(p_sta_entry->tx_desc_post)); + if (!txl_cntrl_tx_check(p_vif_entry)) + break; + if (!apm_tx_int_ps_check(desc)) { + break; + } + int stop; + // prioritize the frame from apm + desc = apm_tx_int_ps_get_postpone(p_vif_entry, p_sta_entry, &stop); + if (stop) break; + if (desc == NULL) { + desc = co_list_pop_front(&(p_sta_entry->tx_desc_post)); + } + uint8_t tid = (desc->host).tid; + /// TODO: why this is 9?? + /// the offset is 0xd5 = 213 from txdesc* + /// Also, I can't see where p_sta_entry->tx_desc_post get data from... + ((char*)desc->buf)[9] = 0; + cnt++; + txl_cntrl_push_int(desc, tid); + if ((limit != 0) && (cnt == limit)) { + break; + } + } + return cnt; +} diff --git a/src/bl602_wifi/ip/lmac/td/td.c b/src/bl602_wifi/ip/lmac/td/td.c new file mode 100644 index 0000000..762d482 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/td/td.c @@ -0,0 +1,104 @@ +#include + +#include + +#include + +#include + +#include + +struct td_env_tag td_env[NX_VIRT_DEV_MAX]; + +void td_timer_end(void *env) { + uint32_t now = ke_time(); + struct td_env_tag *p_td_env = (struct td_env_tag *)env; + uint8_t new_status = 0; + if (p_td_env->has_active_chan != false) { + if (p_td_env->pck_cnt_tx != 0) { + new_status = new_status | CO_BIT(TD_STATUS_TX); + } + if (p_td_env->pck_cnt_rx != 0) { + new_status = new_status | CO_BIT(TD_STATUS_RX); + } + if (p_td_env->pck_cnt_tx_ps != 0) { + new_status = new_status | CO_BIT(TD_STATUS_TX_PS); + } + if (p_td_env->pck_cnt_rx_ps != 0) { + new_status = new_status | CO_BIT(TD_STATUS_RX_PS); + } + if (((p_td_env->status ^ new_status) & (CO_BIT(TD_STATUS_TX_PS) | CO_BIT(TD_STATUS_RX_PS))) != 0) { + if ((new_status & CO_BIT(TD_STATUS_TX_PS)) == 0) { + puVar3 = "nul"; + } else { + puVar3 = "TX"; + } + if ((new_status & CO_BIT(TD_STATUS_RX_PS)) == 0) { + puVar4 = "nul"; + } else { + puVar4 = "RX"; + } + printf("Power Status %s:%s\r\n", puVar3, puVar4); + ps_traffic_status_update(p_td_env->vif_index,new_status & (CO_BIT(TD_STATUS_TX_PS) | CO_BIT(TD_STATUS_RX_PS))); + } + p_td_env->status = new_status; + } + p_td_env->pck_cnt_tx = 0; + p_td_env->pck_cnt_rx = 0; + p_td_env->pck_cnt_tx_ps = 0; + p_td_env->pck_cnt_rx_ps = 0; + p_td_env->has_active_chan = (vif_info_tab[p_td_env->vif_index].chan_ctxt == chan_env.current_channel); + mm_timer_set(&p_td_env->td_timer, now + TD_DEFAULT_INTV_US); +} + +/** td_init + */ +void td_init(void) { + printf("td_init\r\n"); + for (int i = 0; i < NX_VIRT_DEV_MAX; i++) + td_reset(i); +} + +/** td_reset + */ +void td_reset(uint8_t vif_index) { + printf("td_reset idx=%d\r\n", vif_index); + if (td_env[vif_index].is_on) { + mm_timer_clear(&timer->td_timer); + } + memset(td_env + vif_index, 0, sizeof(struct td_env_tag)); + td_env[vif_index].td_timer.cb = td_timer_end; + td_env[vif_index].td_timer.env = timer; + td_env[vif_index].vif_index = vif_index; +} + +/** td_start + */ +void td_start(uint8_t vif_index) { + if (td_env[vif_index].is_on == false) { + uint32_t now = ke_time(); + printf("td_start idx=%d\r\n", vif_index); + td_env[vif_index].is_on = true; + /// WARN: the value used by 602 is 1000000 + mm_timer_set(&td_env[vif_index].td_timer, now + TD_DEFAULT_INTV_US); + return; + } +} + +/** td_pck_ind + */ +void td_pck_ind(uint8_t vif_index, uint8_t sta_index, bool rx) { + if (rx) { + td_env[vif_index].pck_cnt_rx++; + } + td_env[vif_index].pck_cnt_tx++; +} + +/** td_pck_ps_ind + */ +void td_pck_ps_ind(uint8_t vif_index, bool rx) { + if (rx) { + td_env[vif_index].pck_cnt_rx_ps++; + } + td_env[vif_index].pck_cnt_tx_ps++; +} diff --git a/src/bl602_wifi/ip/lmac/tpc/tpc.c b/src/bl602_wifi/ip/lmac/tpc/tpc.c new file mode 100644 index 0000000..4d93c79 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tpc/tpc.c @@ -0,0 +1,128 @@ +#include + +#include + +#include +#include + +#include + +#include + +#include + +void bl_tpc_update_power_table(int8_t *power_table) { + trpc_update_power((int8_t (*) [8])power_table); + int8_t power_chan_os[14]; + for (int i = 0; i < 14; i++) { + power_chan_os[i] = power_table[i + 24] << 2; + } + phy_powroffset_set(power_chan_os); +} + +void bl_tpc_power_table_get(int8_t *power_table_config) { + trpc_power_get(power_table_config); + for (int i = 24; i < 38; i++) { + power_table_config[i] = 0 + } +} + +void bl_tpc_update_power_table_rate(int8_t *power_table) { + txpwr_vs_rate_table + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 8; j++) { + txpwr_vs_rate_table[i][j] = power_table[i * 8 + j]; + } + } +} + +void bl_tpc_update_power_table_channel_offset(int8_t *power_table) { + int8_t power_os[14]; + for (int i = 0; i < 14; i++) { + power_os[i] = power_table[i + 24] << 2; + printf("pwr chan[%d] offset:%d\r\n", i, power_os[i]); + } + printf("dynamic update channel offset\r\n"); + phy_powroffset_set(power_os); +} + +void bl_tpc_update_power_rate_11b(int8_t *power_rate_table) { + for (int i = 0; i < 4; i++) { + txpwr_vs_rate_table[0][i] = power_rate_table[i] + } +} + +void bl_tpc_update_power_rate_11g(int8_t *power_rate_table) { + for (int i = 0; i < 8 i++) { + txpwr_vs_rate_table[1][i] = power_rate_table[i] + } +} + +void bl_tpc_update_power_rate_11n(int8_t *power_rate_table) { + for (int i = 0; i < 8 i++) { + txpwr_vs_rate_table[2][i] = power_rate_table[i] + } +} + +void tpc_update_tx_power(int8_t pwr) { + /// TODO: pwr is not used..? + MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel = trpc_get_default_power_idx(PHY_FORMATMOD_11N, 0); + MAC_CORE->MAX_POWER_LEVEL.dsssMaxPwrLevel = trpc_get_default_power_idx(PHY_FORMATMOD_11B, 0); +} + +uint8_t tpc_get_vif_tx_power(struct vif_info_tag *vif) { + /// TODO: not using vif? + return MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel; +} + +void tpc_update_vif_tx_power(struct vif_info_tag *vif, int8_t *pwr, uint8_t *idx) { + if (*pwr == VIF_UNDEF_POWER) + return ; + int8_t old_pwr = vif->tx_power; + phy_get_rf_gain_idx(pwr, idx); + vif->tx_power = *pwr; + + if (vif->user_tx_power < *pwr) { + *pwr = vif->user_tx_power; + phy_get_rf_gain_idx(pwr, idx); + } + + if (*pwr != old_pwr) { + struct sta_info_tag *sta = co_list_pick(vif->sta_list); + for (; sta; sta = (struct sta_info_tag *)co_list_next(sta)) { + struct sta_pol_tbl_cntl *rc = &sta->pol_tbl; + // 0xe + rc->upd_field |= CO_BIT(STA_MGMT_POL_UPD_TX_POWER); + } + + #if NX_CHNL_CTXT + if (vif->chan_ctxt) { + chan_update_tx_power(vif->chan_ctxt); + if (chan_is_on_channel(vif)) { + tpc_update_tx_power((vif->chan_ctxt->channel).tx_power); + } + } + #endif + } +} + +void tpc_update_frame_tx_power(struct vif_info_tag *vif, struct txl_frame_desc_tag *frame) { + /// TODO: this function only updates powercntrlinfo[0]? + struct tx_policy_tbl *pol = (struct tx_policy_tbl *) HW2CPU((((frame->txdesc).lmac.hw_desc)->thd).policyentryaddr); + pol->powercntrlinfo[0] = tpc_get_vif_tx_power_vs_rate(pol->ratecntrlinfo[0]); +} + +uint8_t tpc_get_vif_tx_power_vs_rate(uint32_t rate_config) { + uint8_t mcs = rate_config & 0x7f; + uint8_t formatmod = 0; + if (((rate_config >> 11) & 7) == 0) { + formatmod = (uint8_t)(rate_config & 0x7c); + if ((rate_config & 0x7c) != 0) { + mcs = mcs - 4; + formatmod = 1; + } + } else { + formatmod = 2; + } + return trpc_get_default_power_idx(formatmod, mcs); +} diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer.c new file mode 100644 index 0000000..4839354 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer.c @@ -0,0 +1,148 @@ +#include + +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include + +struct txl_buffer_env_tag txl_buffer_env; + +static void txl_buffer_transfer(struct txdesc *txdesc, struct txl_buffer_tag *buf, uint16_t head_len) { + __builtin_trap(); +} + +void txl_buffer_reinit(void) { + /// TODO: the code here only changes list[0], but I really think it should change all of them + /* + for (int i = 0; i < NX_TXQ_CNT; i++) { + txl_buffer_env.list[i].first = NULL; + txl_buffer_env.list[i].last = NULL; + } + */ + txl_buffer_env.list[0].first = NULL; + txl_buffer_env.list[0].last = NULL; +} + +void txl_buffer_init(void) { + txl_buffer_reinit(); + for (int i = 0; i < NX_REMOTE_STA_MAX; i++) { + struct txl_buffer_control* buf_ctrl = txl_buffer_control_desc + i; + struct tx_policy_tbl* pol = buf_ctrl->policy_tbl; + pol->upatterntx = POLICY_TABLE_PATTERN; + pol->phycntrlinfo1 = phy_get_ntx() << NX_TX_PT_OFT; + pol->phycntrlinfo2 = TX_NTX_2_ANTENNA_SET(phy_get_ntx()); + pol->maccntrlinfo1 = 0; + pol->maccntrlinfo2 = 0xffff0704; + + pol->ratecntrlinfo[0] = 0; + pol->ratecntrlinfo[1] = 0; + pol->ratecntrlinfo[2] = 0; + pol->ratecntrlinfo[3] = 0; + + pol->powercntrlinfo[0] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; + pol->powercntrlinfo[1] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; + pol->powercntrlinfo[2] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; + pol->powercntrlinfo[3] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; + + buf_ctrl->mac_control_info = EXPECTED_ACK_NORMAL_ACK | LOW_RATE_RETRY; // 0x2200 + buf_ctrl->phy_control_info = 63 << GID_TX_OFT; // 0x3f0000 + } + + for (int i = 0; i < NX_VIRT_DEV_MAX; i++) { + struct txl_buffer_control* buf_ctrl = txl_buffer_control_desc_bcmc + i; + struct tx_policy_tbl* pol = buf_ctrl->policy_tbl; + pol->upatterntx = POLICY_TABLE_PATTERN; + pol->phycntrlinfo1 = phy_get_ntx() << NX_TX_PT_OFT; + pol->phycntrlinfo2 = TX_NTX_2_ANTENNA_SET(phy_get_ntx()); + pol->maccntrlinfo1 = 0; + pol->maccntrlinfo2 = 0xffff0704; + + pol->ratecntrlinfo[0] = 0; + pol->ratecntrlinfo[1] = 0; + pol->ratecntrlinfo[2] = 0; + pol->ratecntrlinfo[3] = 0; + + pol->powercntrlinfo[0] = MAC_CORE->MAX_POWER_LEVEL.ofdmMaxPwrLevel << TX_PWR_LEVEL_PT_RCX_OFT; // 0x24 + pol->powercntrlinfo[1] = 0; + pol->powercntrlinfo[2] = 0; + pol->powercntrlinfo[3] = 0; + + buf_ctrl->mac_control_info = 0x0; // 0 + buf_ctrl->phy_control_info = 63 << GID_TX_OFT; // 0x3f0000 + } +} + +void txl_buffer_reset(void) { + /// TODO: the code here only changes list[0], but I really think it should change all of them + /* + for (int i = 0; i < NX_TXQ_CNT; i++) { + txl_buffer_env.list[i].first = NULL; + txl_buffer_env.list[i].last = NULL; + } + */ + txl_buffer_env.list[0].first = NULL; + txl_buffer_env.list[0].last = NULL; +} + +struct txl_buffer_tag *txl_buffer_alloc(struct txdesc *txdesc, uint8_t access_category, uint8_t user_idx) { + struct txl_buffer_tag* buf = &txdesc->buf; + buf->user_idx = user_idx; // 0x1b8 + + // txl_buffer_transfer + uint32_t headlen = (txdesc->umac).head_len; + buf->lenpad = (headlen + 16) & 0xfffffff0 - headlen; // 0xd4 -> 8 + struct tx_pbd* tbd = buf->tbd; // 0x104 -> 56 + tbd->upatterntx = TX_PAYLOAD_DESC_PATTERN; + buf->lenheader = headlen; // 0xd0 + if (!((txdesc->host).flags & TXU_CNTRL_MGMT)) { + txu_cntrl_frame_build(txdesc, CPU2HW(buf->payload) + headlen); + } + + struct txl_buffer_control* buf_control = &((txdesc->umac).buf_control); // 240 + memcpy(&(buf->buffer_control), buf_control, sizeof(struct txl_buffer_control)); + + // txl_buffer_push + txl_buffer_push(access_category, buf); +} + +void txl_buffer_update_thd(struct txdesc *txdesc) { + struct txl_buffer_tag* buf = (txdesc->lmac).buffer; + struct tx_hw_desc* hwdesc = (txdesc->lmac).hw_desc; + struct tx_pbd *tbd = buf->tbd_body; + int i = 0; + for (i = 0; i < 4; i++) { + uint32_t ptr = (txdesc->host).pbuf_chained_ptr[i]; + uint32_t len = (txdesc->host).pbuf_chained_len[i]; + if (ptr) { + tbd[i].upatterntx = TX_PAYLOAD_DESC_PATTERN; + tbd[i].datastartptr = ptr; + tbd[i].bufctrlinfo = 0; + tbd[i].dataendptr = ptr + len - 1; + tbd[i].next = tbd + i + 1; + } else break; + } + if (i == 0) { + printf("%s: assert when set add_pbd chain\r\n", "txl_buffer_update_thd"); + for(;;); + } + tbd[i - 1].bufctrlinfo = 0; + tbd[i - 1].next = 0; + ptr = buf->lenheader; + (buf->tbd).upatterntx = TX_PAYLOAD_DESC_PATTERN; + (buf->tbd).datastartptr = CPU2HW(&(buf->payload)); + (buf->tbd).dataendptr = CPU2HW(&(buf->payload)) + buf->lenheader - 1; + (buf->tbd).next = CPU2HW(buf->tbd_body); + (buf->tbd).bufctrlinfo = 0; + (hwdesc->thd).first_pbd_ptr = CPU2HW(buf->tbd); +} + diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer_shared.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer_shared.c new file mode 100644 index 0000000..09eac2a --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_buffer_shared.c @@ -0,0 +1,5 @@ +#include + +struct txl_buffer_control txl_buffer_control_desc[NX_REMOTE_STA_MAX]; +struct txl_buffer_control txl_buffer_control_desc_bcmc[NX_VIRT_DEV_MAX]; + diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_cfm.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_cfm.c new file mode 100644 index 0000000..e69de29 diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_cntrl.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_cntrl.c new file mode 100644 index 0000000..2df1793 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_cntrl.c @@ -0,0 +1,345 @@ +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include + + +// VHT NSYM +#define VHT_BW 4 +#define VHT_MCS 10 + +// IEEE P802.11ac D3.0 Chptr 22.5 Parameters for VHT MCSs +// Note that some BW, MCS, NSS combinations are not allowed (e.g 20MHz, MCS9, NSS 1,2) +// The NDBPS value given for MCS9 20MHz is for NSS=3 +const uint16_t VHT_NDBPS[VHT_BW][VHT_MCS] = { + // MCS Index: 0 1 2 3 4 5 6 7 8 9 + [BW_20MHZ] = {26, 52, 78, 104, 156, 208, 234, 260, 312, 1040}, + [BW_40MHZ] = {54, 108, 162, 216, 324, 432, 486, 540, 648, 720 }, + [BW_80MHZ] = {117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560}, + [BW_160MHZ] = {234, 468, 702, 936, 1404, 1872, 2106, 2340, 2808, 3120}, +}; + +/// Table containing the TX timeout value per TX queue +const uint32_t TX_TIMEOUT[NX_TXQ_CNT] = { + TX_AC0_TIMEOUT, + TX_AC1_TIMEOUT, + TX_AC2_TIMEOUT, + TX_AC3_TIMEOUT, + #if (NX_BEACONING) + TX_BCN_TIMEOUT + #endif +}; + +struct txl_cntrl_env_tag txl_cntrl_env; + + +static void txl_timer_move(uint8_t ac) +{ + __builtin_trap(); +} + +static void txl_int_fake_transfer(struct txdesc *txdesc, uint8_t access_category) { + struct txl_buffer_tag *buf = txl_buffer_get(); + buf->txdesc = txdesc; + buf->tbd.upatterntx = TX_PAYLOAD_DESC_PATTERN; + txl_buffer_push(access_category, buf); +} + +static bool txl_payload_transfer(struct txdesc *txdesc, uint8_t access_category, uint8_t user_idx) { + if ((txdesc->host).packet_addr == 0) { + txl_int_fake_transfer(txdesc,access_category); + } else { + struct txl_buffer_tag *buffer = txl_buffer_alloc(txdesc, access_category, user_idx); + (txdesc->lmac).buffer = buffer; + buffer->txdesc = txdesc; + txl_buffer_update_thd(txdesc); + } + return false; +} + +static bool txl_payload_alloc(struct txdesc *txdesc, uint8_t access_category, uint8_t user_idx) { + bool success = !txl_payload_transfer(txdesc, access_category, user_idx); + txl_payload_handle_backup(); + return !success; +} + +static void txl_hwdesc_config_pre(struct txdesc *txdesc, int access_category) { + uint8_t taillen = (txdesc->umac).tail_len; + uint8_t headlen = (txdesc->umac).head_len; + struct tx_hw_desc *hwdesc = (txdesc->lmac).hw_desc; + uint16_t packetlen = (txdesc->host).packet_len; + (hwdesc->thd).nextmpdudesc_ptr = 0; + (hwdesc->thd).frmlen = headlen + taillen + packetlen + MAC_FCS_LEN; + (hwdesc->thd).upatterntx = TX_HEADER_DESC_PATTERN; + (hwdesc->thd).nextfrmexseq_ptr = 0; + (hwdesc->thd).first_pbd_ptr = 0; + (hwdesc->thd).policyentryaddr = 0; + (hwdesc->thd).macctrlinfo2 = 0; + (hwdesc->thd).datastartptr = 0; + (hwdesc->thd).dataendptr = 0; + (hwdesc->thd).frmlifetime = 0; + (hwdesc->thd).statinfo = 0; +} + +static void txl_hwdesc_config_post(struct txdesc *txdesc, uint8_t access_category) { + __builtin_trap(); +} + +void txl_machdr_format(uint32_t machdrptr) { + // struct mac_hdr + uint16_t seq_ctrl = co_read8p(machdrptr + MAC_HEAD_CTRL_OFT) & MAC_SEQCTRL_FRAG_MSK; + if (seq_ctrl == 0) { + txl_cntrl_env.seqnbr++; + } + seq_ctrl |= txl_cntrl_env.seqnbr << MAC_SEQCTRL_NUM_OFT; + co_write16p(machdrptr + MAC_HEAD_CTRL_OFT, seq_ctrl); +} + +static void txl_cntrl_newhead(uint32_t desc, uint8_t access_category) { + __builtin_trap(); +} + +static void txl_cntrl_newtail(uint8_t access_category) { + __builtin_trap(); +} + +static void txl_frame_exchange_chain(struct tx_hd *first_thd, struct tx_hd *last_thd, uint8_t access_category) { + __builtin_trap(); +} + +static void txl_frame_exchange_done(uint8_t access_category) { + __builtin_trap(); +} + +static void txl_frame_exchange_manage(struct txdesc *txdesc, struct txl_buffer_tag *buffer, uint8_t access_category) { + __builtin_trap(); +} + +static void txl_cntrl_postpone(struct txdesc *p_txdesc, uint8_t access_category) { + (txdesc->host).tid = access_category; + // struct txl_buffer_tag*buf = txdesc->buf; + /// TODO: bl602 modified txdesc + 0xd5 and set it to 1, which is lenpad.. not really sure why + /// but we also see that at sta_mgmt_send_postponed_frame... + /// maybe just some indicator bit.. that is not refleced in the struct + *(((uint8_t*)txdesc->buf) + 9) = 1; + + return true; +} + +static bool txl_cntrl_start_pm_mon(struct mac_hdr *p_mac_hdr) { + __builtin_trap(); +} + +static void txl_check_bcmc_status(struct txdesc *txdesc, uint8_t access_category, struct mac_hdr *mac_hdr) { + __builtin_trap(); +} + +static void txl_cntrl_init(void) { + txl_hwdesc_init(); + txl_buffer_init(); + txl_cfm_init(); + txl_frame_init(false); + memset(&txl_cntrl_env, 0, sizeof(txl_cntrl_env)); + + /// TODO: it seems that TX_BCN should have id = 4.. ? + /// I'm doing that now.. + uint16_t bridgedmacnts[NX_TXQ_CNT] = { + DMA->TX_AC_0.bridgedmacnt, + DMA->TX_AC_1.bridgedmacnt, + DMA->TX_AC_2.bridgedmacnt, + DMA->TX_AC_3.bridgedmacnt, + DMA->TX_BCN.bridgedmacnt, + }; + for (int i = 0; i < NX_TXQ_CNT; i++) { + co_list_init(&(txl_cntrl_env.txlist[i].transmitting)); + txl_cntrl_env.txlist[i].last_frame_exch = NULL; + txl_cntrl_env.txlist[i].bridgedmacnt = bridgedmacnts[i]; + txl_cntrl_env.txlist[i].chk_state = THD_CHK_STATE; + } + txl_cntrl_env.seqnbr = 0; +} + +bool txl_cntrl_tx_check(struct vif_info_tag *p_vif_entry) { + if (txl_cntrl_env.reset == false) { + return chan_is_tx_allowed(p_vif_entry); + } + return false; +} + +void txl_cntrl_halt_ac(uint8_t access_category) { + switch (access_category) { + case AC_BCN: + MAC_PL->DMA_CNTRL_SET.haltBcnAfterTXOP = 1; + while (MAC_PL->DMA_STATUS_1.txBcnState != 0); + MAC_PL->DMA_CNTRL_CLEAR.haltBcnAfterTXOP = 1; + break; + case AC_VO: + MAC_PL->DMA_CNTRL_SET.haltAC3AfterTXOP = 1; + while (MAC_PL->DMA_STATUS_1.txAC3State != 0); + MAC_PL->DMA_CNTRL_CLEAR.haltAC3AfterTXOP = 1; + break; + case AC_VI: + MAC_PL->DMA_CNTRL_SET.haltAC2AfterTXOP = 1; + while (MAC_PL->DMA_STATUS_1.txAC2State != 0); + MAC_PL->DMA_CNTRL_CLEAR.haltAC2AfterTXOP = 1; + break; + case AC_BE: + MAC_PL->DMA_CNTRL_SET.haltAC1AfterTXOP = 1; + while (MAC_PL->DMA_STATUS_1.txAC1State != 0); + MAC_PL->DMA_CNTRL_CLEAR.haltAC1AfterTXOP = 1; + break; + case AC_BK: + MAC_PL->DMA_CNTRL_SET.haltAC0AfterTXOP = 1; + while (MAC_PL->DMA_STATUS_1.txAC0State != 0); + MAC_PL->DMA_CNTRL_CLEAR.haltAC0AfterTXOP = 1; + break; + default: + ASSERT_ERR(0); + } +} + +void txl_cntrl_flush_ac(uint8_t access_category, uint32_t status) { + uint32_t timer_bit = CO_BIT(TX_AC2TIMER(access_category)); + struct txl_list *txlist = &txl_cntrl_env.txlist[access_category]; + txl_cfm_flush(access_category, txl_cfm_env.cfmlist + access_category, status); + txl_cfm_flush(access_category, &txl_cntrl_env.txlist[access_category].transmitting, status); + + txl_cntrl_env.txlist[access_category].last_frame_exch = NULL; + + txl_buffer_reset(); + + MAC_PL->TIMERS_INT_UN_MASK.value = MAC_PL->TIMERS_INT_UN_MASK.value & ~timer_bit; + MAC_PL->TIMERS_INT_EVENT_CLEAR = timer_bit; +} + +void txl_cntrl_clear_bcn_ac(void) { + txl_cntrl_halt_ac(AC_BCN); + txl_cntrl_flush_ac(AC_BCN, 0x40000000); +} + +void txl_cntrl_clear_all_ac(void) { + txl_cntrl_halt_ac(AC_BCN); + txl_cntrl_flush_ac(AC_BCN, 0x40000000); + txl_cntrl_halt_ac(AC_BK); + txl_cntrl_flush_ac(AC_BK, 0x40000000); + txl_cntrl_halt_ac(AC_BE); + txl_cntrl_flush_ac(AC_BE, 0x40000000); + txl_cntrl_halt_ac(AC_VI); + txl_cntrl_flush_ac(AC_VI, 0x40000000); + txl_cntrl_halt_ac(AC_VO); + txl_cntrl_flush_ac(AC_VO, 0x40000000); +} + +/// TODO: the buffer allocation never failed?? +bool txl_cntrl_push(struct txdesc *txdesc, uint8_t access_category) { + txl_hwdesc_config_pre(txdesc, access_category); + __disable_irq(); + txl_payload_alloc(txdesc, access_category, 0); + co_list_push_back(&txl_cntrl_env.txlist[access_category].transmitting, &txdesc->list_hdr); + __enable_irq(); + txl_cntrl_env.pck_cnt++; + td_pck_ind((txdesc->host).vif_idx, (txdesc->host).staid, false); + ps_check_tx_frame((txdesc->host).staid, (txdesc->host).tid); + return false; +} + +void txl_cntrl_inc_pck_cnt(void) { + txl_cntrl_env.pck_cnt ++; +} + +bool txl_cntrl_push_int(struct txdesc *txdesc, uint8_t access_category) { + struct tx_hw_desc* hwdesc = (txdesc->lmac).hw_desc; + if (txl_cntrl_tx_check(vif_info_tab + (txdesc->host).vif_idx)) { + if (apm_tx_int_ps_check(txdesc)) { + (hwdesc->thd).macctrlinfo2 = (hwdesc->thd).macctrlinfo2 | INTERRUPT_EN_TX; + __disable_irq(); + txl_int_fake_transfer(txdesc,access_category); + co_list_push_back(&txl_cntrl_env.txlist[access_category].transmitting,&txdesc->list_hdr); + __enable_irq(); + txl_cntrl_env.pck_cnt ++; + txl_payload_handle_backup(); + return true; + } + } + #if (NX_CHNL_CTXT || NX_P2P) + if ((txdesc->host).staid != INVALID_STA_IDX) { + txl_frame_release(txdesc, false); + return false; + } else { + txl_cntrl_postpone(txdesc, access_category); + return true; + } + #endif + + return true; +} + +bool txl_cntrl_push_int_force(struct txdesc *txdesc, uint8_t access_category) { + struct tx_hw_desc *hwdesc = (txdesc->lmac).hw_desc; + (hwdesc->thd).macctrlinfo2 = (hwdesc->thd).macctrlinfo2 | INTERRUPT_EN_TX; + __disable_irq(); + txl_int_fake_transfer(txdesc,access_category); + co_list_push_back(&txl_cntrl_env.txlist[CONCAT31(in_register_0000202d,access_category)]. + transmitting,&txdesc->list_hdr); + __enable_irq(); + txl_cntrl_env.pck_cnt++; + txl_payload_handle_backup(); + + return true; +} + +void txl_payload_handle(void) { + for (uint32_t status = DMA->int_status.TX; status; status = DMA->int_status.TX) { + int ldz = __builtin_clz(status); + DMA->int_ack = 1 << (31 - (ldz & 31)); + } +} + +void txl_payload_handle_backup(void) { + __builtin_trap(); +} + +void txl_transmit_trigger(void) +{ + __builtin_trap(); +} + +void txl_current_desc_get(int access_category, struct tx_hd **thd) +{ + __builtin_trap(); +} + +void txl_reset(void) +{ + __builtin_trap(); +} + +void txdesc_dump(struct txdesc *txdesc) +{ + __builtin_trap(); +} + +void txl_cntrl_env_dump(void) +{ + __builtin_trap(); +} + diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_frame.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_frame.c new file mode 100644 index 0000000..0bc5ea2 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_frame.c @@ -0,0 +1,532 @@ +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include + +#include + +static struct txl_frame_desc_tag txl_frame_desc[NX_TXFRAME_CNT]; +struct txl_frame_env_tag txl_frame_env; + +void txl_frame_init_desc(struct txl_frame_desc_tag *frame, struct txl_buffer_tag *buffer, struct tx_hw_desc *hwdesc, struct txl_buffer_control *bufctrl) { + memset(frame, 0, sizeof(struct txl_frame_desc_tag)); + (hwdesc->thd).upatterntx = TX_HEADER_DESC_PATTERN; + (hwdesc->thd).datastartptr = CPU2HW(buffer->payload); + (hwdesc->thd).frmlifetime = 0; + (hwdesc->thd).optlen[0] = 0; + (hwdesc->thd).optlen[1] = 0; + (hwdesc->thd).optlen[2] = 0; + bufctrl->policy_tbl.upatterntx = POLICY_TABLE_PATTERN; + (frame->txdesc).lmac.hw_desc = hwdesc; + (frame->txdesc).lmac.buffer = buffer; + (frame->txdesc).umac.buf_control = bufctrl; + frame->type = TX_EXT; +} + +void txl_frame_init(bool reset) { + co_list_init(&txl_frame_env.desc_free); + co_list_init(&txl_frame_env.desc_used); + + for (int i = 0; i < NX_TXFRAME_CNT; i ++) { + struct txl_frame_desc_tag* desc = txl_frame_desc + i; + struct tx_hw_desc_s* hwdesc = txl_frame_hwdesc_pool + i; + struct txl_buffer_control *bufctrl = txl_frame_buf_ctrl + i; + struct txl_buffer_tag *buffer = (struct txl_buffer_tag *)(txl_frame_pool + i); + if ((reset == 0) || (desc->postponed == false)) { + memset(desc, 0, sizeof(struct txl_frame_desc_tag)); // 0xd8 == 216 + hwdesc->thd.upatterntx = TX_HEADER_DESC_PATTERN; + + (hwdesc->thd).frmlifetime = 0; + (hwdesc->thd).optlen[0] = 0; + (hwdesc->thd).optlen[1] = 0; + (hwdesc->thd).optlen[2] = 0; + bufctrl->policy_tbl.upatterntx = POLICY_TABLE_PATTERN; + + (desc->txdesc).lmac.buffer = buffer; + hwdesc->cfm_ptr = txl_frame_hwdesc_cfms + i; + + hwdesc->thd.datastartptr = CPU2HW(&(buffer->payload)); // 0x14c + (desc->txdesc).umac.buf_control = bufctrl; + (desc->txdesc).lmac.hw_desc = hwdesc; + desc->type = TX_INT; + + co_list_push_back(&txl_frame_env.desc_free, &desc->txdesc.list_hdr); + } + } + txl_buffer_control_24G.policy_tbl.upatterntx = POLICY_TABLE_PATTERN; + txl_buffer_control_24G.policy_tbl.mac_control_info = 0; + txl_buffer_control_24G.policy_tbl.phy_control_info = 0; + txl_buffer_control_24G.policy_tbl.phycntrlinfo1 = phy_get_ntx() << NX_TX_PT_OFT; + txl_buffer_control_24G.policy_tbl.phycntrlinfo2 = TX_NTX_2_ANTENNA_SET(phy_get_ntx()); + + txl_buffer_control_24G.policy_tbl.maccntrlinfo1 = 0; + txl_buffer_control_24G.policy_tbl.maccntrlinfo2 = 0xffff0704; + txl_buffer_control_24G.policy_tbl.ratecntrlinfo[0] = (HW_RATE_1MBPS << MCS_INDEX_TX_RCX_OFT) | PRE_TYPE_TX_RCX_MASK; // 0x400; + txl_buffer_control_24G.policy_tbl.ratecntrlinfo[1] = 0; + txl_buffer_control_24G.policy_tbl.ratecntrlinfo[2] = 0; + txl_buffer_control_24G.policy_tbl.ratecntrlinfo[3] = 0; + + txl_buffer_control_24G.policy_tbl.powercntrlinfo[1] = 0; + txl_buffer_control_24G.policy_tbl.powercntrlinfo[2] = 0; + txl_buffer_control_24G.policy_tbl.powercntrlinfo[3] = 0; +} + + +static uint32_t tx_count; +static uint32_t rx_count; +extern uint8_t mac_hw_reset; + +struct txl_frame_desc_tag *txl_frame_get(int type, int len) { + struct txl_frame_desc_tag * desc = co_list_pop_front(&txl_frame_env.desc_free); + if (!desc) { + tx_count++; + if (tx_count == 10) { + tx_count = 0; + rx_count = 2; + int cnt1 = co_list_cnt(&txl_frame_env.desc_free); + int cnt2 = co_list_cnt(&txl_frame_env.desc_done); + if ((cnt1 | cnt2) == 0) { + txl_cntrl_clear_all_ac(); + } + } + return 0; + } else { + if (rx_count == 1) { + rx_count = 0; + mac_hw_reset = 1; + + vTaskEnterCritical(); + assert_rec("MAC HW RESET include tx and rx", "tx rx", __LINE__); + vTaskDelay(200); + vTaskExitCritical(); + return 0; + } else { + if (rx_count != 0) { + rx_count = rx_count - 1; + } + struct tx_hw_desc *hwdesc = (desc->txdesc).lmac.hw_desc; + struct txl_buffer_tag *buffer = (desc->txdesc).lmac.buffer; + (hwdesc->thd).frmlen = len + MAC_FCS_LEN; + (hwdesc->thd).dataendptr = (hwdesc->thd).datastartptr + len + -1; + if (type == TX_DEFAULT_24G) { + memcpy(&buffer->buffer_control.policy_tbl, &txl_buffer_control_24G.policy_tbl, sizeof(struct tx_policy_tbl)); // len = 0x34 + } + /* 0x114 */ + (buffer->buffer_control).policy_tbl.powercntrlinfo[0] = tpc_get_vif_tx_power_vs_rate((buffer->buffer_control).policy_tbl.ratecntrlinfo[0]); // 0x104(buffer) + (hwdesc->thd).policyentryaddr = CPU2HW(&buffer->buffer_control.policy_tbl); + (hwdesc->thd).phyctrlinfo = 0; + (hwdesc->thd).macctrlinfo2 = 0; + (hwdesc->thd).first_pbd_ptr = 0; // 0x10 = 16 - 4 = 12 + (ptVar2->cfm).cfm_func = (cfm_func_ptr *)0x0; + (ptVar2->cfm).env = (void *)0x0; + return desc; + } + } + return 0; +} + +bool txl_frame_push(struct txl_frame_desc_tag *frame, uint8_t ac) { + struct tx_hw_desc* hwdesc = frame->txdesc.lmac.hw_desc; + struct tx_hd* thd = &(hwdesc->thd); + ASSERT_ERR((thd->datastartptr & 0x01) == 0); + + thd->nextfrmexseq_ptr = 0; + thd->nextmpdudesc_ptr = 0; + thd->macctrlinfo2 = thd->macctrlinfo2 & ~(WHICHDESC_MSK | UNDER_BA_SETUP_BIT); + + struct mac_hdr *hdr = HW2CPU(thd->datastartptr); + + if (MAC_ADDR_GROUP(&hdr->addr1)) { + thd->macctrlinfo1 = EXPECTED_ACK_NO_ACK; + } else { + thd->macctrlinfo1 = EXPECTED_ACK_NORMAL_ACK; + } + thd->statinfo = 0; + return txl_cntrl_push_int(&frame->txdesc, ac); +} + +bool txl_frame_push_force(struct txl_frame_desc_tag *frame, uint8_t ac) { + /// TODO: I can't see any difference between the two functions + struct tx_hw_desc* hwdesc = frame->txdesc.lmac.hw_desc; + struct tx_hd* thd = &(hwdesc->thd); + ASSERT_ERR((thd->datastartptr & 0x01) == 0); + + thd->nextfrmexseq_ptr = 0; + thd->nextmpdudesc_ptr = 0; + thd->macctrlinfo2 = thd->macctrlinfo2 & ~(WHICHDESC_MSK | UNDER_BA_SETUP_BIT); + + struct mac_hdr *hdr = HW2CPU(thd->datastartptr); + + if (MAC_ADDR_GROUP(&hdr->addr1)) { + thd->macctrlinfo1 = EXPECTED_ACK_NO_ACK; + } else { + thd->macctrlinfo1 = EXPECTED_ACK_NORMAL_ACK; + } + thd->statinfo = 0; + return txl_cntrl_push_int(&frame->txdesc, ac); +} + +void txl_frame_cfm(struct txdesc *txdesc) { + co_list_push_back(&txl_frame_env.desc_done, &txdesc->list_hdr); + ke_evt_set(KE_EVT_TXFRAME_CFM_BIT); +} + +void txl_frame_release(struct txdesc *txdesc, bool postponed) { + struct txl_frame_desc_tag *frame = (struct txl_frame_desc_tag *)txdesc; + if (frame->type == TX_INT) { + co_list_push_back(&txl_frame_env.desc_free, &(txdesc->list_hdr)); + } else { + if (postponed && frame->cfm) { + frame->cfm.cfm_func(frame->cfm.env, 0); + } + } +} + +void txl_frame_evt(int dummy) { + ke_evt_clear(KE_EVT_TXFRAME_CFM_BIT); + + while (true) { + __disable_irq(); + struct txl_frame_desc_tag *frame = (struct txl_frame_desc_tag *)co_list_pop_front(&txl_frame_env.desc_done); + __enable_irq(); + + if (frame == NULL) + break; + + txl_cntrl_env.pck_cnt--; + + if (frame->cfm.cfm_func != 0) { + frame->cfm.cfm_func(frame->cfm.env, (((frame->txdesc).lmac.hw_desc)->thd).statinfo); + if (frame->keep_desc) { + frame->keep_desc = false; + continue; + } + } + + if (frame->type == TX_INT) { + co_list_push_back(&txl_frame_env.desc_free, &frame->txdesc.list_hdr); + } + + } +} + +uint8_t txl_frame_send_null_frame(uint8_t sta_idx, cfm_func_ptr cfm, void *env) { + struct sta_info_tag* sta = sta_info_tab + sta_idx; + struct phy_channel_info phy_info; + phy_get_channel(&phy_info, 0); + uint8_t band = phy_info.info1 & 0xFF; + // Chose the right rate according to the band + int txtype = (band == PHY_BAND_2G4)?TX_DEFAULT_24G:TX_DEFAULT_5G; + struct txl_frame_desc_tag *frame = txl_frame_get(txtype, MAC_NULL_FRAME_SIZE); // 0x18 + + if (frame) { + struct vif_info_tag* vif = vif_info_tab + sta->inst_nbr; + tpc_update_frame_tx_power(vif, frame); + struct txl_buffer_tag *buffer = (frame->txdesc).lmac.buffer; + struct mac_hdr *payload = &(buffer->payload); + payload->fctl = MAC_FCTRL_NULL_FUNCTION | MAC_FCTRL_TODS; + payload->durid = 0; + memcpy(payload->addr1, sta->mac_addr, sizeof(struct mac_addr)); + memcpy(payload->addr2, vif->mac_addr, sizeof(struct mac_addr)); + memcpy(payload->addr3, sta->mac_addr, sizeof(struct mac_addr)); + payload->seq = txl_get_seq_ctrl(); + (frame->cfm).cfm_func = cfm; + (frame->cfm).env = env; + (frame->txdesc).host.staid = sta_idx; + (frame->txdesc).host.vif_idx = sta->inst_nbr; + txl_frame_push(frame, AC_VO); + + return CO_OK; + } + + return CO_FAIL; +} + +uint8_t txl_frame_send_qosnull_frame(uint8_t sta_idx, uint16_t qos, cfm_func_ptr cfm, void *env) { + struct sta_info_tag* sta = sta_info_tab + sta_idx; + struct phy_channel_info phy_info; + phy_get_channel(&phy_info, 0); + uint8_t band = phy_info.info1 & 0xFF; + // Chose the right rate according to the band + int txtype = (band == PHY_BAND_2G4)?TX_DEFAULT_24G:TX_DEFAULT_5G; + struct txl_frame_desc_tag *frame = txl_frame_get(txtype, MAC_QOS_NULL_FRAME_SIZE); // 0x1a + + if (frame) { + struct vif_info_tag* vif = vif_info_tab + sta->inst_nbr; + tpc_update_frame_tx_power(vif, frame); + struct txl_buffer_tag *buffer = (frame->txdesc).lmac.buffer; + struct mac_hdr_qos *payload = &(buffer->payload); + + payload->fctl = MAC_FCTRL_QOS_NULL; + payload->durid = 0; + memcpy(payload->addr1, sta->mac_addr, sizeof(struct mac_addr)); + memcpy(payload->addr2, vif->mac_addr, sizeof(struct mac_addr)); + if (vif->type == VIF_STA) { + payload->fctl |= MAC_FCTRL_TODS; + memcpy(payload->addr3, sta->mac_addr, sizeof(struct mac_addr)); + } else { + payload->fctl |= MAC_FCTRL_FROMDS; + memcpy(payload->addr3, vif->mac_addr, sizeof(struct mac_addr)); + } + + payload->seq = 0; + payload->qos = qos; + + frame->cfm.cfm_func = cfm; + frame->cfm.env = env; + + frame->txdesc.host.vif_idx = sta->inst_nbr; + frame->txdesc.host.staid = sta_idx; + txl_frame_push(frame, AC_VO); + + return CO_OK; + } + return CO_FAIL; +} + +// inlined part of txl_frame_send_eapol_frame +uint8_t txl_frame_sechdr_len_compute(struct txdesc *txdesc) { + int sta_idx = txdesc->host.staid; + struct sta_info_tag* sta = sta_info_tab + sta_idx; + struct vif_info_tag* vif = vif_info_tab + txdesc->host.vif_idx; + uint8_t iVar9 = 0; + uint8_t len_sec_hdr = 0; + if ((vif->type == VIF_STA) && (sta->ctrl_port_state == PORT_CLOSING)) { + struct key_info_tag * keyinfo = *(sta->sta_sec_info.cur_key); + if ((keyinfo->cipher == MAC_RSNIE_CIPHER_TKIP) || (keyinfo->cipher == MAC_RSNIE_CIPHER_WEP104)) { + // == 1 + keyinfo->tx_pn++; + memcpy((txdesc)->host.pn, keyinfo->tx_pn, 6); // why here is 6??? + iVar9 = 12; + len_sec_hdr = 8; + } else { + if (keyinfo->cipher == MAC_RSNIE_CIPHER_WEP40) { + keyinfo->tx_pn++; + memcpy((txdesc)->host.pn,&keyinfo->tx_pn, 4); + iVar9 = 4; + len_sec_hdr = 4; + } else { + if (keyinfo->cipher == MAC_RSNIE_CIPHER_CCMP) { + keyinfo->tx_pn++; + memcpy((txdesc)->host.pn,&keyinfo->tx_pn, 6); + iVar9 = 8; + len_sec_hdr = 8; + } else { + iVar9 = 0; + len_sec_hdr = 0; + } + } + } + } + /// TODO: I don't understand this length calc for ivar9.. + return sec_hdr + iVar9; +} + +/* +uint8_t txl_frame_sec_hdr_append(struct txdesc *txdesc, uint32_t buf) { + __builtin_trap(); +} + +void txl_frame_tkip_mic_append(struct txdesc *txdesc, uint8_t *buf, uint32_t len) { + __builtin_trap(); +} +*/ + + +/// TODO: this function need extra verify +uint8_t txl_frame_send_eapol_frame(uint8_t sta_idx, cfm_func_ptr cfm, void *cfm_env, uint8_t *pBuf, uint32_t pBuf_len) { + struct sta_info_tag* sta = sta_info_tab + sta_idx; + struct phy_channel_info phy_info; + phy_get_channel(&phy_info, 0); + uint8_t band = phy_info.info1 & 0xFF; + // Chose the right rate according to the band + int txtype = (band == PHY_BAND_2G4)?TX_DEFAULT_24G:TX_DEFAULT_5G; + struct txl_frame_desc_tag *frame = txl_frame_get(txtype, NX_TXFRAME_LEN); // 0x100 + + if (!frame) { + /// TODO: WTF?? the assembly says return 0 here??? + return CO_OK; + } + + struct vif_info_tag* vif = vif_info_tab + sta->inst_nbr; + (frame->txdesc).host.vif_idx = sta->inst_nbr; + (frame->txdesc).host.staid = sta_idx; + (frame->txdesc).host.tid = 0; + + uint16_t sn = sta->seq_nbr[0]; + sta->seq_nbr[0] = (sn + 1) & 0xfff; + (frame->txdesc).host.ethertype = 0x8e88; + (frame->txdesc).host.sn = sn; + memcpy(&((frame->txdesc).host.eth_dest_addr.array), &(sta->mac_addr.array), sizeof(struct mac_addr)); + memcpy(&((frame->txdesc).host.eth_src_addr.array), &(vif->mac_addr.array), sizeof(struct mac_addr)); + + tpc_update_frame_tx_power(vif,frame); + struct txl_buffer_tag *buffer = (frame->txdesc).lmac.buffer; + //struct txl_buffer_tag *payload = + struct eapol_payload* eapol_payload = NULL; + uint32_t length = pBuf_len; + if (!(vif->bss_info.valid_flags & 1)) { + //MAC_FCTRL_DATA_T + struct mac_hdr* data = &(buffer->payload); + //len += 0x20 = buffer + //struct mac_hdr + //} + data->fctl = MAC_FCTRL_DATA_T; // 8 + data->seq = txl_get_seq_ctrl(); + eapol_payload = (struct eapol_payload*)(data + 1); + length += sizeof(struct mac_hdr) + sizeof(struct eapol_payload); + } else { + //MAC_FCTRL_QOS_DATA 0x88? + struct mac_hdr_qos* data = &(buffer->payload); + data->fctl = MAC_FCTRL_QOS_DATA; // 0x88 + data->seq = (frame->txdesc).host.sn << MAC_SEQCTRL_NUM_OFT; + data->qos = (frame->txdesc).host.tid; + //len += 0x22 + eapol_payload = (struct eapol_payload*)(data + 1); + length += sizeof(struct mac_hdr_qos) + sizeof(struct eapol_payload); + } + + ASSERT_ERR(length <= NX_TXFRAME_LEN); + + // -332 = data + struct mac_hdr* payload = &(buffer->payload); + payload->durid = 0; + // 0z152 + memcpy(payload->addr1, sta->mac_addr, sizeof(struct mac_addr)); + // 0x156 + memcpy(payload->addr2, vif->mac_addr, sizeof(struct mac_addr)); + + // 0x15c + if (vif->type == VIF_STA) { + // 0x0 = sta + payload->fctl |= MAC_FCTRL_TODS; + memcpy(payload->addr3, sta->mac_addr, sizeof(struct mac_addr)); + } else { + // 0x2 = vif + payload->fctl |= MAC_FCTRL_FROMDS; + memcpy(payload->addr3, vif->mac_addr, sizeof(struct mac_addr)); + } + + // buffer = { + // 2 bytes of 0xaaaa + // 2 bytes of 0x3 = FRAME_BODY_LLC_H + // 2 bytes of 0 + // 2 bytes os (frame->txdesc).host.ethertype + // data + int sechdrlen = txl_frame_sechdr_len_compute(txdesc); + length += sechdrlen; + if (sechdrlen != 0) { // if length != 0 + // payload + payload->fctl |= MAC_FCTRL_PROTECTEDFRAME; // = 0x4000; + uint16_t* sechdr = (uint16_t*)eapol_payload; + // till now is current function + // function: txl_frame_sec_hdr_append + int secbytes = 0; + if (sta->ctrl_port_state == PORT_CLOSING) { + struct key_info_tag * keyinfo = *(sta->sta_sec_info.cur_key); + struct tx_policy_tbl *pol = HW2CPU((((frame->txdesc).lmac.hw_desc)->thd).policyentryaddr); + switch (keyinfo->cipher) { + /// TODO: here the packet number goes really weird... even the endian.. + /// I'm also wondering if there are other parts using different endian? + case MAC_RSNIE_CIPHER_TKIP: { + secbytes = 8; + uint16_t pn0 = (frame->txdesc).host.pn[0]; + sechdr[0] = (pn0 & 0x7f00 | 0x2000) | (pn0 >> 8); + sechdr[1] = ((pn0 & 0xff) | keyinfo->key_idx << 0xe) | 0x2000; + sechdr[2] = (frame->txdesc).host.pn[1]; + sechdr[3] = (frame->txdesc).host.pn[2]; + break; + } + case MAC_RSNIE_CIPHER_CCMP:{ + secbytes = 8; + uint16_t pn0 = (frame->txdesc).host.pn[0]; + sechdr[0] = pn0; + sechdr[1] = (keyinfo->key_idx << 0xe) | 0x2000; + sechdr[2] = (frame->txdesc).host.pn[1]; + sechdr[3] = (frame->txdesc).host.pn[2]; + break; + } + case MAC_RSNIE_CIPHER_WEP40: + case MAC_RSNIE_CIPHER_WEP104: { + secbytes = 4; + sechdr[0] = (frame->txdesc).host.pn[0]; + sechdr[1] = (frame->txdesc).host.pn[1] | (keyinfo->key_idx << 0xe); + } + default: + break; + } + pol->maccntrlinfo1 = pol->maccntrlinfo1 & 0xffc00 | keyinfo->hw_key_idx; + } + eapol_payload = (struct eapol_payload* ) (((uint8_t*)eapol_payload) + secbytes); + } + + eapol_payload->llc = FRAME_BODY_LLC_H; + eapol_payload->zero = 0; + eapol_payload->eth_type = (frame->txdesc).host.ethertype; + + memcpy(eapol_payload + 1, pBuf, pBuf_len); + uint8_t *ebufptr = eapol_payload + 1; + + if (sechdrlen != 0) { + // txl_frame_tkip_mic_append + struct key_info_tag * keyinfo = *(sta->sta_sec_info.cur_key); + if (keyinfo->cipher == MAC_RSNIE_CIPHER_TKIP) { + struct mic_calc mic_calc; + struct hostdesc *host = &(frame->txdesc.host); + me_mic_init(&mic_calc, (uint32_t *)&keyinfo->u, + (struct mac_addr *)&host->eth_dest_addr, + (struct mac_addr *)&host->eth_src_addr,&host->tid); + /// TODO: why +8? + me_mic_calc(&mic_calc, (uint32_t)(ebufptr), pBuf_len + 8); + me_mic_end(&mic_calc); + co_copy8p(CPU2HW(ebufptr + pBuf_len), CPU2HW(&mic_calc), 8); + } + // end of func + } + struct tx_hw_desc * hwdesc = (frame->txdesc).lmac.hw_desc; + hwdesc->thd.dataendptr = hwdesc->thd.datastartptr - 1 + length; + hwdesc->thd.frmlen = length + MAC_FCS_LEN; + if (cfm != 0x0) { + (frame->cfm).cfm_func = cfm; + (frame->cfm).env = cfm_env; + } + + txl_frame_push(frame, mac_tid2ac[(frame->txdesc).host.tid]); + return CO_OK; +} + +void txl_frame_dump(void) { + int cnt = co_list_cnt(&txl_frame_env.desc_free); + struct txdesc* desc = co_list_pick(&txl_frame_env.desc_free); + if (cnt != 0) { + for (; desc; desc = co_list_next(&desc->list_hdr)) { + + } + desc = co_list_pick(&txl_frame_env.desc_done); + for (; desc; desc = co_list_next(&desc->list_hdr)) { + + } + } +} + diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_frame_shared.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_frame_shared.c new file mode 100644 index 0000000..7d45444 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_frame_shared.c @@ -0,0 +1,54 @@ +#include +#include + +#include + +uint32_t txl_frame_pool[NX_TXFRAME_CNT][(sizeof(struct txl_buffer_tag) + NX_TXFRAME_LEN) / 4]; + + +#if NX_BCN_AUTONOMOUS_TX +//uint32_t txl_tim_ie_pool[NX_VIRT_DEV_MAX][CO_ALIGN4_HI(MAC_TIM_BMP_OFT + 1)/4]; +//uint32_t txl_tim_bitmap_pool[NX_VIRT_DEV_MAX][CO_ALIGN4_HI(MAC_TIM_SIZE)/4]; +uint8_t txl_tim_ie_pool[CO_ALIGN4_HI(MAC_TIM_BMP_OFT + 1)]; +uint8_t txl_tim_bitmap_pool[CO_ALIGN4_HI(MAC_TIM_SIZE)]; + +//struct tx_pbd txl_tim_desc[NX_VIRT_DEV_MAX][2]; +struct tx_pbd txl_tim_desc[2]; + +uint32_t txl_bcn_pool[(sizeof(struct txl_buffer_tag) + NX_BCNFRAME_LEN)]; +//struct tx_hw_desc_s txl_bcn_hwdesc_pool[NX_VIRT_DEV_MAX]; +struct tx_hw_desc_s txl_bcn_hwdesc_pool; +struct tx_pbd txl_bcn_end_desc;//[NX_VIRT_DEV_MAX]; + +struct txl_buffer_control txl_bcn_buf_ctrl;//[NX_VIRT_DEV_MAX]; + +#if (NX_P2P_GO) +/// Pool of P2P NOA payload descriptors +struct tx_pbd txl_p2p_noa_desc[NX_VIRT_DEV_MAX]; +/// Pool of P2P NOA Attributes +uint16_t txl_p2p_noa_ie_pool[NX_VIRT_DEV_MAX][P2P_NOA_IE_BUFFER_LEN]; +#endif //(NX_P2P_GO) + +#if (RW_MESH_EN) +// Payload Descriptor for additional IEs of Mesh Beacon +struct tx_pbd txl_mesh_add_ies_desc[RW_MESH_VIF_NB]; +// Buffer containing the additional IEs of Mesh Beacon +struct mesh_add_ies_tag txl_mesh_add_ies[RW_MESH_VIF_NB]; +#endif //(RW_MESH_EN) +#endif //(NX_BCN_AUTONOMOUS_TX) + +struct tx_hw_desc_s txl_frame_hwdesc_pool[NX_TXFRAME_CNT] ; + +/// Default buffer control structure for 2.4GHz band +struct txl_buffer_control txl_buffer_control_24G; + +#if (RW_BFMER_EN) +/// Default policy table for transmission of NDPA and BRP frames sent during Beamforming Sounding procedure +struct txl_buffer_control txl_buffer_control_ndpa_brp; +/// Default policy table for NDP frame sent during Beamforming Sounding procedure +struct txl_buffer_control txl_buffer_control_ndp; +#endif //(RW_BFMER_EN) + +struct txl_buffer_control txl_frame_buf_ctrl[NX_TXFRAME_CNT] ; + +#endif \ No newline at end of file diff --git a/src/bl602_wifi/ip/lmac/tx/txl/txl_hwdesc.c b/src/bl602_wifi/ip/lmac/tx/txl/txl_hwdesc.c new file mode 100644 index 0000000..e98a942 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/tx/txl/txl_hwdesc.c @@ -0,0 +1,10 @@ +#include + +void txl_hwdesc_init(void) { + +} + +void txl_hwdesc_reset(void) { + +} + diff --git a/src/bl602_wifi/ip/lmac/vif/vif_mgmt.c b/src/bl602_wifi/ip/lmac/vif/vif_mgmt.c new file mode 100644 index 0000000..fc1a504 --- /dev/null +++ b/src/bl602_wifi/ip/lmac/vif/vif_mgmt.c @@ -0,0 +1,325 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include + +struct vif_mgmt_env_tag vif_mgmt_env; +struct vif_info_tag vif_info_tab[NX_VIRT_DEV_MAX]; + +static void vif_mgmt_bcn_to_evt(void *env) { + struct vif_info_tag *p_info_env = (struct vif_info_tag *)env; + if (p_info_env->chan_ctxt != 0) { + chan_bcn_to_evt(p_info_env); + return; + } +} + +static void vif_mgmt_entry_init(struct vif_info_tag *vif_entry) { + memset(vif_entry, 0, sizeof(*vif_entry)); + + vif_entry->type = VIF_UNKNOWN; + vif_entry->tx_power = VIF_UNDEF_POWER; + vif_entry->user_tx_power = VIF_UNDEF_POWER; + + #if (NX_P2P || NX_CHNL_CTXT) + vif_entry->tmr_bcn_to.cb = vif_mgmt_bcn_to_evt; + vif_entry->tmr_bcn_to.env = vif_entry; + #endif +} + +void vif_mgmt_init(void) { + memset(&vif_mgmt_env, 0, sizeof(struct vif_mgmt_env_tag)); + co_list_init(&vif_mgmt_env.free_list); + co_list_init(&vif_mgmt_env.used_list); + for (int i = 0; i < NX_VIRT_DEV_MAX; i++) { + vif_mgmt_entry_init(&vif_info_tab[i]); + co_list_push_back(&vif_mgmt_env.free_list, &vif_info_tab[i].list_hdr); + } +} + +void vif_mgmt_reset(void) { + struct vif_info_tag *p_vif_entry = co_list_pick(&vif_mgmt_env.used_list); + + for (; p_vif_entry != NULL; p_vif_entry = co_list_next(&p_vif_entry->list_hdr)) { + vif_mgmt_send_postponed_frame(p_vif_entry); + } +} + +uint8_t vif_mgmt_register(const struct mac_addr *mac_addr, uint8_t vif_type, bool p2p, uint8_t *vif_idx) { + if (co_list_is_empty(&vif_mgmt_env.free_list)) { + return 1; + } + + if (co_list_is_empty(&vif_mgmt_env.used_list)) { + mm_hw_info_set(mac_addr); + } else { + if (*((uint32_t*)(mac_addr->array)) != MAC_CORE->MAC_ADDR_LOW.value) { + return CO_FAIL; + } + + if ((MAC_CORE->MAC_ADDR_HI.value & ~(MAC_CORE->MAC_ADDR_HI_MASK.value)) != *((uint32_t*)(mac_addr->array + 2))) { + return CO_FAIL; + } + + mm_rx_filter_lmac_enable_set(NXMAC_ACCEPT_OTHER_BSSID_BIT); + } + + struct vif_info_tag* vif_entry = (struct vif_info_tag *) co_list_pop_front(&vif_mgmt_env.free_list); + + vif_entry->type = vif_type; + vif_entry->mac_addr = *mac_addr; + vif_entry->index = CO_GET_INDEX(vif_entry, vif_info_tab); + + // reset values + vif_entry->txq_params[AC_BK] = 0x0a47; + vif_entry->txq_params[AC_BE] = 0xa43; + vif_entry->txq_params[AC_VI] = 0x5e432; + vif_entry->txq_params[AC_VO] = 0x2f322; + + #if (NX_CHNL_CTXT) + vif_entry->chan_ctxt = NULL; + (vif_entry->tbtt_switch).vif_index = vif_entry->index; + #endif + + switch (vif_type) { + case VIF_STA: { + (vif_entry->tbtt_timer).env = vif_entry; + vif_entry->u.sta.csa_count = 0; + vif_mgmt_env.vif_sta_cnt = vif_mgmt_env.vif_sta_cnt + 1; + vif_entry->tbtt_timer.cb = mm_sta_tbtt; + vif_entry->u.sta.ap_id = 0xff; + vif_entry->u.sta.csa_occured = 0; + break; + } + case VIF_AP: { + if (vif_mgmt_env.vif_ap_cnt == 0) { + mm_hw_ap_info_set(); + } + vif_mgmt_env.vif_ap_cnt++; + mm_bcn_init_vif(vif_entry); + break;; + } + default: + break; + } + + td_start(vif_entry->index); + *vif_idx = vif_entry->index; + co_list_push_back(&vif_mgmt_env.used_list,&vif_entry->list_hdr); + return CO_OK; +} + +void vif_mgmt_unregister(uint8_t vif_idx) { + struct vif_info_tag *vif_entry = &vif_info_tab[vif_idx]; + co_list_extract(&vif_mgmt_env.used_list, &vif_entry->list_hdr); + switch (vif_entry->type) { + case VIF_STA: { + vif_mgmt_env.vif_sta_cnt--; + break; + } + case VIF_AP: { + vif_mgmt_env.vif_ap_cnt--; + if (vif_mgmt_env.vif_ap_cnt == 0) + mm_hw_ap_info_reset(); + break; + } + default: + break; + } + + if (vif_mgmt_used_cnt() == 1) { + mm_rx_filter_lmac_enable_clear(NXMAC_ACCEPT_OTHER_BSSID_BIT); + struct vif_info_tag* vif_next = co_list_pick(&vif_mgmt_env.used_list); + MAC_CORE->BSS_ID_LOW.value = vif_next->bssid.array[0] | (vif_next->bssid.array[1] << 16); + MAC_CORE->BSS_ID_HI.value = vif_next->bssid.array[2]; + } + + if (vif_entry->type == VIF_AP) { + txl_cntrl_clear_bcn_ac(); + } + + mm_timer_clear(&(vif_entry->tbtt_timer)); + mm_timer_clear(&(vif_entry->tmr_bcn_to)); + + td_reset(vif_entry->index); + + vif_mgmt_entry_init(vif_entry); + + co_list_push_back(&vif_mgmt_env.free_list, &vif_entry->list_hdr); +} + +void vif_mgmt_add_key(const struct mm_key_add_req *param, uint8_t hw_key_idx) { + uint8_t inst_nbr = param->inst_nbr; + struct vif_info_tag *vif_entry = &vif_info_tab[inst_nbr]; + uint8_t key_idx = param->key_idx; + struct key_info_tag *key_info = &vif_info_tab[inst_nbr].key_info[key_idx]; + key_info->hw_key_idx = hw_key_idx; + key_info->cipher = param->cipher_suite; + key_info->key_idx = param->key_idx; + + memset(key->rx_pn, 0, sizeof(key->rx_pn)); + + switch (key_info->cipher) { + case MAC_RSNIE_CIPHER_TKIP: { + key_info->tx_pn = 0; + key_info->u.mic.tx_key[0] = param->key.array[4]; + key_info->u.mic.tx_key[1] = param->key.array[5]; + key_info->u.mic.rx_key[0] = param->key.array[6]; + key_info->u.mic.rx_key[1] = param->key.array[7]; + break; + } + case MAC_RSNIE_CIPHER_WEP40: + case MAC_RSNIE_CIPHER_WEP104: { + key_info->tx_pn = co_rand_word() & 0xFFFFFF; + break; + } + default: + key_info->tx_pn = 0; + } + key_info->valid = true; + vif_entry->default_key = vif_entry->key_info + key_idx; +} + +void vif_mgmt_del_key(struct vif_info_tag *vif, uint8_t keyid) { + vif->key_info[keyid].valid = false; + if (vif->default_key == vif->key_info + keyid) { + vif->default_key = NULL; + for (int i = 0 ; i < MAC_DEFAULT_KEY_COUNT; i++) { + if (vif->key_info[i].valid) { + vif->default_key = vif->key_info + i; + break; + } + } + } +} + +void vif_mgmt_send_postponed_frame(struct vif_info_tag *p_vif_entry) { + struct sta_info_tag *p_sta_entry = co_list_pick(&p_vif_entry->sta_list); + for (; p_sta_entry != NULL; p_sta_entry = co_list_next(&p_sta_entry->list_hdr)) { + sta_mgmt_send_postponed_frame(p_vif_entry,p_sta_entry, 0); + } +} + +#if (NX_CHNL_CTXT || NX_P2P) +void vif_mgmt_bcn_to_prog(struct vif_info_tag *p_vif_entry) { + mm_timer_set(&p_vif_entry->tmr_bcn_to, ke_time() + VIF_MGMT_BCN_TO_DUR); +} + +void vif_mgmt_bcn_recv(struct vif_info_tag *p_vif_entry) { + if (((ps_env.ps_on != false) && + ((ps_env.prevent_sleep & PS_VIF_WAITING_EOSP) == 0)) && + (p_vif_entry->prevent_sleep == 0) + ) { + mm_timer_clear(&p_vif_entry->tmr_bcn_to); + vif_mgmt_bcn_to_evt(p_vif_entry); + } +} +#endif + +void vif_mgmt_set_ap_bcn_int(struct vif_info_tag *p_vif_entry, uint16_t bcn_int) { + uint16_t new_bcn_int = bcn_int; + p_vif_entry->u.ap.bcn_int = bcn_int; + __disable_irq(); + if (vif_mgmt_env.vif_ap_cnt < 2) { + vif_mgmt_env.low_bcn_int_idx = p_vif_entry->index; + p_vif_entry->u.ap.bcn_tbtt_ratio = 1; + p_vif_entry->u.ap.bcn_tbtt_cnt = 1; + } else { + uint16_t lowest_bcn_int = vif_info_tab[vif_mgmt_env.low_bcn_int_idx].u.ap.bcn_int; + if (new_bcn_int < lowest_bcn_int) { + vif_mgmt_env.low_bcn_int_idx = p_vif_entry->index; + } else { + new_bcn_int = lowest_bcn_int; + } + struct vif_info_tag * p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry != NULL; p_vif_entry = co_list_next(&p_vif_entry->list_hdr)) { + p_vif_entry->u.ap.bcn_tbtt_cnt = 1; /// e5: 229 + uint8_t ratio = p_vif_entry->u.ap.bcn_int / new_bcn_intl; // e2: 226 + p_vif_entry->u.ap.bcn_tbtt_ratio = ratio /// e4: 228 + } + } + MAC_CORE->BCN_CNTRL_1.beaconInt = new_bcn_int; + __enable_irq(); +} + +void vif_mgmt_switch_channel(struct vif_info_tag *p_vif_entry) { + struct mm_csa_finish_ind *ind = KE_MSG_ALLOC(MM_CSA_FINISH_IND, TASK_API, TASK_MM, mm_csa_finish_ind); + chan_ctxt_unlink(p_vif_entry->index); + uint8_t chan_idx = 0xff; + struct mm_chan_ctxt_add_req* chan = &p_vif_entry->csa_channel; + struct mac_bss_info *bss_info = &p_vif_entry->bss_info; + uint16_t prim_freq = chan->prim20_freq; + uint16_t center1_freq = chan->center1_freq; + + bss_info->chan = me_freq_to_chan_ptr(chan->band, prim_freq);; + bss_info->center_freq1 = center1_freq; + bss_info->center_freq2 = chan->center2_freq; + + if (chan->type == PHY_CHNL_BW_80P80) { + bss_info->phy_bw = BW_160MHZ + } else { + bss_info->phy_bw = chan->type; + } + + if (bss_info->chan) { + chan->tx_power = bss_info->chan->tx_power; + int ret = chan_ctxt_add(&p_vif_entry->csa_channel, &chan_idx); + ind->status = ret; + ind->chan_idx = chan_idx; + switch (p_vif_entry->type) { + case VIF_STA: { + p_vif_entry->u.sta.csa_count = 0; + if (ret == CO_OK) { + chan_ctxt_link(p_vif_entry->index, chan_idx); + mm_timer_clear(&p_vif_entry->tmr_bcn_to); + mm_timer_set(&p_vif_entry->tbtt_timer,ke_time() + sta_info_tab[p_vif_entry->u.sta.ap_id].bcn_int); + p_vif_entry->u.sta.beacon_loss_cnt = 0; // 0x18 + p_vif_entry->u.sta.csa_occured = true; // 0x1e + } else { + mm_send_connection_loss_ind(p_vif_entry); + } + break; + } + case VIF_AP: { + // p_vif_entry->type == VIF_AP + p_vif_entry->u.ap.csa_count = 0; + if (ret == CO_OK) { + chan_ctxt_link(p_vif_entry->index, chan_idx); + mm_bcn_env.update_ongoing = true; + } + } + default: + break; + } + } else { + /// TODO: why use c.break? + ASSERT_ERR(bss_info->chan); + } + ke_msg_send(ind); +} + +struct vif_info_tag *vif_mgmt_get_first_ap_inf(void) { + if (vif_mgmt_env.vif_ap_cnt != '\0') { + struct vif_info_tag* p_vif_entry = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); + for (; p_vif_entry != NULL; p_vif_entry = co_list_next(&p_vif_entry->list_hdr)) { + if (p_vif_entry->type == VIF_AP) { + return p_vif_entry; + } + } + } + return NULL; +} diff --git a/src/bl602_wifi/modules/common/co_dlist.c b/src/bl602_wifi/modules/common/co_dlist.c new file mode 100644 index 0000000..f6ff047 --- /dev/null +++ b/src/bl602_wifi/modules/common/co_dlist.c @@ -0,0 +1,23 @@ +#include + +// functions here are not even used in bl602 + +void co_dlist_init(struct co_dlist *list) { + __builtin_trap(); +} + +void co_dlist_push_back(struct co_dlist *list, struct co_dlist_hdr *list_hdr) { + __builtin_trap(); +} + +void co_dlist_push_front(struct co_dlist *list, struct co_dlist_hdr *list_hdr) { + __builtin_trap(); +} + +struct co_dlist_hdr *co_dlist_pop_front(struct co_dlist *list) { + __builtin_trap(); +} + +void co_dlist_extract(struct co_dlist *list, const struct co_dlist_hdr *list_hdr) { + __builtin_trap(); +} diff --git a/src/bl602_wifi/modules/common/co_list.c b/src/bl602_wifi/modules/common/co_list.c new file mode 100644 index 0000000..7e38d96 --- /dev/null +++ b/src/bl602_wifi/modules/common/co_list.c @@ -0,0 +1,150 @@ +#include + +#include +#include +#include +#include +#include + +void co_list_init(struct co_list *list) { + list->first = list->last = NULL; +} + +void co_list_pool_init(struct co_list *list, void *pool, size_t elmt_size, uint32_t elmt_cnt, void *default_value) { + co_list_init(list); + for (uint32_t i = 0; i < elmt_cnt; i++) { + if (default_value) { + memcpy(pool, default_value, elmt_size); + } + co_list_push_back(list, (struct co_list_hdr*) pool); + pool = (void *)((uint8_t *)pool + (uint32_t)elmt_size); + } +} + +void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr) { + ASSERT_ERR(list_hdr != NULL); + if (!list->first) { + list->first = list_hdr; + } else { + list->last->next = list_hdr; + } + list->last = list_hdr; + list_hdr->next = NULL; +} + +void co_list_push_front(struct co_list *list, struct co_list_hdr *list_hdr) { + ASSERT_ERR(list_hdr != NULL); + if (!list->first) { + list->last = list_hdr; + } + list_hdr->next = list->first; + list->first = list_hdr; +} + +struct co_list_hdr *co_list_pop_front(struct co_list *list) { + struct co_list_hdr* elm = list->first; + if (elm) { + list->first = elm->next; + } + return elm; +} + +// I think the original impl of this function is buggy +// when the list->first == list->last == list_hdr +// it only set list->first = NULL and leaving list->last still list_hdr +void co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr) { + ASSERT_ERR(list != NULL); + struct co_list_hdr *cur = list->first; + if (!cur) + return; + if (cur == list_hdr) { + if (list->last == cur) list->last = NULL; // added this to remove the last + list->first = cur->next; + return ; + } + for (; cur && cur->next != list_hdr; cur = cur->next); + if (!cur) return ; // cannot find the element in list + cur->next = list_hdr->next; + if (list_hdr == list->last) + list->last = cur; +} + +bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr) { + if (!list_hdr) return true; // the original impl will return true when list_hdr == NULL + for (struct co_list_hdr * cur = list->first; cur; cur = cur->next) + if (cur == list_hdr) + return true; + return false; +} + +uint32_t co_list_cnt(const struct co_list* const list) { + uint32_t count = 0; + for (struct co_list_hdr * cur = list->first; cur; cur = cur->next) + count++; + return count; +} + +void co_list_insert(struct co_list* const list, struct co_list_hdr* const element, bool (*cmp)(const struct co_list_hdr*, const struct co_list_hdr*)) { + struct co_list_hdr *prev = NULL; + struct co_list_hdr *cur = list->first; + for (; cur && !cmp(element, cur); prev = cur, cur = cur->next); + if (!cur) + list->last = element; + element->next = cur; + if (prev) + prev->next = element; + else + list->first = element; +} + +void co_list_insert_after(struct co_list* const list, struct co_list_hdr* const prev_element, struct co_list_hdr* const element) { + if (!prev_element) { + co_list_push_front(list, element); + } else { + if (co_list_find(list, prev_element)) { + element->next = prev_element->next; + prev_element->next = element; + if (element->next == NULL) + list->last = element; + } + } +} + +void co_list_insert_before(struct co_list* const list, struct co_list_hdr* const next_element, struct co_list_hdr* const element) { + if (!next_element) { + co_list_push_back(list, element); + return ; + } + if (next_element == list->first) { + co_list_push_front(list, element); + return ; + } + struct co_list_hdr *cur = list->first; + for (; cur && cur->next != next_element; cur = cur->next); + if (! cur) return; + cur->next = element; + element->next = next_element; +} + +void co_list_concat(struct co_list *list1, struct co_list *list2) { + if (!(list2->first)) + return ; + if (!(list1->first)) + *list1 = *list2; + list1->last->next = list2->first; + list1->last = list2->last; + list2->first = list2->last = NULL; +} + +void co_list_remove(struct co_list *list, struct co_list_hdr *prev_element, struct co_list_hdr *element) { + ASSERT_ERR(list != NULL); + ASSERT_ERR((prev_element == NULL) || (prev_element->next == element)); + if (prev_element) { + prev_element->next = element->next; + } else { + list->first = element->next; + } + if (list->last == element) + list->last = prev_element; + element->next = NULL; +} diff --git a/src/bl602_wifi/modules/common/co_math.c b/src/bl602_wifi/modules/common/co_math.c new file mode 100644 index 0000000..bcbd5db --- /dev/null +++ b/src/bl602_wifi/modules/common/co_math.c @@ -0,0 +1,78 @@ +#include +#include + +static const uint32_t crc_tab[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +uint32_t co_crc32(uint32_t addr, uint32_t len, uint32_t crc) { + for (uint32_t i = 0; i != len; i = i + 1) { + crc = (crc << 8) ^ crc_tab[(crc >> 24) ^ co_read8p(addr + i)]; + } + return crc; +} + +long unsigned int next = 1; \ No newline at end of file diff --git a/src/bl602_wifi/modules/common/co_pool.c b/src/bl602_wifi/modules/common/co_pool.c new file mode 100644 index 0000000..2aae954 --- /dev/null +++ b/src/bl602_wifi/modules/common/co_pool.c @@ -0,0 +1,15 @@ +#include + +// functions here are also not used at all + +void co_pool_init(struct co_pool *pool, struct co_pool_hdr *pool_hdr, void *elements, uint32_t elem_size, uint32_t elem_cnt) { + __builtin_trap(); +} + +struct co_pool_hdr *co_pool_alloc(struct co_pool *pool, uint32_t nbelem) { + __builtin_trap(); +} + +void co_pool_free(struct co_pool *pool, struct co_pool_hdr *elements, uint32_t nbelem) { + __builtin_trap(); +} diff --git a/src/bl602_wifi/modules/common/co_ring.c b/src/bl602_wifi/modules/common/co_ring.c new file mode 100644 index 0000000..8b1a393 --- /dev/null +++ b/src/bl602_wifi/modules/common/co_ring.c @@ -0,0 +1 @@ +// empty diff --git a/src/bl602_wifi/modules/common/notifier.c b/src/bl602_wifi/modules/common/notifier.c new file mode 100644 index 0000000..18877c0 --- /dev/null +++ b/src/bl602_wifi/modules/common/notifier.c @@ -0,0 +1,57 @@ +#include + +#include +#include + +int notifier_chain_regsiter(struct notifier_block **list, struct notifier_block *n) { + vTaskEnterCritical(); + for (; *list && (n->priority <= (*list)->priority); list = &((*list)->next)); + n->next = *list; + *list = n; + vTaskExitCritical(); + return 0; +} + +int notifier_chain_regsiter_fromCritical(struct notifier_block **list, struct notifier_block *n) { + for (; *list && (n->priority <= (*list)->priority); list = &((*list)->next)); + n->next = *list; + *list = n; + return 0; +} + +int notifier_chain_unregsiter(struct notifier_block **list, struct notifier_block *n) { + vTaskEnterCritical(); + for (; *list && (*list != n); list = &((*list)->next)); + if (*list == n) { + *list = n->next; + } + vTaskExitCritical(); + return 0; +} + +int notifier_chain_unregsiter_fromCritical(struct notifier_block **list, struct notifier_block *n) { + for (; *list && (*list != n); list = &((*list)->next)); + if (*list == n) { + *list = n->next; + } + return 0; +} + +int notifier_chain_call(struct notifier_block **list, int event, void *env) { + + vTaskEnterCritical(); + struct notifier_block *cur = *list; // reversed code do this before enter critical + // this might be a problem + for (; cur; cur = cur->next) { + (*cur->cb)(cur, event, env); + } + vTaskExitCritical(); + return 0; +} + +int notifier_chain_call_fromeCritical(struct notifier_block **list, int event, void *env) { + for (struct notifier_block *cur = *list; cur; cur = cur->next) { + (*cur->cb)(cur, event, env); + } + return 0; +} diff --git a/src/bl602_wifi/modules/dbg/dbg.c b/src/bl602_wifi/modules/dbg/dbg.c new file mode 100644 index 0000000..2e77315 --- /dev/null +++ b/src/bl602_wifi/modules/dbg/dbg.c @@ -0,0 +1,10 @@ +#include +#include + +struct debug_env_tag dbg_env; + +void dbg_init(void) { + memset(&dbg_env, 0, sizeof(struct debug_env_tag)); + dbg_env.filter_module = 0xffffffff; + dbg_env.filter_severity = DBG_SEV_IDX_ERR; +} diff --git a/src/bl602_wifi/modules/dbg/dbg_print.c b/src/bl602_wifi/modules/dbg/dbg_print.c new file mode 100644 index 0000000..b9e05b2 --- /dev/null +++ b/src/bl602_wifi/modules/dbg/dbg_print.c @@ -0,0 +1,49 @@ +#include + +#include + +#include +#include + +void vprint(char *fmt, va_list argp); + +/* +static const uint8_t transition_table[8][8] = { + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x02, 0x03, 0x02, 0x06, 0x07, + 0x00, 0x00, 0x04, 0x02, 0x03, 0x02, 0x06, 0x07, + 0x00, 0x00, 0x04, 0x03, 0x03, 0x00, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const char hex_upper_table[17] = "0123456789ABCDEF"; +*/ + +void dbg_test_print(const char *fmt,...) { + if (dbg_env.filter_severity != DBG_SEV_IDX_NONE) { + for (int i = 0; i < 2; i++) { + uint8_t prefix = *fmt; + if (-1 < (int8_t)prefix) break; // maybe break? + prefix = prefix & 0x7f; // remove msb 1 + if (prefix < DBG_MOD_IDX_MAX) { + if (((dbg_env.filter_module >> (prefix)) & 1) == 0) return; + } else { + ASSERT_ERR(DBG_SEV_MIN <= prefix && prefix < DBG_SEV_MAX); + if (dbg_env.filter_severity <= prefix - DBG_SEV_MIN) return; + } + } + // we don't want to print anything anyway + // the compiled code omitted the real printing.. + // so that's all my guess.. + #ifdef PRINT_DBG + va_list args; + va_start(args, fmt); + vprint(fmt, args); + va_end(args); + #endif + } +} + diff --git a/src/bl602_wifi/modules/dbg/dbg_task.c b/src/bl602_wifi/modules/dbg/dbg_task.c new file mode 100644 index 0000000..bf44559 --- /dev/null +++ b/src/bl602_wifi/modules/dbg/dbg_task.c @@ -0,0 +1,72 @@ +#include +#include + +#include +#include + + +static int dbg_mem_read_req_handler(const ke_msg_id_t msgid, const struct dbg_mem_read_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct dbg_mem_read_cfm* msg = (struct dbg_mem_read_cfm*) ke_msg_alloc(DBG_MEM_READ_CFM, src_id, dest_id, 8); + msg->memaddr = param->memaddr; + msg->memaddr = *(uint32_t*)param->memaddr; + ke_msg_send(msg); + return KE_MSG_CONSUMED; +} + +static int dbg_mem_write_req_handler(const ke_msg_id_t msgid, const struct dbg_mem_write_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct dbg_mem_write_cfm* msg = (struct dbg_mem_write_cfm*) ke_msg_alloc(DBG_MEM_WRITE_CFM, src_id, dest_id, 8); + *(uint32_t *)param->memaddr = param->memdata; + msg->memaddr = param->memaddr; + msg->memaddr = *(uint32_t*)param->memaddr; + ke_msg_send(msg); + return KE_MSG_CONSUMED; +} + +static int dbg_set_mod_filter_req_handler(const ke_msg_id_t msgid, const struct dbg_set_mod_filter_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + dbg_env.filter_module = param->mod_filter; + ke_msg_send_basic(DBG_SET_MOD_FILTER_CFM, src_id, dest_id); + return KE_MSG_CONSUMED; +} + +static int dbg_set_sev_filter_req_handler(const ke_msg_id_t msgid, const struct dbg_set_sev_filter_req *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + dbg_env.filter_severity = param->sev_filter; + ke_msg_send_basic(DBG_SET_SEV_FILTER_CFM, src_id, dest_id); + return KE_MSG_CONSUMED; +} + +static int dbg_get_sys_stat_req_handler(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct dbg_get_sys_stat_cfm * msg = (struct dbg_get_sys_stat_cfm *)ke_msg_alloc(DBG_GET_SYS_STAT_CFM, src_id, dest_id, 0xc); + msg->cpu_sleep_time = 0; + msg->doze_time = 0; + msg->stats_time = 0; + ke_msg_send(msg); + return KE_MSG_CONSUMED; +} + +const struct ke_msg_handler dbg_default_state[5] = { + { + .id = DBG_MEM_READ_REQ, + .func = (ke_msg_func_t)dbg_mem_read_req_handler + }, + { + .id = DBG_MEM_WRITE_REQ, + .func = (ke_msg_func_t)dbg_mem_write_req_handler + }, + { + .id = DBG_SET_MOD_FILTER_REQ, + .func = (ke_msg_func_t)dbg_set_mod_filter_req_handler + }, + { + .id = DBG_SET_SEV_FILTER_REQ, + .func = (ke_msg_func_t)dbg_set_sev_filter_req_handler, + }, + { + .id = DBG_GET_SYS_STAT_REQ, + .func = (ke_msg_func_t)dbg_get_sys_stat_req_handler + } +}; + +const struct ke_state_handler dbg_default_handler = { + .msg_table = dbg_default_state, + .msg_cnt = 5 +}; diff --git a/src/bl602_wifi/modules/ke/ke_env.c b/src/bl602_wifi/modules/ke/ke_env.c new file mode 100644 index 0000000..711485b --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_env.c @@ -0,0 +1,4 @@ +#include + + +struct ke_env_tag ke_env; diff --git a/src/bl602_wifi/modules/ke/ke_event.c b/src/bl602_wifi/modules/ke/ke_event.c new file mode 100644 index 0000000..edf707d --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_event.c @@ -0,0 +1,109 @@ +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +typedef void (*evt_ptr_t)(int); + +struct ke_evt_tag { + evt_ptr_t func; // +0 + int param; // +4 +}; + +void bl_event_handle(int param) { + ke_evt_clear(KE_EVT_MAIN_BIT); + void bl_main_event_handle(void); // this is a wifidrv function + bl_main_event_handle(); +} + +void bl_fw_statistic_dump(int param); + +#define EVENT_DEF(name, F, P) [KE_EVT_##name] = {.func = F, .param = P}, +static const struct ke_evt_tag ke_evt_hdlr[32] = { + #include +}; +#undef EVENT_DEF + +void bl_fw_statistic_dump(int param) { + void bl_utils_dump(void); + void txl_frame_dump(void); + void ipc_emb_dump(void); + void txl_cntrl_env_dump(void); + void txl_cfm_dump(void); + void rxl_hwdesc_dump(void); + void rxl_cntrl_dump(void); + void hal_mib_dump(void); + ke_evt_clear(KE_EVT_EVM_VIA_MAC_TEST_BIT); + bl_utils_dump(); + txl_frame_dump(); + ipc_emb_dump(); + txl_cntrl_env_dump(); + txl_cfm_dump(); + rxl_hwdesc_dump(); + rxl_cntrl_dump(); + hal_mib_dump(); +} + +void ke_evt_set(const evt_field_t event) { + __disable_irq(); + ke_env.evt_field |= event; + __enable_irq(); +} + +void ke_evt_clear(const evt_field_t event) { + __disable_irq(); + ke_env.evt_field &= ~event; + __enable_irq(); +} + +void ke_evt_schedule(void) { + while (ke_env.evt_field) { + int event = __builtin_clz(ke_env.evt_field); + ASSERT_ERR((event < KE_EVT_MAX) && ke_evt_hdlr[event].func); + ke_evt_hdlr[event].func(ke_evt_hdlr[event].param); + } +} + +void ke_init(void) { + ke_env.mblock_first = ke_mem_init(); + ke_env.queue_saved.first = (struct co_list_hdr *)0x0; + ke_env.queue_saved.last = (struct co_list_hdr *)0x0; + ke_env.queue_sent.first = (struct co_list_hdr *)0x0; + ke_env.queue_sent.last = (struct co_list_hdr *)0x0; + ke_env.queue_timer.first = (struct co_list_hdr *)0x0; + ke_env.queue_timer.last = (struct co_list_hdr *)0x0; + ke_evt_clear(0xffffffff); +} + +void ke_flush(void) { + struct co_list_hdr *cur; + for (cur = co_list_pop_front(&ke_env.queue_sent); cur; cur = co_list_pop_front(&ke_env.queue_sent)) + ke_msg_free((struct ke_msg *)cur); + for (cur = co_list_pop_front(&ke_env.queue_saved); cur; cur = co_list_pop_front(&ke_env.queue_saved)) + ke_msg_free((struct ke_msg *)cur); + for (cur = co_list_pop_front(&ke_env.queue_timer); cur; cur = co_list_pop_front(&ke_env.queue_timer)) + ke_free((struct ke_msg *)cur); + ke_evt_clear(0xffffffff); +} + +void bl60x_fw_dump_statistic(int forced) { + if (forced != 0) { + bl_fw_statistic_dump(0); + return ; + } + ke_evt_set(KE_EVT_EVM_VIA_MAC_TEST_BIT); +} diff --git a/src/bl602_wifi/modules/ke/ke_mem.c b/src/bl602_wifi/modules/ke/ke_mem.c new file mode 100644 index 0000000..958d399 --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_mem.c @@ -0,0 +1,86 @@ +#include +#include +#include + +#include + +#include + +#include + +struct mblock_free { + struct mblock_free *next; // +0 + uint32_t size; // +4 +}; + +struct mblock_used { + uint32_t size; // +0 +}; + +uint8_t ke_mem_heap[5248]; + +struct mblock_free *ke_mem_init(void) { + // for some reason, ghidra cannot correctly recover this function + // this function creates a initial block with the sizeof ke_mem_heap + // and put the link list onto the ke_env.mblock_first + // but ghidra completely ignored that and think it's -4(ke_mem_heap) + // given they are close in the generated file + __disable_irq(); + struct mblock_free *initial_block = (struct mblock_free *)ke_mem_heap; + initial_block->next = NULL; + initial_block->size = sizeof(ke_mem_heap); + ke_env.mblock_first = initial_block; + __enable_irq(); + return initial_block; +} + +void *ke_malloc(uint32_t size) { + uint32_t totalsize = CO_ALIGN4_HI(size) + 4; + ASSERT_ERR(totalsize >= sizeof(struct mblock_free)); + struct mblock_free * found = NULL; + __disable_irq(); + for (struct mblock_free *blk = ke_env.mblock_first; blk; blk = blk->next) { + if (blk->size >= totalsize + sizeof(struct mblock_free)) { + if (!found) + found = blk; + else { + if (blk->size < found->size) + found = blk; + } + } + } + ASSERT_ERR(found != NULL); + uint32_t residue = found->size - totalsize; + found->size = residue; + struct mblock_used* used = (struct mblock_used*)(((uint8_t*)found) + residue); + used->size = totalsize; + __enable_irq(); + return (void*)(used + 1); +} + +void ke_free(void *mem_ptr) { + struct mblock_free *node = ke_env.mblock_first; + struct mblock_used *mblock = ((struct mblock_used *)mem_ptr) - 1; + struct mblock_free *free = (struct mblock_free *)mblock; + ASSERT_ERR((uint32_t)mem_ptr > (uint32_t)node); + __disable_irq(); + // find node X that free should be inserted after X. + for (; node->next; node = node->next) { + if ((uint32_t)node <= (uint32_t)free && (uint32_t)free <= (uint32_t)(node->next)) + break; + } + // step 1. insert free + uint32_t size = mblock->size; + free->size = size; + free->next = node->next; + node->next = free; + // step 2. merge nodes from node + int merge_cnt = 0; + while (node->next && (((uint32_t)node) + node->size == ((uint32_t)(node->next)))) { + struct mblock_free *next = node->next; + node->next = next->next; + node->size += next->size; + if (++merge_cnt == 2) break; + } + __enable_irq(); +} diff --git a/src/bl602_wifi/modules/ke/ke_msg.c b/src/bl602_wifi/modules/ke/ke_msg.c new file mode 100644 index 0000000..42c9268 --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_msg.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +void *ke_msg_alloc(const ke_msg_id_t id, const ke_task_id_t dest_id, const ke_task_id_t src_id, const uint16_t param_len) { + struct ke_msg* msg = (struct ke_msg*)ke_malloc(param_len + sizeof(struct ke_msg)); + ASSERT_ERR(msg != NULL); + msg->id = id; + msg->dest_id = dest_id; + msg->src_id = src_id; + msg->param_len = param_len; + msg->hdr.next = NULL; + memset(ke_msg2param(msg), 0, param_len); + return ke_msg2param(msg); +} + +void ke_msg_send(const void *param_ptr) { + struct ke_msg* msg = ke_param2msg(param_ptr); + ke_task_id_t id = KE_TYPE_GET(msg->dest_id); + if (ke_task_local(id)) { + co_list_push_back(&ke_env.queue_sent, &(msg->hdr)); + ke_evt_set(KE_EVT_KE_MESSAGE_BIT); + } else { + void bl_rx_e2a_handler(void *arg); // this is wifidrv function + bl_rx_e2a_handler(&(msg->id)); + ke_free(msg); + } +} + +void ke_msg_send_basic(const ke_msg_id_t id, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + ke_msg_send(ke_msg_alloc(id, dest_id, src_id, 0)); +} + +void ke_msg_forward(const void *param_ptr, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct ke_msg* msg = ke_param2msg(param_ptr); + msg->dest_id = dest_id; + msg->src_id = src_id; + ke_msg_send(param_ptr); +} + +void ke_msg_forward_and_change_id(const void *param_ptr, const ke_msg_id_t msg_id, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + struct ke_msg* msg = ke_param2msg(param_ptr); + msg->id = msg_id; + msg->dest_id = dest_id; + msg->src_id = src_id; + ke_msg_send(param_ptr); +} + +void ke_msg_free(const struct ke_msg *msg) { + if (msg) + ke_free((void*)msg); +} diff --git a/src/bl602_wifi/modules/ke/ke_queue.c b/src/bl602_wifi/modules/ke/ke_queue.c new file mode 100644 index 0000000..f6d74e0 --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_queue.c @@ -0,0 +1,22 @@ +#include + +#include + +struct co_list_hdr *ke_queue_extract(struct co_list* const queue, bool (*func)(const struct co_list_hdr*, uint32_t), uint32_t arg) { + struct co_list_hdr *prev = NULL; + struct co_list_hdr *cur = queue->first; + for (; cur && !func(cur, arg); prev = cur, cur = cur->next); + if (!cur) + return NULL; // cannot find the target + if (prev) { + prev->next = cur->next; + } else { + queue->first = cur->next; + } + if (cur->next) { + cur->next = NULL; + } else { + queue->last = prev; + } + return cur; +} diff --git a/src/bl602_wifi/modules/ke/ke_task.c b/src/bl602_wifi/modules/ke/ke_task.c new file mode 100644 index 0000000..211dbd3 --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_task.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +static const struct ke_task_desc TASK_DESC[TASK_MAX] = { + /// MAC Management task. + [TASK_MM] = { + .state_handler = mm_state_handler, + .default_handler = &mm_default_handler, + .state = mm_state, + .state_max = MM_STATE_MAX, + .idx_max = MM_IDX_MAX, + }, + [TASK_DBG] = { + .state_handler = NULL, + .default_handler = &dbg_default_handler, + .state = NULL, + .state_max = 1, + .idx_max = 1, + }, + /// SCAN task + [TASK_SCAN] = { + .state_handler = NULL, + .default_handler = &scan_default_handler, + .state = scan_state, + .state_max = SCAN_STATE_MAX, + .idx_max = SCAN_ID_MAX, + }, + /// TDLS task + [TASK_TDLS] = {0}, + /// SCAN task + [TASK_SCANU] = { + .state_handler = scanu_state_handler, + .default_handler = &scanu_default_handler, + .state = scanu_state, + .state_max = SCANU_STATE_MAX, + .idx_max = SCANU_IDX_MAX, + }, + /// SCAN task + [TASK_ME] = { + .state_handler = NULL, + .default_handler = &me_default_handler, + .state = me_state, + .state_max = ME_STATE_MAX, + .idx_max = ME_IDX_MAX, + }, + /// SM task + [TASK_SM] = { + .state_handler = NULL, + .default_handler = &sm_default_handler, + .state = sm_state, + .state_max = SM_STATE_MAX, + .idx_max = SM_IDX_MAX, + }, + /// APM task + [TASK_APM] = { + .state_handler = NULL, + .default_handler = &apm_default_handler, + .state = apm_state, + .state_max = APM_STATE_MAX, + .idx_max = APM_IDX_MAX, + }, + /// BAM task + [TASK_BAM] = { + .state_handler = NULL, + .default_handler = &bam_default_handler, + .state = bam_state, + .state_max = BAM_STATE_MAX, + .idx_max = BAM_IDX_MAX, + }, + /// MESH task + [TASK_MESH] = {0}, + [TASK_HOSTAPD] = { + .state_handler = NULL, + .default_handler = &hostapd_default_handler, + .state = hostapd_u_state, + .state_max = HOSTAPD_STATE_MAX, + .idx_max = HOSTAPD_IDX_MAX, + }, + /// RXU task + [TASK_RXU] = {0}, + /// CFG task + [TASK_CFG] = { + .state_handler = NULL, + .default_handler = &cfg_default_handler, + .state = cfg_state, + .state_max = CFG_STATE_MAX, + .idx_max = CFG_IDX_MAX, + }, + // nX API task + [TASK_API] = {0}, +}; + + +static bool cmp_dest_id(const struct co_list_hdr *msg, uint32_t dest_id) { + return ((struct ke_msg*)msg)->dest_id == dest_id; +} + +static void ke_task_saved_update(const ke_task_id_t ke_task_id) { + while (true) { + struct ke_msg* msg = (struct ke_msg*) ke_queue_extract(&ke_env.queue_saved, &cmp_dest_id, (uint32_t) ke_task_id); + if (msg) { + __disable_irq(); + ke_queue_push(&ke_env.queue_sent, (struct co_list_hdr*)msg); + __enable_irq(); + ke_evt_set(KE_EVT_KE_MESSAGE_BIT); + } else return ; + } +} + +void ke_state_set(const ke_task_id_t id, const ke_state_t state_id) { + int type = KE_TYPE_GET(id); + int idx = KE_IDX_GET(id); + ASSERT_ERR(type < TASK_MAX); + ASSERT_ERR(ke_task_local(type)); + ASSERT_ERR(idx < TASK_DESC[type].idx_max); + ke_state_t *ke_stateid_ptr = TASK_DESC[type].state + idx; + ASSERT_ERR(ke_stateid_ptr); + if (*ke_stateid_ptr != state_id) { + *ke_stateid_ptr = state_id; + ke_task_saved_update(id); + } +} + +ke_state_t ke_state_get(const ke_task_id_t id) { + int type = KE_TYPE_GET(id); + int idx = KE_IDX_GET(id); + ASSERT_ERR(type < TASK_MAX); + ASSERT_ERR(ke_task_local(type)); + ASSERT_ERR(idx < TASK_DESC[type].idx_max); + return TASK_DESC[idx].state[type]; +} + +static ke_msg_func_t ke_handler_search(const ke_msg_id_t msg_id, const struct ke_state_handler *state_handler) { + if (state_handler->msg_cnt == 0) + return NULL; + for (int i = ((int)state_handler->msg_cnt) - 1; i >= 0; i--) { + if (state_handler->msg_table[i].id == msg_id) { + ASSERT_ERR(state_handler->msg_table[i].func); + return state_handler->msg_table[i].func; + } + } + return NULL; +} + +static ke_msg_func_t ke_task_handler_get(const ke_msg_id_t msg_id, const ke_task_id_t task_id) { + int type = KE_TYPE_GET(task_id); + int idx = KE_IDX_GET(task_id); + + ASSERT_ERR(type < TASK_MAX); + ASSERT_ERR(ke_task_local(type)); + ASSERT_ERR(idx < TASK_DESC[type].idx_max); + + const struct ke_task_desc *desc = TASK_DESC + type; + ASSERT_ERR(desc); + + const struct ke_state_handler * handler = desc->state_handler ? (desc->state_handler + desc->state[idx]) + : (desc->default_handler); + return ke_handler_search(msg_id, handler);; +} + +void ke_task_schedule(int dummy) { + do { + __disable_irq(); + struct ke_msg * msg = (struct ke_msg *) ke_queue_pop(&ke_env.queue_sent); + __enable_irq(); + if (!msg) + break; + ke_msg_func_t func = ke_task_handler_get(msg->id, msg->dest_id); + enum ke_msg_status_tag status = KE_MSG_CONSUMED; + if (func) { + status = (enum ke_msg_status_tag) func(msg->id, ke_msg2param(msg), msg->dest_id, msg->src_id); + } + switch (status) { + case KE_MSG_CONSUMED: + ke_msg_free(msg); + case KE_MSG_NO_FREE: + break; + case KE_MSG_SAVED: + ke_queue_push(&ke_env.queue_saved, (struct co_list_hdr*) msg); + break; + default: + ASSERT_ERR(0); + } + + } while (0); + + __disable_irq(); + if (ke_env.queue_sent.first == 0x0) { + ke_evt_clear(KE_EVT_KE_MESSAGE_BIT); + } + __enable_irq(); +} + +int ke_msg_discard(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + return KE_MSG_CONSUMED; +} + +int ke_msg_save(const ke_msg_id_t msgid, const void *param, const ke_task_id_t dest_id, const ke_task_id_t src_id) { + return KE_MSG_SAVED; +} diff --git a/src/bl602_wifi/modules/ke/ke_timer.c b/src/bl602_wifi/modules/ke/ke_timer.c new file mode 100644 index 0000000..d6681b3 --- /dev/null +++ b/src/bl602_wifi/modules/ke/ke_timer.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +static void ke_timer_hw_set(struct ke_timer *timer) { + __disable_irq(); + if (!timer) { + MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers8 = 0; + } else { + STATIC_ASSERT(&(MAC_CORE->ABS_TIMER[8]) == (void*)0x44b00148, abs_timer_address); + MAC_CORE->ABS_TIMER[8] = timer->time; + if (MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers8) { + __enable_irq(); + return ; + } + MAC_PL->TIMERS_INT_EVENT_CLEAR.value = 0x100; + MAC_PL->TIMERS_INT_UN_MASK.maskabsTimers8 = 1; + } + __enable_irq(); +} + +static bool cmp_abs_time(const struct co_list_hdr *timerA, const struct co_list_hdr *timerB) { + uint32_t timeA = ((const struct ke_timer *)timerA)->time; + uint32_t timeB = ((const struct ke_timer *)timerB)->time; + return (((uint32_t)(timeA - timeB)) > KE_TIMER_DELAY_MAX); +} + +static bool cmp_timer_id(const struct co_list_hdr *timer, uint32_t timer_task) { + if (((const struct ke_timer*)timer)->id == timer_task >> 0x10) { + return (((const struct ke_timer*)timer)->task == (timer_task & 0xffff)); + } + return false; +} + +void ke_timer_set(const ke_msg_id_t timer_id, const ke_task_id_t task_id, const uint32_t delay) { + ASSERT_ERR(delay > 0); + ASSERT_ERR(delay < KE_TIMER_DELAY_MAX); + struct ke_timer *first = (struct ke_timer *)ke_env.queue_timer.first; + bool isFirst = false; + if (first && first->id == timer_id && first->task == task_id) + isFirst = true; + struct ke_timer *timer = (struct ke_timer *)ke_queue_extract(&ke_env.queue_timer, cmp_timer_id, ((uint32_t)timer_id << 0x10) | task_id); + if (!timer) { + timer = (struct ke_timer *)ke_malloc(sizeof(struct ke_timer)); + ASSERT_ERR(timer); + timer->id = timer_id; + timer->task = task_id; + } + int32_t trigger_time = ke_time() + delay; + timer->time = trigger_time; + + co_list_insert(&ke_env.queue_timer, (struct co_list_hdr *)timer, cmp_abs_time); + if (isFirst || (struct ke_timer*)ke_env.queue_timer.first == timer) { + ke_timer_hw_set((struct ke_timer *)ke_env.queue_timer.first); + } + if (ke_time_past(trigger_time)) { + ke_evt_set(KE_EVT_KE_TIMER_BIT); + } +} + +void ke_timer_clear(const ke_msg_id_t timer_id, const ke_task_id_t task_id) { + struct ke_timer *timer = (struct ke_timer *) ke_env.queue_timer.first; + if (timer) { + if (timer->id == timer_id && timer->task == task_id) { + ke_queue_pop(&ke_env.queue_timer); + struct ke_timer *first = (struct ke_timer *) ke_env.queue_timer.first; + ke_timer_hw_set(first); + // shouldn't this be a ke_evt_set? + ASSERT_ERR(!first || !ke_time_past(first->time)); + } else { + timer = (struct ke_timer *)ke_queue_extract(&ke_env.queue_timer, cmp_timer_id, ((uint32_t)timer_id << 16) | task_id); + } + if (timer) + ke_free(timer); + } +} + +void ke_timer_schedule(int dummy) { + while (true) { + ke_evt_clear(KE_EVT_KE_TIMER_BIT); + struct ke_timer* timer = (struct ke_timer*)ke_env.queue_timer.first; + if (!timer) { + ke_timer_hw_set(NULL); + return ; + } + // the first timer not about to time out? + if (!ke_time_past(timer->time - 50)) { + // make it the next timer + ke_timer_hw_set(timer); + // still not timeout? leave + if (!ke_time_past(timer->time)) + break; + } + // timer has time out + timer = (struct ke_timer*) ke_queue_pop(&ke_env.queue_timer); + ke_msg_send_basic(timer->id, timer->task, TASK_NONE); + ke_free(timer); + } +} + +bool ke_timer_active(const ke_msg_id_t timer_id, const ke_task_id_t task_id) { + for (struct ke_timer* timer = (struct ke_timer*)ke_env.queue_timer.first; timer; timer = timer->next) { + if (timer->id == timer_id && timer->task == task_id) + return true; + } + return false; +} diff --git a/src/bl602_wifi/modules/mac/mac.c b/src/bl602_wifi/modules/mac/mac.c new file mode 100644 index 0000000..41fe560 --- /dev/null +++ b/src/bl602_wifi/modules/mac/mac.c @@ -0,0 +1,61 @@ +#include + +#include + + +const uint8_t mac_tid2ac[] = { + AC_BE, // TID0 + AC_BK, // TID1 + AC_BK, // TID2 + AC_BE, // TID3 + AC_VI, // TID4 + AC_VI, // TID5 + AC_VO, // TID6 + AC_VO, // TID7 + AC_VO, // TIDMGT + 0,0,0 +}; // :31:15 + +const uint8_t mac_ac2uapsd[4] = { + MAC_QOS_INFO_STA_UAPSD_ENABLED_BK, + MAC_QOS_INFO_STA_UAPSD_ENABLED_BE, + MAC_QOS_INFO_STA_UAPSD_ENABLED_VI, + MAC_QOS_INFO_STA_UAPSD_ENABLED_VO, +}; // :44:15 + +const uint8_t mac_id2rate[] = { + /* + MAC_RATE_1MBPS, + MAC_RATE_2MBPS, + MAC_RATE_5_5MBPS, + MAC_RATE_11MBPS, + MAC_RATE_6MBPS, + MAC_RATE_9MBPS, + MAC_RATE_12MBPS, + MAC_RATE_18MBPS, + MAC_RATE_24MBPS, + MAC_RATE_36MBPS, + MAC_RATE_48MBPS, + MAC_RATE_54MBPS + */ + // for unknown reason, the vals here are 0x82 instead of 0x2 + 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18,0x24, 0x30, 0x48, 0x60, 0x6c +}; // :53:15 + +const struct mac_addr mac_addr_bcst = { + .array = {0xFFFF, 0xFFFF, 0xFFFF} +}; // :92:23 + +uint32_t mac_paid_gid_sta_compute(const struct mac_addr *p_mac_addr) { + const mac_addr_unpack* unpack = (const mac_addr_unpack*)p_mac_addr; + return (((uint32_t)unpack->array[5] << 1) | ((uint32_t)unpack->array[4] & 0x80)) << 0x16; +} // :99:10 + +uint32_t mac_paid_gid_ap_compute(const struct mac_addr *p_mac_addr, uint16_t aid){ + const mac_addr_unpack* unpack = (const mac_addr_unpack*)p_mac_addr; + return ((uint32_t)aid + (((int32_t)((uint32_t)unpack->array[5] >> 4) ^ (uint32_t)unpack->array[5]) & 0xf) * 0x20) * 0x400000 & 0x7fc00000 | 0x3f0000; +} // :110:10 + +void bl60x_current_time_us(long long *time_now){ + *time_now = ((MAC_PL->TSF_LO.tsfTimerLow) | (long long)MAC_PL->TSF_HI.tsfTimerHigh); +} // :123:6 diff --git a/src/bl602_wifi/modules/mac/mac_ie.c b/src/bl602_wifi/modules/mac/mac_ie.c new file mode 100644 index 0000000..82fbbf6 --- /dev/null +++ b/src/bl602_wifi/modules/mac/mac_ie.c @@ -0,0 +1,30 @@ +#include +#include + +#include + +uint32_t mac_ie_find(uint32_t addr, uint16_t buflen, uint8_t ie_id) { + int offset = 0; + while (offset < buflen) { + struct mgmt_ie* data = (struct mgmt_ie*) addr; + if (data->element_id == ie_id) { + return addr; + } + addr = addr + sizeof(struct mgmt_ie) + data->payload_length; + } + return 0; +} + +uint32_t mac_vsie_find(uint32_t addr, uint16_t buflen, const uint8_t *oui, uint8_t ouilen) { + int offset = 0; + while (offset < buflen) { + struct mgmt_ie* data = (struct mgmt_ie*) addr; + if (data->element_id == MAC_ELTID_OUI) { + if (co_cmp8p((uint32_t)&(data->payload), oui, ouilen)) { + return addr; + } + } + addr = addr + sizeof(struct mgmt_ie) + data->payload_length; + } + return 0; +} diff --git a/src/bl602_wifi/test.ipynb b/src/bl602_wifi/test.ipynb new file mode 100644 index 0000000..4bc904d --- /dev/null +++ b/src/bl602_wifi/test.ipynb @@ -0,0 +1,398 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "lst = [ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00 ]\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "import ctypes" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "aint = []\n", + "for i in range(0, len(lst), 4):\n", + " aint.append(lst[i] + (lst[i+1] << 8) + (lst[i+2] << 16) + (lst[i+3] << 24))" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "16.0\n" + ] + } + ], + "source": [ + "print(len(aint) / 7)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "pint = [ -0x100000000 + i if i & 0x80000000 else i for i in aint]\n", + "arr = np.array(pint)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 2, 14, 256],\n", + " [ 0, 2, 5, 256],\n", + " [ 0, 2, 1, 256],\n", + " [ 0, 4, 2, 272],\n", + " [ 0, 4, 0, 224],\n", + " [ 0, 4, 0, 272],\n", + " [ 0, 4, 0, 288],\n", + " [ 0, 4, 0, 304]])" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "arr.reshape(8, 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([-16, -13, -10, -8, -5, -2, 0, 2, 5, 7, 9, 11, 14,\n", + " 18])" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "arr" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [], + "source": [ + " channel_div_table = [0 for i in range(0, 21)]\n", + " channel_cnt_table = [0 for i in range(0, 21)]\n", + " channel_cnt_range = [0 for i in range(0,3)]\n", + " rx_notch_para = [[0,0] for i in range(0, 14)]" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [], + "source": [ + "def get_array(freq):\n", + " global channel_div_table, channel_cnt_table, channel_cnt_range, rx_notch_para, fcal_div\n", + " channel_div_table = [hex(i) for i in channel_div_table]\n", + " channel_cnt_table = [hex(i) for i in channel_cnt_table]\n", + " channel_cnt_range = [hex(i) for i in channel_cnt_range]\n", + " rx_notch_para1 = [\"{\" + f\"{str(i[0])}, {str(i[1])}\" + \"}\" for i in rx_notch_para]\n", + " print(f\"static uint32_t channel_div_table_{freq}[21] = \"+ \"{\")\n", + " print(\" \" + \", \".join(channel_div_table))\n", + " print(\"};\")\n", + " \n", + " print(f\"static uint16_t channel_cnt_table_{freq}[21] = \" + \"{\")\n", + " print(\" \" + \", \".join(channel_cnt_table))\n", + " print(\"};\")\n", + "\n", + " print(f\"static uint16_t channel_cnt_range_{freq}[21] = \" + \"{\")\n", + " print(\" \" + \", \".join(channel_cnt_range))\n", + " print(\"};\")\n", + " \n", + " print(f\"static int32_t rx_notch_para_{freq}[14][2] = \"+ \"{\")\n", + " print(\" \" + \", \".join(rx_notch_para1))\n", + " print(\"};\")\n", + "\n", + " print(f\"static uint16_t fcal_div_{freq} = {fcal_div};\")" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + " channel_div_table[0] = 0xF690690;\n", + " channel_div_table[1] = 0xF6F96F9;\n", + " channel_div_table[2] = 0xF762762;\n", + " channel_div_table[3] = 0xF7CB7CB;\n", + " channel_div_table[4] = 0xF834835;\n", + " channel_div_table[5] = 0xF89D89E;\n", + " channel_div_table[6] = 0xF906907;\n", + " channel_div_table[7] = 0xF96F970;\n", + " channel_div_table[8] = 0xF9D89D9;\n", + " channel_div_table[9] = 0xFA41A42;\n", + " channel_div_table[10] = 0xFAAAAAB;\n", + " channel_div_table[11] = 0xFB13B14;\n", + " channel_div_table[12] = 0xFB7CB7D;\n", + " channel_div_table[13] = 0xFBE5BE6;\n", + " channel_div_table[14] = 0xFC4EC4F;\n", + " channel_div_table[15] = 0xFCB7CB8;\n", + " channel_div_table[16] = 0xFD20D21;\n", + " channel_div_table[17] = 0xFD89D8A;\n", + " channel_div_table[18] = 0xFDF2DF3;\n", + " channel_div_table[19] = 0xFE5BE5C;\n", + " channel_div_table[20] = 0xFEC4EC5;\n", + " \n", + " channel_cnt_table[0] = 0xA6ED;\n", + " channel_cnt_table[1] = 0xA734;\n", + " channel_cnt_table[2] = 0xA77B;\n", + " channel_cnt_table[3] = 0xA7C2;\n", + " channel_cnt_table[4] = 0xA809;\n", + " channel_cnt_table[5] = 0xA850;\n", + " channel_cnt_table[6] = 0xA897;\n", + " channel_cnt_table[7] = 0xA8DE;\n", + " channel_cnt_table[8] = 0xA925;\n", + " channel_cnt_table[9] = 0xA96D;\n", + " channel_cnt_table[10] = 0xA9B4;\n", + " channel_cnt_table[11] = 0xA9FB;\n", + " channel_cnt_table[12] = 0xAA42;\n", + " channel_cnt_table[13] = 0xAA89;\n", + " channel_cnt_table[14] = 0xAAD0;\n", + " channel_cnt_table[15] = 0xAB17;\n", + " channel_cnt_table[16] = 0xAB5E;\n", + " channel_cnt_table[17] = 0xABA5;\n", + " channel_cnt_table[18] = 0xABEC;\n", + " channel_cnt_table[19] = 0xAC34;\n", + " channel_cnt_table[20] = 0xAC7B;\n", + " \n", + " channel_cnt_range[0] = 0xA6A2;\n", + " channel_cnt_range[1] = 0xA6E2;\n", + " channel_cnt_range[2] = 0xACE2; \n", + " \n", + " fcal_div = 0xad5; \n", + " \n", + " rx_notch_para[0][0] = 0; \n", + " rx_notch_para[1][0] = 0;\n", + " rx_notch_para[2][0] = 0;\n", + " rx_notch_para[3][0] = 0;\n", + " rx_notch_para[4][0] = 0;\n", + " rx_notch_para[5][0] = 1;\n", + " rx_notch_para[6][0] = 1; \n", + " rx_notch_para[7][0] = 1; \n", + " rx_notch_para[8][0] = 1;\n", + " rx_notch_para[9][0] = 0;\n", + " rx_notch_para[10][0] = 0;\n", + " rx_notch_para[11][0] = 0;\n", + " rx_notch_para[12][0] = 0;\n", + " rx_notch_para[13][0] = 0; \n", + " rx_notch_para[0][1] = 0 *1000*1000; \n", + " rx_notch_para[1][1] = 0 *1000*1000;\n", + " rx_notch_para[2][1] = 0 *1000*1000;\n", + " rx_notch_para[3][1] = 0 *1000*1000;\n", + " rx_notch_para[4][1] = 0 *1000*1000;\n", + " rx_notch_para[5][1] = 7 *1000*1000;\n", + " rx_notch_para[6][1] = 2 *1000*1000; \n", + " rx_notch_para[7][1] = -3 *1000*1000; \n", + " rx_notch_para[8][1] = -8 *1000*1000;\n", + " rx_notch_para[9][1] = 0 *1000*1000;\n", + " rx_notch_para[10][1] = 0 *1000*1000;\n", + " rx_notch_para[11][1] = 0 *1000*1000;\n", + " rx_notch_para[12][1] = 0 *1000*1000;\n", + " rx_notch_para[13][1] = 0 *1000*1000; " + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "static uint32_t channel_div_table_52M[21] = {\n", + " 0xf690690, 0xf6f96f9, 0xf762762, 0xf7cb7cb, 0xf834835, 0xf89d89e, 0xf906907, 0xf96f970, 0xf9d89d9, 0xfa41a42, 0xfaaaaab, 0xfb13b14, 0xfb7cb7d, 0xfbe5be6, 0xfc4ec4f, 0xfcb7cb8, 0xfd20d21, 0xfd89d8a, 0xfdf2df3, 0xfe5be5c, 0xfec4ec5\n", + "};\n", + "static uint16_t channel_cnt_table_52M[21] = {\n", + " 0xa6ed, 0xa734, 0xa77b, 0xa7c2, 0xa809, 0xa850, 0xa897, 0xa8de, 0xa925, 0xa96d, 0xa9b4, 0xa9fb, 0xaa42, 0xaa89, 0xaad0, 0xab17, 0xab5e, 0xaba5, 0xabec, 0xac34, 0xac7b\n", + "};\n", + "static uint16_t channel_cnt_range_52M[21] = {\n", + " 0xa6a2, 0xa6e2, 0xace2\n", + "};\n", + "static int32_t rx_notch_para_52M[14][2] = {\n", + " {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {1, 7000000}, {1, 2000000}, {1, -3000000}, {1, -8000000}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}\n", + "};\n", + "static uint16_t fcal_div_52M = 2773;\n" + ] + } + ], + "source": [ + "get_array(\"52M\")" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + " s = \"\"\"00000000 01000000 07000000 1b000000 \n", + " 20000000 fcffffff e6000000 00000000 \n", + " 01000000 07000000 1b000000 20000000 \n", + " f8ffffff dc000000 00000000 01000000 \n", + " 07000000 14000000 20000000 fcffffff \n", + " d2000000 00000000 01000000 07000000 \n", + " 14000000 20000000 f8ffffff c8000000 \n", + " 00000000 01000000 07000000 0f000000 \n", + " 20000000 fcffffff be000000 00000000 \n", + " 01000000 07000000 0f000000 20000000 \n", + " f8ffffff b4000000 00000000 01000000 \n", + " 07000000 0b000000 20000000 fcffffff \n", + " aa000000 00000000 01000000 07000000 \n", + " 0b000000 20000000 f8ffffff a0000000 \n", + " 00000000 01000000 06000000 0a000000 \n", + " 20000000 fcffffff 96000000 00000000 \n", + " 01000000 06000000 0a000000 20000000 \n", + " f8ffffff 8c000000 00000000 01000000 \n", + " 06000000 08000000 20000000 fbffffff \n", + " 82000000 00000000 01000000 06000000 \n", + " 08000000 20000000 f7ffffff 78000000 \n", + " 00000000 01000000 05000000 07000000 \n", + " 20000000 fcffffff 6e000000 00000000 \n", + " 01000000 05000000 07000000 20000000 \n", + " f8ffffff 64000000 00000000 01000000 \n", + " 04000000 07000000 20000000 fbffffff \n", + " 5a000000 00000000 01000000 04000000 \n", + " 07000000 20000000 f7ffffff 50000000\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "ints = s.replace(\"\\n\", \"\").replace(\" \", \" \").split(\" \")" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "data = [int.from_bytes(bytearray.fromhex(i), byteorder='little') for i in ints]\n", + "data = [ -0x100000000 + i if i & 0x80000000 else i for i in data]" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 1, 7, 27, 32, -4, 230],\n", + " [ 0, 1, 7, 27, 32, -8, 220],\n", + " [ 0, 1, 7, 20, 32, -4, 210],\n", + " [ 0, 1, 7, 20, 32, -8, 200],\n", + " [ 0, 1, 7, 15, 32, -4, 190],\n", + " [ 0, 1, 7, 15, 32, -8, 180],\n", + " [ 0, 1, 7, 11, 32, -4, 170],\n", + " [ 0, 1, 7, 11, 32, -8, 160],\n", + " [ 0, 1, 6, 10, 32, -4, 150],\n", + " [ 0, 1, 6, 10, 32, -8, 140],\n", + " [ 0, 1, 6, 8, 32, -5, 130],\n", + " [ 0, 1, 6, 8, 32, -9, 120],\n", + " [ 0, 1, 5, 7, 32, -4, 110],\n", + " [ 0, 1, 5, 7, 32, -8, 100],\n", + " [ 0, 1, 4, 7, 32, -5, 90],\n", + " [ 0, 1, 4, 7, 32, -9, 80]])" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "na = np.array(data)\n", + "na.reshape(16,7)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "767d51c1340bd893661ea55ea3124f6de3c7a262a8b4abca0554b478b1e2ff90" + }, + "kernelspec": { + "display_name": "Python 2.7.17 64-bit", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "2.7.17" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/src/include/assert.h b/src/include/assert.h new file mode 100644 index 0000000..8b7ab5b --- /dev/null +++ b/src/include/assert.h @@ -0,0 +1,11 @@ +#ifndef _ASSERT_H_ +#define _ASSERT_H_ + +#include + +#define ASSERT_ERR(cond) if (!(cond)) assert_err(#cond, __FILE__, __LINE__); +#define ASSERT_WARN(cond) if (!(cond)) assert_warn(#cond, __FILE__, __LINE__); + +#define ASSERT_REC_VAL(cond, ret) if (!(cond)) { assert_rec(#cond, __FILE__, __LINE__); return (ret); } +#define ASSERT_REC(cond) if (!(cond)) { assert_rec(#cond, __FILE__, __LINE__); } +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/arch/arch.h b/src/include/bl602_wifi/arch/arch.h new file mode 100644 index 0000000..78b27ff --- /dev/null +++ b/src/include/bl602_wifi/arch/arch.h @@ -0,0 +1,14 @@ +#ifndef _ARCH_H_ +#define _ARCH_H_ + +void assert_rec(const char *condition, const char *file, int line); // :66:6 +void assert_err(const char *condition, const char *file, int line); // :132:6 +void assert_warn(const char *condition, const char *file, int line); // :163:6 +void force_trigger(const char *msg); // :178:6 +void wifi_main(void *param); // :355:6 +void coex_dump_pta(void); // :527:6 +void coex_dump_wifi(void); // :640:6 +void coex_wifi_rf_forece_enable(int enable); // :650:6 +void coex_wifi_pti_forece_enable(int enable); // :659:6 + +#endif // _ARCH_H_ diff --git a/src/include/bl602_wifi/arch/rv32i/ll.h b/src/include/bl602_wifi/arch/rv32i/ll.h new file mode 100644 index 0000000..051fef4 --- /dev/null +++ b/src/include/bl602_wifi/arch/rv32i/ll.h @@ -0,0 +1,12 @@ +#ifndef _LL_H_ +#define _LL_H_ + +__attribute__((always_inline)) static void __disable_irq(void) { + __asm("csrrci zero, mstatus, 0x8"); +} + +__attribute__((always_inline)) static void __enable_irq(void) { + __asm("csrrsi zero, mstatus, 0x8"); +} + +#endif // _LL_H_ diff --git a/src/include/bl602_wifi/cfg/cfg_api.h b/src/include/bl602_wifi/cfg/cfg_api.h new file mode 100644 index 0000000..f8f6db8 --- /dev/null +++ b/src/include/bl602_wifi/cfg/cfg_api.h @@ -0,0 +1,27 @@ +#ifndef _CFG_API_H_ +#define _CFG_API_H_ + +#include + +#include + + +struct cfg_element_entry { + uint32_t task; // +0 + uint16_t element; // +4 + uint16_t type; // +6 + char *name; // +8 + void *val; // +12 + int (*set)(struct cfg_element_entry *, void *, void *); // +16 + int (*get)(struct cfg_element_entry *, void *, void *); // +20 + int (*notify)(struct cfg_element_entry *, void *, void *, enum CFG_ELEMENT_TYPE_OPS); // +24 +}; + +extern struct cfg_element_entry _ld_bl_static_cfg_entry_start; +extern struct cfg_element_entry _ld_bl_static_cfg_entry_end; + +const char *cfg_api_element_dump(void *val, enum CFG_ELEMENT_TYPE type, char *strs); +int cfg_api_element_set(uint32_t task, uint32_t element, uint32_t type, void *arg1, void *arg2); +int cfg_api_element_general_set(struct cfg_element_entry *entry, void *arg1, void *arg2); +int cfg_api_element_general_get(struct cfg_element_entry *entry, void *arg1, void *arg2); +#endif // _CFG_API_H_ diff --git a/src/include/bl602_wifi/cfg/cfg_task.h b/src/include/bl602_wifi/cfg/cfg_task.h new file mode 100644 index 0000000..ce52a82 --- /dev/null +++ b/src/include/bl602_wifi/cfg/cfg_task.h @@ -0,0 +1,57 @@ +#ifndef _CFG_TASK_H_ +#define _CFG_TASK_H_ + +#include + +#include + +#define CFG_IDX_MAX 1 + + +enum cfg_state_tag { + CFG_IDLE = 0, + CFG_STATE_MAX = 1, +}; + +enum cfg_msg_tag { + CFG_START_REQ = 12288, + CFG_START_CFM = 12289, +}; + +struct { + uint32_t task; // +0 + uint32_t element; // +4 + uint32_t length; // +8 + uint32_t buf[0]; // +12 +} cfg_start_req_u_tlv_t; + +struct cfg_start_req { + uint32_t ops; // +0 + union { + struct { + uint32_t task; // +0 + uint32_t element; // +4 + } get[0]; + struct { + uint32_t task; // +0 + uint32_t element; // +4 + } reset[0]; + struct { + uint32_t task; // +0 + uint32_t element; // +4 + uint32_t type; // +8 + uint32_t length; // +12 + uint32_t buf[0]; // +16 + } set[0]; + } u; // +4 +}; + +struct cfg_start_cfm { + uint8_t status; // +0 +}; + + +extern const struct ke_state_handler cfg_default_handler; +extern ke_state_t cfg_state[CFG_IDX_MAX]; + +#endif // _CFG_TASK_H_ diff --git a/src/include/bl602_wifi/dma/dma.h b/src/include/bl602_wifi/dma/dma.h new file mode 100644 index 0000000..be628d2 --- /dev/null +++ b/src/include/bl602_wifi/dma/dma.h @@ -0,0 +1,20 @@ +#ifndef _DMA_H_ +#define _DMA_H_ + +#include + +struct dma_desc { + uint32_t src; // +0 + uint32_t dest; // +4 + uint16_t length; // +8 + uint16_t ctrl; // +10 + uint32_t next; // +12 +}; + +struct dma_env_tag { + volatile struct dma_desc *last_dma[4]; // +0 +}; + +extern struct dma_env_tag dma_env; + +#endif diff --git a/src/include/bl602_wifi/dma/dma_reg.h b/src/include/bl602_wifi/dma/dma_reg.h new file mode 100644 index 0000000..06bf084 --- /dev/null +++ b/src/include/bl602_wifi/dma/dma_reg.h @@ -0,0 +1,19 @@ +#ifndef _DMA_REG_H_ +#define _DMA_REG_H_ +typedef struct DMA_Control_Reg DMA_Control_Reg, *DMA_Control_Reg; + +struct DMA_Control_Reg { + uint32_t TransferSize:12; + uint32_t SBSize:3; + uint32_t DBSize:3; + uint32_t SWidth:3; + uint32_t DWidth:3; + uint32_t SLargerD:1; + uint32_t reserved_25:1; + uint32_t SI:1; + uint32_t DI:1; + uint32_t Prot:3; + uint32_t I:1; +}; + +#endif // _DMA_REG_H_ diff --git a/src/include/bl602_wifi/hal/hal_desc.h b/src/include/bl602_wifi/hal/hal_desc.h new file mode 100644 index 0000000..211cb34 --- /dev/null +++ b/src/include/bl602_wifi/hal/hal_desc.h @@ -0,0 +1,480 @@ + +#ifndef _HAL_DESC_H_ +#define _HAL_DESC_H_ +#include + +#include +#include + +/// 20 MHz bandwidth +#define BW_20MHZ 0 +/// 40 MHz bandwidth +#define BW_40MHZ 1 +/// 80 MHz bandwidth +#define BW_80MHZ 2 +/// 160 or 80+80 MHz bandwidth +#define BW_160MHZ 3 + + +struct tx_policy_tbl { + uint32_t upatterntx; // +0 + uint32_t phycntrlinfo1; // +4 + uint32_t phycntrlinfo2; // +8 + uint32_t maccntrlinfo1; // +12 + uint32_t maccntrlinfo2; // +16 + uint32_t ratecntrlinfo[4]; // +20 + uint32_t powercntrlinfo[4]; // +36 +}; // :669:8 + +struct tx_compressed_policy_tbl { + uint32_t upatterntx; // +0 + uint32_t sec_user_control; // +4 +}; // :689:8 + +struct tx_hd { + uint32_t upatterntx; // +0 + uint32_t nextfrmexseq_ptr; // +4 + uint32_t nextmpdudesc_ptr; // +8 + union { + uint32_t first_pbd_ptr; + uint32_t sec_user1_ptr; + }; // +12 + union { + uint32_t datastartptr; + uint32_t sec_user2_ptr; + }; // +16 + union { + uint32_t dataendptr; + uint32_t sec_user3_ptr; + }; // +20 + uint32_t frmlen; // +24 + uint32_t frmlifetime; // +28 + uint32_t phyctrlinfo; // +32 + uint32_t policyentryaddr; // +36 + uint32_t optlen[3]; // +40 + uint32_t macctrlinfo1; // +52 + uint32_t macctrlinfo2; // +56 + uint32_t statinfo; // +60 + uint32_t mediumtimeused; // +64 +}; // :698:8 + +struct tx_pbd { + uint32_t upatterntx; // +0 + uint32_t next; // +4 + uint32_t datastartptr; // +8 + uint32_t dataendptr; // +12 + uint32_t bufctrlinfo; // +16 +}; // :748:8 + +struct rx_hd { + uint32_t upatternrx; // +0 + uint32_t next; // +4 + uint32_t first_pbd_ptr; // +8 + struct rx_swdesc *swdesc; // +12 + uint32_t datastartptr; // +16 + uint32_t dataendptr; // +20 + uint32_t headerctrlinfo; // +24 + uint16_t frmlen; // +28 + uint16_t ampdu_stat_info; // +30 + uint32_t tsflo; // +32 + uint32_t tsfhi; // +36 + uint32_t recvec1a; // +40 + uint32_t recvec1b; // +44 + uint32_t recvec1c; // +48 + uint32_t recvec1d; // +52 + uint32_t recvec2a; // +56 + uint32_t recvec2b; // +60 + uint32_t statinfo; // +64 +}; // :774:8 + +struct rx_pbd { + uint32_t upattern; // +0 + uint32_t next; // +4 + uint32_t datastartptr; // +8 + uint32_t dataendptr; // +12 + uint16_t bufstatinfo; // +16 + uint16_t reserved; // +18 +}; // :816:8 + +struct rx_dmadesc { + struct rx_hd hd; // +0 + struct phy_channel_info phy_info; // +68 + uint32_t flags; // +76 + uint32_t pattern; // +80 + uint32_t payl_offset; // +84 + uint32_t reserved_pad[2]; // +88 + uint32_t use_in_tcpip; // +96 +}; // :834:8 + +struct rx_payloaddesc { + struct rx_pbd pbd; // +0 + uint32_t pd_status; // +20 + uint32_t *buffer_rx; // +24 + void *pbuf_holder[6]; // +28 +}; // :854:8 + +struct tx_cfm_tag { + uint16_t pn[4]; // +0 + uint16_t sn; // +8 + uint16_t timestamp; // +10 + int8_t credits; // +12 + uint8_t ampdu_size; // +13 + uint8_t pad[2]; // +14 + uint32_t status; // +16 +}; // :865:8 + +struct tx_hw_desc { + struct tx_cfm_tag *cfm_ptr; // +0 + struct tx_hd thd; // +4 +}; // :885:8 + +struct tx_agg_desc { + uint8_t reserved; // +0 +}; // :979:8 + + +/// Bit indicating if an interrupt has to be set or not once packet is transmitted +#define INTERRUPT_EN_TX CO_BIT(8) + +/// Offset of Number of Blank delimiters +#define NB_BLANK_DELIM_OFT 9 +/// Mask of Number of Blank delimiters +#define NB_BLANK_DELIM_MSK (0x3FF << NB_BLANK_DELIM_OFT) + +/// 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) + +/// Under BA setup bit +#define UNDER_BA_SETUP_BIT CO_BIT(22) + +/// Don't touch duration bit +#define DONT_TOUCH_DUR CO_BIT(28) + + + +//---------------------------------------------------------------------------------------- +//THD STATINFO fields +//---------------------------------------------------------------------------------------- +/// Number of RTS frame retries offset +#define NUM_RTS_RETRIES_OFT 0 +/// Number of RTS frame retries mask +#define NUM_RTS_RETRIES_MSK (0xFF << NUM_RTS_RETRIES_OFT) +/// Number of MPDU frame retries offset +#define NUM_MPDU_RETRIES_OFT 8 +/// Number of MPDU frame retries mask +#define NUM_MPDU_RETRIES_MSK (0xFF << NUM_MPDU_RETRIES_OFT) +/// Retry limit reached: frame unsuccessful +#define RETRY_LIMIT_REACHED_BIT CO_BIT(16) +/// Frame lifetime expired: frame unsuccessful +#define LIFETIME_EXPIRED_BIT CO_BIT(17) +/// BA frame not received - valid only for MPDUs part of AMPDU +#define BA_FRAME_RECEIVED_BIT CO_BIT(18) +/// Frame successful by TX DMA: Ack received successfully +#define FRAME_SUCCESSFUL_TX_BIT CO_BIT(23) +/// Last MPDU of an A-MPDU +#define A_MPDU_LAST (0x0F << 26) +/// Transmission bandwidth offset +#define BW_TX_OFT 24 +/// Transmission bandwidth mask +#define BW_TX_MSK (0x3 << BW_TX_OFT) +/// Transmission bandwidth - 20MHz +#define BW_20MHZ_TX (0x0 << BW_TX_OFT) +/// Transmission bandwidth - 40MHz +#define BW_40MHZ_TX (0x1 << BW_TX_OFT) +/// Transmission bandwidth - 80MHz +#define BW_80MHZ_TX (0x2 << BW_TX_OFT) +/// Transmission bandwidth - 160MHz +#define BW_160MHZ_TX (0x3 << BW_TX_OFT) +/// Descriptor done bit: Set by HW for TX DMA +#define DESC_DONE_TX_BIT CO_BIT(31) +/// Descriptor done bit: Set by SW for TX DMA +#define DESC_DONE_SW_TX_BIT CO_BIT(30) + +/// uPattern for TX header descriptor. +#define TX_HEADER_DESC_PATTERN 0xCAFEBABE +/// uPattern for TX buffer descriptor +#define TX_PAYLOAD_DESC_PATTERN 0xCAFEFADE +/// uPattern for RX header descriptor. +#define RX_HEADER_DESC_PATTERN 0xBAADF00D +/// uPattern for RX payload descriptor. +#define RX_PAYLOAD_DESC_PATTERN 0xC0DEDBAD + +// Policy Table: Power Control Information field +/// Transmit Power Level for RCX offset +#define TX_PWR_LEVEL_PT_RCX_OFT 0 +/// Transmit Power Level for RCX mask +#define TX_PWR_LEVEL_PT_RCX_MASK (0xff << TX_PWR_LEVEL_PT_RCX_OFT) +/// Transmit Power Level of Protection for RCX offset +#define TX_PWR_LEVEL_PROT_PT_RCX_OFT 8 +/// Transmit Power Level of Protection for RCX mask +#define TX_PWR_LEVEL_PROT_PT_RCX_MASK (0xff << TX_PWR_LEVEL_PROT_PT_RCX_OFT) + + +/// @name RHD STATINFO +/// @{ + +/// Key index offset +#define KEY_IDX_OFT 15 +/// Key index mask +#define KEY_IDX_MSK (0x3FF << KEY_IDX_OFT) +/// Key index valid bit +#define KEY_IDX_VALID_BIT CO_BIT(25) +/// Immediate response access category offset +#define IMM_RSP_AC_OFT 11 +/// Immediate response access category mask +#define IMM_RSP_AC_MSK (0x03 << IMM_RSP_AC_OFT) + +/// Last buffer of the MPDU +#define RX_PD_LASTBUF 0x0001 +/// Descriptor Done in HW +#define RX_PD_DONE 0x0002 + +/// Storage RAM key index valid bit. +#define RX_HD_KEYIDV 0x02000000 +/// Storage RAM key index. +#define RX_HD_KEYID 0x01FF8000 +/// Lowest significant bit of the storage RAM key index. +#define RX_HD_KEYID_LSB 15 +/// Done bit. +#define RX_HD_DONE 0x00004000 +/// Frame successfully received bit. +#define RX_HD_SUCCESS 0x00002000 +/// Group Addressed frame bit. +#define RX_HD_GA_FRAME 0x00000400 +/// Address mismatch bit. +#define RX_HD_ADDRMIS 0x00000200 +/// FCS error bit. +#define RX_HD_FCSERR 0x0100 +/// PHY error bit. +#define RX_HD_PHYERR 0x00000080 +/// Undefined error bit. +#define RX_HD_UNDEFERR 0x00000040 +/// Decryption status mask. +#define RX_HD_DECRSTATUS 0x0000001C +/// Is response frame bit. +#define RX_HD_RSP_FRM 0x00000002 +/// Vector 2 valid bit. +#define RX_HD_RXVEC2V 0x00000001 +/// Frame unencrypted. +#define RX_HD_DECR_UNENC 0x0000 +/// WEP/TKIP ICV failure. +#define RX_HD_DECR_ICVFAIL 0x0004 +/// MAC CCMP failure. +#define RX_HD_DECR_CCMPFAIL 0x0008 +/// MAC A-MSDU discarded at HW. +#define RX_HD_DECR_AMSDUDISCARD 0x000C +/// NULL key found. +#define RX_HD_DECR_NULLKEY 0x0010 +/// MAC security type WEP. +#define RX_HD_DECR_WEPSUCCESS 0x0014 +/// MAC security type TKIP. +#define RX_HD_DECR_TKIPSUCCESS 0x0018 +/// MAC security type CCMP. +#define RX_HD_DECR_CCMPSUCCESS 0x001C +/// Macro to retrieve the storage RAM key index for the received frame. +/// @param[in] __s MPDU status information from the RX header descriptor. +#define RX_HD_KEYID_GET(__s) (((__s) & RX_HD_KEYID) >> RX_HD_KEYID_LSB) +/// Macro to retrieve the done bit of the received frame. +/// @param[in] __s MPDU status information from the RX header descriptor. +#define RX_HD_DONE_GET(__s) ((__s) & RX_HD_DONE) +/// Macro to retrieve the success bit of the received frame. +/// @param[in] __s MPDU status information from the RX header descriptor. +#define RX_HD_SUCCESS_GET(__s) ((__s) & (RX_HD_SUCCESS | RX_HD_FCSERR)) + +/// @} + +/// Length of the receive vectors +#define RXL_HWDESC_RXV_LEN 40 + +#define RATE_CONTROL_STEPS 4 +#define POLICY_TABLE_PATTERN 0xBADCAB1E + +#define STBC_PT_MASK (0x3 << STBC_PT_OFT) +/// Number of Transmit Chains for PPDU offset +#define NX_TX_PT_OFT 14 + +#define ANTENNA_SET_PT_OFT 0 + +#define MCS_INDEX_TX_RCX_OFT 0 + +//---------------------------------------------------------------------------------------- +// THD: PHY CONTROL INFO definitions +//---------------------------------------------------------------------------------------- +/// Sounding of PPDU Frame Transmission (Bit 0) +#define SOUNDING_TX_BIT CO_BIT(0) +/// Smoothing for PPDU frames (Bit 1) +#define SMTHN_TX_BIT CO_BIT(1) +/// Smoothing for Control frames (Bit 2) +#define SMTHN_PROT_BIT CO_BIT(2) +/// Use BW signaling bit +#define USE_BW_SIG_TX_BIT CO_BIT(3) +/// Dynamic BW +#define DYN_BW_TX_BIT CO_BIT(4) +/// Doze allowed by AP during TXOP +#define DOZE_ALLOWED_TX_BIT CO_BIT(5) +/// Continuous transmit +#define CONT_TX_BIT CO_BIT(6) +/// User Position field offset +#define USER_POS_OFT 12 +/// User Position field mask +#define USER_POS_MASK (0x3 << USER_POS_OFT) +/// Use RIFS for Transmission (Bit 14) +#define USE_RIFS_TX_BIT CO_BIT(14) +/// Use MU-MIMO for Transmission (Bit 15) +#define USE_MUMIMO_TX_BIT CO_BIT(15) +/// GroupId field offset +#define GID_TX_OFT 16 +/// GroupId field mask +#define GID_TX_MASK (0x3F << GID_TX_OFT) +/// Partial AID field offset +#define PAID_TX_OFT 22 +/// Partial AID field mask +#define PAID_TX_MASK (0x1FF << PAID_TX_OFT) + +//---------------------------------------------------------------------------------------- +// TBD: BUF CONTROL INFO definitions +//---------------------------------------------------------------------------------------- +/// Flag indicating if HW handled the buffer +#define TBD_DONE_HW CO_BIT(31) +/// Bit allowing to request HW to generate an interrupt upon a payload buffer transmission +#define TBD_INTERRUPT_EN CO_BIT(0) + +//---------------------------------------------------------------------------------------- +// THD: MAC CONTROL INFO 1 definitions +//---------------------------------------------------------------------------------------- +/// Protection Frame Duration offset +#define PROT_FRM_DURATION_OFT 16 +/// Protection Frame Duration mask +#define PROT_FRM_DURATION_MSK (0xFFFF << PROT_FRM_DURATION_OFT) + +/// Set if ACK has to be passed to SW +#define WRITE_ACK CO_BIT(14) +/// Set if lower rates have to be used for retries +#define LOW_RATE_RETRY CO_BIT(13) +/// L-SIG TXOP Protection for protection frame +#define LSTP_PROT CO_BIT(12) +/// L-SIG TXOP Protection +#define LSTP CO_BIT(11) + +// Expected Acknowledgment +/// Expected Acknowledgment offset +#define EXPECTED_ACK_OFT 9 +/// Expected Acknowledgment mask +#define EXPECTED_ACK_MSK (0x3 << EXPECTED_ACK_OFT) +/// No acknowledgment +#define EXPECTED_ACK_NO_ACK (0x0 << EXPECTED_ACK_OFT) +/// Normal acknowledgment +#define EXPECTED_ACK_NORMAL_ACK (0x1 << EXPECTED_ACK_OFT) +/// Uncompressed block acknowledgment +#define EXPECTED_ACK_BLOCK_ACK (0x2 << EXPECTED_ACK_OFT) +/// Compressed block acknowledgment +#define EXPECTED_ACK_COMPRESSED_BLOCK_ACK (0x3 << EXPECTED_ACK_OFT) + +/// legacy RATE definitions +typedef enum +{ + /// 1Mbps + HW_RATE_1MBPS = 0, + /// 2Mbps + HW_RATE_2MBPS, + /// 5.5Mbps + HW_RATE_5_5MBPS, + /// 11Mbps + HW_RATE_11MBPS, + /// 6Mbps + HW_RATE_6MBPS, + /// 9Mbps + HW_RATE_9MBPS, + /// 12Mbps + HW_RATE_12MBPS, + /// 18Mbps + HW_RATE_18MBPS, + /// 24Mbps + HW_RATE_24MBPS, + /// 36Mbps + HW_RATE_36MBPS, + /// 48Mbps + HW_RATE_48MBPS, + /// 54Mbps + HW_RATE_54MBPS +} HW_RATE_E; + + +// Policy Table: Rate Control Information field +/// MCS Index offset +#define MCS_INDEX_TX_RCX_OFT 0 +/// MCS Index mask +#define MCS_INDEX_TX_RCX_MASK (0X7FU << MCS_INDEX_TX_RCX_OFT) +/// Bandwidth for transmission offset +#define BW_TX_RCX_OFT 7 +/// Bandwidth for transmission mask +#define BW_TX_RCX_MASK (0X3U << BW_TX_RCX_OFT) +/// Short Guard Interval for Transmission offset +#define SHORT_GI_TX_RCX_OFT 9 +/// Short Guard Interval for Transmission mask +#define SHORT_GI_TX_RCX_MASK (0x1U << SHORT_GI_TX_RCX_OFT) +/// Preamble type for 11b Transmission offset +#define PRE_TYPE_TX_RCX_OFT 10 +/// Preamble type for 11b Transmission mask +#define PRE_TYPE_TX_RCX_MASK (0x1U << PRE_TYPE_TX_RCX_OFT) +/// Format of the modulation offset +#define FORMAT_MOD_TX_RCX_OFT 11 +/// Format of the modulation mask +#define FORMAT_MOD_TX_RCX_MASK (0X7U << FORMAT_MOD_TX_RCX_OFT) +/// Type of NAV protection frame exchange offset +#define PROT_FRM_EX_RCX_OFT 14 +/// Type of NAV protection frame exchange mask +#define PROT_FRM_EX_RCX_MASK (0X7 << PROT_FRM_EX_RCX_OFT) +/// No protection +#define PROT_NO_PROT (0x0 << PROT_FRM_EX_RCX_OFT) +/// Self-CTS +#define PROT_SELF_CTS (0x1 << PROT_FRM_EX_RCX_OFT) +/// RTS-CTS with intended receiver +#define PROT_RTS_CTS (0x2 << PROT_FRM_EX_RCX_OFT) +/// RTS-CTS with QAP +#define PROT_RTS_CTS_WITH_QAP (0x3 << PROT_FRM_EX_RCX_OFT) +/// STBC protection +#define PROT_STBC (0x4 << PROT_FRM_EX_RCX_OFT) + + +// TODO: check why tx_hw_descX are not existing in binary +// It seems that the entire tx_swdesc is not exists in bl602 +extern struct dma_desc bcn_dwnld_desc; +extern struct rx_dmadesc rx_dma_hdrdesc[]; // NX_RXDESC_CNT +extern struct rx_payloaddesc rx_payload_desc[]; // NX_RX_PAYLOAD_DESC_CNT +extern uint32_t rx_payload_desc_buffer[NX_RX_PAYLOAD_DESC_CNT][212]; +extern struct tx_hw_desc tx_hw_desc0[RW_USER_MAX * NX_TXDESC_CNT0]; +extern struct tx_hw_desc tx_hw_desc1[RW_USER_MAX * NX_TXDESC_CNT0]; +extern struct tx_hw_desc tx_hw_desc2[RW_USER_MAX * NX_TXDESC_CNT0]; +extern struct tx_hw_desc tx_hw_desc3[RW_USER_MAX * NX_TXDESC_CNT0]; +#if (NX_BEACONING) +/// Array of HW descriptors for BCN queue +extern struct tx_hw_desc tx_hw_desc4[NX_TXDESC_CNT4]; +#endif +extern struct tx_cfm_tag tx_hw_cfms[RW_USER_MAX * NX_TXDESC_CNT0]; + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/hal/hal_dma.h b/src/include/bl602_wifi/hal/hal_dma.h new file mode 100644 index 0000000..a105613 --- /dev/null +++ b/src/include/bl602_wifi/hal/hal_dma.h @@ -0,0 +1,37 @@ +#ifndef _HAL_DMA_H_ +#define _HAL_DMA_H_ + +#include + +#include +#include + +enum { + /// A general purpose DMA download + DMA_DL, + /// A general purpose DMA upload + DMA_UL, + /// Number of general purpose DMA directions + DMA_MAX +}; + +typedef void (*cb_dma_func_ptr)(void *, int); +struct hal_dma_desc_tag { + struct co_list_hdr hdr; // +0 + struct dma_desc *dma_desc; // +4 + cb_dma_func_ptr cb; // +8 + void *env; // +12 +}; +struct hal_dma_env_tag { + struct co_list prog[2]; // +0 + struct co_list free_gp_dma_descs; // +16 + uint16_t lli_cnt[2]; // +24 +}; + +extern struct hal_dma_env_tag hal_dma_env; + +void hal_dma_init(void); +void hal_dma_push(struct hal_dma_desc_tag *desc, int type); +void hal_dma_evt(int dma_queue); + +#endif // _HAL_DMA_H_ diff --git a/src/include/bl602_wifi/hal/hal_machw.h b/src/include/bl602_wifi/hal/hal_machw.h new file mode 100644 index 0000000..480aa40 --- /dev/null +++ b/src/include/bl602_wifi/hal/hal_machw.h @@ -0,0 +1,128 @@ +#ifndef _HAL_MACHW_H_ +#define _HAL_MACHW_H_ + +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +/// For MAC HW States. +enum { + /// MAC HW IDLE State. + HW_IDLE = 0, + /// MAC HW RESERVED State. + HW_RESERVED, + /// MAC HW DOZE State. + HW_DOZE, + /// MAC HW ACTIVE State. + HW_ACTIVE +}; + + +/// Mapping of HW timers +enum +{ + /// AC0 TX timeout + HAL_AC0_TIMER = 0, + /// AC1 TX timeout + HAL_AC1_TIMER, + /// AC2 TX timeout + HAL_AC2_TIMER, + /// AC3 TX timeout + HAL_AC3_TIMER, + /// BCN TX timeout + HAL_BCN_TIMER, + /// Go to IDLE timeout + HAL_IDLE_TIMER, + /// RX interrupt mitigation timeout + HAL_RX_TIMER, + #if NX_MM_TIMER + /// MM timeout + HAL_MM_TIMER, + #endif + /// Kernel timer + HAL_KE_TIMER, + + /// Number of HW timers used + HAL_TIMER_MAX, +}; + +/// Bits associated to HW timers +enum +{ + /// AC0 TX timeout bit + HAL_AC0_TIMER_BIT = CO_BIT(HAL_AC0_TIMER), + /// AC1 TX timeout bit + HAL_AC1_TIMER_BIT = CO_BIT(HAL_AC1_TIMER), + /// AC2 TX timeout bit + HAL_AC2_TIMER_BIT = CO_BIT(HAL_AC2_TIMER), + /// AC3 TX timeout bit + HAL_AC3_TIMER_BIT = CO_BIT(HAL_AC3_TIMER), + /// BCN TX timeout bit + HAL_BCN_TIMER_BIT = CO_BIT(HAL_BCN_TIMER), + /// Go to IDLE timeout bit + HAL_IDLE_TIMER_BIT = CO_BIT(HAL_IDLE_TIMER), + /// RX interrupt mitigation timeout bit + HAL_RX_TIMER_BIT = CO_BIT(HAL_RX_TIMER), + #if NX_MM_TIMER + /// MM timeout bit + HAL_MM_TIMER_BIT = CO_BIT(HAL_MM_TIMER), + #endif + /// Kernel timer bit + HAL_KE_TIMER_BIT = CO_BIT(HAL_KE_TIMER), +}; + +static inline uint32_t hal_machw_time(void) { + return MAC_CORE->MONOTONIC_COUNTER_2_LO.value; +} + +static inline bool hal_machw_time_cmp(uint32_t time1, uint32_t time2) { + uint32_t diff = time1 - time2; + return (((int32_t)diff) < 0); +} + +static inline bool hal_machw_time_past(uint32_t time) { + return (hal_machw_time_cmp(time, hal_machw_time())); +} + +extern const uint8_t rxv2macrate[]; + +uint32_t hal_machw_rx_duration(struct rx_hd *rhd, uint16_t len) { + rvec_t *recv = (rvec_t *) &(rhd->recvec1a); + uint8_t mcs_index = recv->leg_rate; + MAC_PL->TIME_ON_AIR_PARAM_2.value = mcs_index; + uint8_t pre_type = recv->pre_type; + PACK(MAC_PL->TIME_ON_AIR_PARAM_1, time_on_air_param_1) { + time_on_air_param_1.value = 0; + time_on_air_param_1.ppduLength = len; + time_on_air_param_1.ppduPreType = pre_type; + } + PACK(MAC_PL->TIME_ON_AIR_VALUE, time_on_air_value) { + time_on_air_value.value = 0; + time_on_air_value.computeDuration = 1; + } + for (;!MAC_PL->TIME_ON_AIR_VALUE.timeOnAirValid;); + ASSERT_REC_VAL(MAC_PL->TIME_ON_AIR_VALUE.timeOnAirValid != 0, 500); + return MAC_PL->TIME_ON_AIR_VALUE.timeOnAir; +} + +void hal_machw_init(void); +void hal_machw_reset(void); +uint8_t hal_machw_search_addr(struct mac_addr *addr); +void hal_machw_disable_int(void); +void hal_machw_stop(void); +void hal_machw_monitor_mode(void); +bool hal_machw_sleep_check(void); +void hal_machw_idle_req(void); +extern void hal_machw_gen_handler(void); + +#endif // _HAL_MACHW_H_ diff --git a/src/include/bl602_wifi/intc/intc.h b/src/include/bl602_wifi/intc/intc.h new file mode 100644 index 0000000..f68d730 --- /dev/null +++ b/src/include/bl602_wifi/intc/intc.h @@ -0,0 +1,7 @@ +#ifndef _INTC_H_ +#define _INTC_H_ + +void intc_init(void); +void intc_spurious(void); + +#endif // _INTC_H_ diff --git a/src/include/bl602_wifi/ipc/ipc_emb.h b/src/include/bl602_wifi/ipc/ipc_emb.h new file mode 100644 index 0000000..eaaa008 --- /dev/null +++ b/src/include/bl602_wifi/ipc/ipc_emb.h @@ -0,0 +1,48 @@ +#ifndef _IPC_EMB_H_ +#define _IPC_EMB_H_ + +#include +#include +#include + +#include + +struct ipc_emb_env_tag { + struct co_list rx_queue; // +0 + struct co_list cfm_queue; // +8 + uint8_t ipc_rxdesc_idx; // +16 + uint8_t ipc_rxbuf_idx; // +17 + uint8_t ipc_radar_buf_idx; // +18 + uint8_t ipc_msge2a_buf_idx; // +19 + uint8_t ipc_dbg_buf_idx; // +20 + uint8_t ipc_msgacke2a_cnt; // +21 + uint32_t txdesc_idx; // +24 + volatile struct txdesc_host *txdesc; // +28 +}; + + +extern struct ipc_emb_env_tag ipc_emb_env; +extern const int nx_txdesc_cnt_msk[]; + + +static inline bool ipc_emb_tx_q_has_data(int queue_idx) { + // guessed, not sure if it's !=0 or == 0 + // rationally, it should be != 0 + return (ipc_emb_env.txdesc + (ipc_emb_env.txdesc_idx & 3))->ready != 0; +} + +uint32_t ipc_emb_tx_evt_field(uint32_t stat); +void ipc_emb_txcfm_ind(uint32_t queue_bits); +void ipc_emb_init(void); +void ipc_emb_notify(void); +void ipc_emb_wait(void); +void ipc_emb_msg_dma_int_handler(void); +void ipc_emb_dbg_dma_int_handler(void); +void ipc_emb_msg_irq(void); +void ipc_emb_cfmback_irq(void); +void ipc_emb_tx_irq(void); + +void ipc_emb_tx_evt(int queue_idx); +void ipc_emb_msg_evt(int dummy); + +#endif diff --git a/src/include/bl602_wifi/ipc/ipc_shared.h b/src/include/bl602_wifi/ipc/ipc_shared.h new file mode 100644 index 0000000..38c2173 --- /dev/null +++ b/src/include/bl602_wifi/ipc/ipc_shared.h @@ -0,0 +1,18 @@ +#ifndef _IPC_SHARED_H_ +#define _IPC_SHARED_H_ +#include +#include + +#include + +struct ipc_a2e_msg { + uint32_t dummy_word; // +0 + uint32_t msg[127]; // +4 +}; // :213:8 +struct ipc_shared_env_tag { + volatile struct ipc_a2e_msg msg_a2e_buf; // +0 + volatile uint32_t pattern_addr; // +512 + volatile struct txdesc_host txdesc0[4]; // +516 +}; // :244:8 +extern struct ipc_shared_env_tag ipc_shared_env; // :257:34 +#endif // _IPC_SHARED_H_ \ No newline at end of file diff --git a/src/include/bl602_wifi/la/la_mem.h b/src/include/bl602_wifi/la/la_mem.h new file mode 100644 index 0000000..5a9f460 --- /dev/null +++ b/src/include/bl602_wifi/la/la_mem.h @@ -0,0 +1,8 @@ +#ifndef _LA_MEM_H_ +#define _LA_MEM_H_ + +struct la_mem_format { + uint32_t word[4]; // +0 +}; // :37:8 + +#endif // _LA_MEM_H_ diff --git a/src/include/bl602_wifi/lmac/bl/bl.h b/src/include/bl602_wifi/lmac/bl/bl.h new file mode 100644 index 0000000..b5b9a1c --- /dev/null +++ b/src/include/bl602_wifi/lmac/bl/bl.h @@ -0,0 +1,21 @@ +#ifndef _BL_H_ +#define _BL_H_ + +#include + + +struct bl_env_tag { + uint8_t prev_hw_state; // +0 + int hw_in_doze; // +4 +}; + +extern struct bl_env_tag bl_env; + +void bl_init(void); +uint32_t bl_nap_calculate(void); +int bl_sleep(void); +void bl_reset_evt(int dummy); + +extern struct notifier_block fw_nap_chain; + +#endif // _BL_H_ diff --git a/src/include/bl602_wifi/lmac/bl/version.h b/src/include/bl602_wifi/lmac/bl/version.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/bl602_wifi/lmac/chan/chan.h b/src/include/bl602_wifi/lmac/chan/chan.h new file mode 100644 index 0000000..9d36f56 --- /dev/null +++ b/src/include/bl602_wifi/lmac/chan/chan.h @@ -0,0 +1,131 @@ +#ifndef _CHAN_H_ +#define _CHAN_H_ + +#include +#include + +#include +#include +#include +#include + + +struct vif_info_tag; + +enum chan_ctxt_status { + CHAN_NOT_SCHEDULED = 0, + CHAN_NOT_PROG = 1, + CHAN_GOTO_IDLE = 2, + CHAN_WAIT_NOA_CFM = 3, + CHAN_WAITING_END = 4, + CHAN_PRESENT = 5, + CHAN_SENDING_NOA = 6, + CHAN_CTXT_STATUS_MAX = 7, +}; + +enum chan_tbtt_status { + CHAN_TBTT_NOT_PROG = 0, + CHAN_TBTT_PROG = 1, + CHAN_TBTT_PRESENCE = 2, + CHAN_TBTT_STATUS_MAX = 3, +}; + +enum chan_env_status_bit { + CHAN_ENV_ROC_WAIT_BIT = 0, + CHAN_ENV_SCAN_WAIT_BIT = 1, + CHAN_ENV_ROC_BIT = 2, + CHAN_ENV_SCAN_BIT = 3, + CHAN_ENV_DELAY_PROG_BIT = 4, + CHAN_ENV_TIMEOUT_BIT = 5, + CHAN_ENV_BCN_DETECT_BIT = 6, + CHAN_ENV_BIT_MAX = 7, +}; + +struct chan_tbtt_tag { + struct co_list_hdr list_hdr; // +0 + uint32_t time; // +4 + uint8_t vif_index; // +8 + uint8_t priority; // +9 + uint8_t status; // +10 +}; + +struct chan_ctxt_tag { + struct co_list_hdr list_hdr; // +0 + struct mm_chan_ctxt_add_req channel; // +4 + ke_task_id_t taskid; // +14 + uint16_t nb_slots; // +16 + uint16_t nb_rem_slots; // +18 + uint16_t nb_res_slots; // +20 + uint8_t status; // +22 + uint8_t idx; // +23 + uint8_t nb_linked_vif; // +24 + uint8_t vif_index; // +25 +}; + +struct chan_env_tag { + struct co_list list_free_ctxt; // +0 + struct co_list list_sched_ctxt; // +8 + struct co_list list_tbtt; // +16 + struct co_list list_tbtt_delay; // +24 + struct chan_ctxt_tag *current_channel; // +32 + struct chan_ctxt_tag *chan_switch; // +36 + struct mm_timer_tag tmr_tbtt_switch; // +40 + struct mm_timer_tag tmr_cde; // +56 + struct mm_timer_tag tmr_ctxt_op; // +72 + struct mm_timer_tag tmr_conn_less; // +88 + uint32_t cde_dur_us; // +104 + uint32_t cde_time; // +108 + uint8_t status; // +112 + uint8_t cfm_cnt; // +113 + uint8_t nb_sched_ctxt; // +114 + uint8_t pm; // +115 +}; + + +extern struct chan_env_tag chan_env; + + +void chan_init(void); +void chan_scan_req(uint8_t band, uint16_t freq, int8_t pwr, uint32_t duration_us, uint8_t vif_index); +uint8_t chan_roc_req(const struct mm_remain_on_channel_req *req, ke_task_id_t taskid); +uint8_t chan_ctxt_add(const struct mm_chan_ctxt_add_req *p_add_req, uint8_t *idx); +void chan_ctxt_link(uint8_t vif_idx, uint8_t chan_idx); +void chan_ctxt_unlink(uint8_t vif_idx); +void chan_ctxt_update(const struct mm_chan_ctxt_update_req *p_upd_req); +void chan_tbtt_switch_update(struct vif_info_tag *p_vif_entry, uint32_t tbtt_time); +void chan_bcn_to_evt(struct vif_info_tag *p_vif_entry); +void chan_bcn_detect_start(struct vif_info_tag *p_vif_entry); +bool chan_is_on_channel(struct vif_info_tag *p_vif_entry); +bool chan_is_on_operational_channel(struct vif_info_tag *p_vif_entry); +bool chan_is_tx_allowed(struct vif_info_tag *p_vif_entry); +void chan_update_tx_power(struct chan_ctxt_tag *p_chan_entry); + +/// Number of channel contexts for traffic +#define CHAN_TRAF_CTXT_CNT (NX_CHAN_CTXT_CNT) +/// Number of channel context (+1 for the Scan Channel Context and +1 for the Remain on Channel Context) +#define CHAN_CHAN_CTXT_CNT (CHAN_TRAF_CTXT_CNT + 1 + 1) +/// Index of the Scan Channel Context +#define CHAN_SCAN_CTXT_IDX (CHAN_TRAF_CTXT_CNT) +/// Index of the Remain on Channel Context +#define CHAN_ROC_CTXT_IDX (CHAN_SCAN_CTXT_IDX + 1) +/// Index of a Channel Context that is not linked with a VIF +#define CHAN_CTXT_UNUSED (0xFF) + +/// Duration of a slot (in TUs) +#define CHAN_SLOT_DURATION_TU (1) +/// Duration of a slot (in us) +#define CHAN_SLOT_DURATION_US (CHAN_SLOT_DURATION_TU * 1024) +/// Number of slots initially allocated for a VIF +#define CHAN_VIF_NB_SLOTS (50) + +/// Maximal TBTT presence duration (in slots) +#define CHAN_MAX_TBTT_PRES_DUR (10) +/// Minimal presence duration on a channel (in slots) +#define CHAN_MIN_PRES_DUR (5) + +#define CHAN_CONN_LESS_DELAY (30000) +#define CHAN_SWITCH_DELAY (2500) +#define CHAN_MIN_TIMER_VALUE (2000) +#define CHAN_TBTT_PRIORITY_MAX (5) +#define CHAN_SWITCH_TO_DUR (4000) +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/lmac/mm/mm.h b/src/include/bl602_wifi/lmac/mm/mm.h new file mode 100644 index 0000000..02de670 --- /dev/null +++ b/src/include/bl602_wifi/lmac/mm/mm.h @@ -0,0 +1,290 @@ +#ifndef _MM_H_ +#define _MM_H_ + +#include +#include + +#include +#include +#include +#include + +#include + +enum mm_features { + MM_FEAT_BCN_BIT = 0, + MM_FEAT_AUTOBCN_BIT = 1, + MM_FEAT_HWSCAN_BIT = 2, + MM_FEAT_CMON_BIT = 3, + MM_FEAT_MROLE_BIT = 4, + MM_FEAT_RADAR_BIT = 5, + MM_FEAT_PS_BIT = 6, + MM_FEAT_UAPSD_BIT = 7, + MM_FEAT_DPSM_BIT = 8, + MM_FEAT_AMPDU_BIT = 9, + MM_FEAT_AMSDU_BIT = 10, + MM_FEAT_CHNL_CTXT_BIT = 11, + MM_FEAT_REORD_BIT = 12, + MM_FEAT_P2P_BIT = 13, + MM_FEAT_P2P_GO_BIT = 14, + MM_FEAT_UMAC_BIT = 15, + MM_FEAT_VHT_BIT = 16, + MM_FEAT_BFMEE_BIT = 17, + MM_FEAT_BFMER_BIT = 18, + MM_FEAT_WAPI_BIT = 19, + MM_FEAT_MFP_BIT = 20, + MM_FEAT_MU_MIMO_RX_BIT = 21, + MM_FEAT_MU_MIMO_TX_BIT = 22, + MM_FEAT_MESH_BIT = 23, + MM_FEAT_TDLS_BIT = 24, +}; + +///BA agreement related status +enum { + /// Correct BA agreement establishment + BA_AGMT_ESTABLISHED, + /// BA agreement already exists for STA+TID requested, cannot override it (should have been deleted first) + BA_AGMT_ALREADY_EXISTS, + /// Correct BA agreement deletion + BA_AGMT_DELETED, + /// BA agreement for the (STA, TID) doesn't exist so nothing to delete + BA_AGMT_DOESNT_EXIST, + /// No more BA agreement can be added for the specified type + BA_AGMT_NO_MORE_BA_AGMT, + /// BA agreement type not supported + BA_AGMT_NOT_SUPPORTED +}; + +///BA agreement types +enum +{ + ///BlockAck agreement for TX + BA_AGMT_TX, + ///BlockAck agreement for RX + BA_AGMT_RX, +}; + +struct mm_env_tag { + uint32_t rx_filter_umac; // +0 + uint32_t rx_filter_lmac_enable; // +4 + uint16_t ampdu_max_dur[5]; // +8 + uint8_t prev_mm_state; // +18 + uint8_t prev_hw_state; // +19 + uint32_t basic_rates[2]; // +20 + uint32_t uapsd_timeout; // +28 + uint16_t lp_clk_accuracy; // +32 + uint8_t host_idle; // +34 + bool keep_alive_status_enabled; // +35 + uint32_t keep_alive_packet_counter; // +36 + uint32_t keep_alive_time_last_received; // +40 +}; + +extern struct mm_env_tag mm_env; + +void mm_rx_filter_set(void); + +inline static void mm_rx_filter_umac_set(uint32_t filter) { + mm_env.rx_filter_umac = filter; + mm_rx_filter_set(); +} + +inline static void mm_rx_filter_lmac_enable_set(uint32_t filter) { + mm_env.rx_filter_lmac_enable |= filter; + mm_rx_filter_set(); +} + +inline static void mm_rx_filter_lmac_enable_clear(uint32_t filter) { + mm_env.rx_filter_lmac_enable &= ~filter; + mm_rx_filter_set(); +} + +void mm_ps_change_ind(uint8_t sta_idx, uint8_t ps_state); + +void mm_init(void); +void mm_reset(void); +void mm_active(void); +void mm_env_max_ampdu_duration_set(void); +uint8_t mm_sec_machwkey_wr(const struct mm_key_add_req *param); +void mm_sec_machwkey_del(uint8_t hw_key_idx); +bool mm_check_beacon(struct rx_hd *rhd, struct vif_info_tag *vif_entry, struct sta_info_tag *p_sta_entry, uint32_t *tim); +void mm_hw_info_set(const struct mac_addr *mac_addr); +void mm_hw_ap_info_set(void); +void mm_hw_ap_info_reset(void); +void mm_force_idle_req(void); +uint8_t mm_sta_add(const struct mm_sta_add_req *param, uint8_t *sta_idx, uint8_t *hw_sta_idx); +void mm_sta_del(uint8_t sta_idx); +void mm_back_to_host_idle(void); +void mm_cfg_element_keepalive_timestamp_update(void); +void mm_send_connection_loss_ind(struct vif_info_tag *p_vif_entry); +void mm_send_csa_traffic_ind(uint8_t vif_index, bool enable); +void mm_check_rssi(struct vif_info_tag *vif_entry, int8_t rssi); + +void mm_tbtt_evt(int dummy); +void mm_hw_idle_evt(int dummy); + +#define TXOP(limit) (((limit)==0) || ((limit) > MM_DEFAULT_MAX_AMPDU_DURATION))? \ + MM_DEFAULT_MAX_AMPDU_DURATION:(limit); +#define MM_DEFAULT_MAX_AMPDU_DURATION 150 // not 100 +#define MM_BEACON_LOSS_THD (100) // not 30 +/// Periodicity of keep-alive NULL frame transmission +#define MM_KEEP_ALIVE_PERIOD (30 * 1000000) ///< 30s +/// Default peer device accuracy (in ppm) +#define MM_AP_CLK_ACCURACY 20 + +#define NXMAC_EN_DUPLICATE_DETECTION_BIT ((uint32_t)0x80000000) +#define NXMAC_EN_DUPLICATE_DETECTION_POS 31 +#define NXMAC_ACCEPT_UNKNOWN_BIT ((uint32_t)0x40000000) +#define NXMAC_ACCEPT_UNKNOWN_POS 30 +#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT ((uint32_t)0x20000000) +#define NXMAC_ACCEPT_OTHER_DATA_FRAMES_POS 29 +#define NXMAC_ACCEPT_QO_S_NULL_BIT ((uint32_t)0x10000000) +#define NXMAC_ACCEPT_QO_S_NULL_POS 28 +#define NXMAC_ACCEPT_QCFWO_DATA_BIT ((uint32_t)0x08000000) +#define NXMAC_ACCEPT_QCFWO_DATA_POS 27 +#define NXMAC_ACCEPT_Q_DATA_BIT ((uint32_t)0x04000000) +#define NXMAC_ACCEPT_Q_DATA_POS 26 +#define NXMAC_ACCEPT_CFWO_DATA_BIT ((uint32_t)0x02000000) +#define NXMAC_ACCEPT_CFWO_DATA_POS 25 +#define NXMAC_ACCEPT_DATA_BIT ((uint32_t)0x01000000) +#define NXMAC_ACCEPT_DATA_POS 24 +#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_BIT ((uint32_t)0x00800000) +#define NXMAC_ACCEPT_OTHER_CNTRL_FRAMES_POS 23 +#define NXMAC_ACCEPT_CF_END_BIT ((uint32_t)0x00400000) +#define NXMAC_ACCEPT_CF_END_POS 22 +#define NXMAC_ACCEPT_ACK_BIT ((uint32_t)0x00200000) +#define NXMAC_ACCEPT_ACK_POS 21 +#define NXMAC_ACCEPT_CTS_BIT ((uint32_t)0x00100000) +#define NXMAC_ACCEPT_CTS_POS 20 +#define NXMAC_ACCEPT_RTS_BIT ((uint32_t)0x00080000) +#define NXMAC_ACCEPT_RTS_POS 19 +#define NXMAC_ACCEPT_PS_POLL_BIT ((uint32_t)0x00040000) +#define NXMAC_ACCEPT_PS_POLL_POS 18 +#define NXMAC_ACCEPT_BA_BIT ((uint32_t)0x00020000) +#define NXMAC_ACCEPT_BA_POS 17 +#define NXMAC_ACCEPT_BAR_BIT ((uint32_t)0x00010000) +#define NXMAC_ACCEPT_BAR_POS 16 +#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT ((uint32_t)0x00008000) +#define NXMAC_ACCEPT_OTHER_MGMT_FRAMES_POS 15 +#define NXMAC_ACCEPT_ALL_BEACON_BIT ((uint32_t)0x00002000) +#define NXMAC_ACCEPT_ALL_BEACON_POS 13 +#define NXMAC_ACCEPT_NOT_EXPECTED_BA_BIT ((uint32_t)0x00001000) +#define NXMAC_ACCEPT_NOT_EXPECTED_BA_POS 12 +#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_BIT ((uint32_t)0x00000800) +#define NXMAC_ACCEPT_DECRYPT_ERROR_FRAMES_POS 11 +#define NXMAC_ACCEPT_BEACON_BIT ((uint32_t)0x00000400) +#define NXMAC_ACCEPT_BEACON_POS 10 +#define NXMAC_ACCEPT_PROBE_RESP_BIT ((uint32_t)0x00000200) +#define NXMAC_ACCEPT_PROBE_RESP_POS 9 +#define NXMAC_ACCEPT_PROBE_REQ_BIT ((uint32_t)0x00000100) +#define NXMAC_ACCEPT_PROBE_REQ_POS 8 +#define NXMAC_ACCEPT_MY_UNICAST_BIT ((uint32_t)0x00000080) +#define NXMAC_ACCEPT_MY_UNICAST_POS 7 +#define NXMAC_ACCEPT_UNICAST_BIT ((uint32_t)0x00000040) +#define NXMAC_ACCEPT_UNICAST_POS 6 +#define NXMAC_ACCEPT_ERROR_FRAMES_BIT ((uint32_t)0x00000020) +#define NXMAC_ACCEPT_ERROR_FRAMES_POS 5 +#define NXMAC_ACCEPT_OTHER_BSSID_BIT ((uint32_t)0x00000010) +#define NXMAC_ACCEPT_OTHER_BSSID_POS 4 +#define NXMAC_ACCEPT_BROADCAST_BIT ((uint32_t)0x00000008) +#define NXMAC_ACCEPT_BROADCAST_POS 3 +#define NXMAC_ACCEPT_MULTICAST_BIT ((uint32_t)0x00000004) +#define NXMAC_ACCEPT_MULTICAST_POS 2 +#define NXMAC_DONT_DECRYPT_BIT ((uint32_t)0x00000002) +#define NXMAC_DONT_DECRYPT_POS 1 +#define NXMAC_EXC_UNENCRYPTED_BIT ((uint32_t)0x00000001) +#define NXMAC_EXC_UNENCRYPTED_POS 0 + +/// RX filter for monitoring mode (all packets allowed) +#define MM_RX_FILTER_MONITOR (0xFFFFFFFF & ~(NXMAC_ACCEPT_ERROR_FRAMES_BIT \ + | NXMAC_EXC_UNENCRYPTED_BIT | \ + NXMAC_EN_DUPLICATE_DETECTION_BIT)) + +/// Number of VLAN Id +#if NX_KEY_RAM_CONFIG +#define MM_SEC_VLAN_COUNT (NX_VIRT_DEV_MAX + RW_MESH_LINK_NB) +#else +#define MM_SEC_VLAN_COUNT 6 +#endif + +/// Number of default keys +#define MM_SEC_DEFAULT_KEY_COUNT (MAC_DEFAULT_KEY_COUNT * MM_SEC_VLAN_COUNT) // =8 + + +/// NULL cipher +#define MM_SEC_CTYPE_NULL 0 +/// WEP (RC4) cipher +#define MM_SEC_CTYPE_WEP 1 +/// TKIP cipher +#define MM_SEC_CTYPE_TKIP 2 +/// CCMP cipher +#define MM_SEC_CTYPE_CCMP 3 +/// WAPI (SMS4) cipher +#define MM_SEC_CTYPE_WPI_SMS4 4 + +/// Macro converting a default key index to its HW index in key memory +#define MM_VIF_TO_KEY(key_idx, vif_idx) ((key_idx) + ((vif_idx) * MAC_DEFAULT_KEY_COUNT)) +/// Macro converting a STA index to the its HW pairwise key index in key memory +#define MM_STA_TO_KEY(sta_idx) ((sta_idx) + MM_SEC_DEFAULT_KEY_COUNT) +#if (RW_MESH_EN) +/// Macro converting a Mesh Link Index and a key index to its HW index in key memory +#define MM_MLINK_TO_KEY(key_idx, mlink_idx) (((NX_VIRT_DEV_MAX + mlink_idx) * MAC_DEFAULT_KEY_COUNT) + key_idx) +#endif //(RW_MESH_EN) + +/// Macro converting HW pairwise key index (>= @ref MAC_DEFAULT_KEY_COUNT) to a STA index +#define MM_KEY_TO_STA(hw_key_idx) ((hw_key_idx) - MM_SEC_DEFAULT_KEY_COUNT) +/// Macro converting a hw_key_idx (< @ref MAC_DEFAULT_KEY_COUNT) to the VIF index it corresponds +#define MM_KEY_TO_VIF(hw_key_idx) (((hw_key_idx) & ~(MAC_DEFAULT_KEY_COUNT - 1)) / MAC_DEFAULT_KEY_COUNT) +/// Macro converting a hw_key_idx (< @ref MAC_DEFAULT_KEY_COUNT) to the default key id ir corresponds +#define MM_KEY_TO_KEYID(hw_key_idx) ((hw_key_idx) & (MAC_DEFAULT_KEY_COUNT - 1)) +/// RX filter for active mode (i.e. not monitoring) +#ifdef CONFIG_AOS_MESH +#define MM_RX_FILTER_ACTIVE (NXMAC_ACCEPT_MULTICAST_BIT | NXMAC_ACCEPT_BROADCAST_BIT | \ + NXMAC_ACCEPT_MY_UNICAST_BIT | \ + NXMAC_ACCEPT_BEACON_BIT | NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT | \ + NXMAC_ACCEPT_BAR_BIT | NXMAC_ACCEPT_BA_BIT | \ + NXMAC_ACCEPT_DATA_BIT | NXMAC_ACCEPT_Q_DATA_BIT | \ + NXMAC_ACCEPT_QO_S_NULL_BIT | NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT| \ + NXMAC_ACCEPT_OTHER_BSSID_BIT) +#else +#define MM_RX_FILTER_ACTIVE (NXMAC_ACCEPT_MULTICAST_BIT | NXMAC_ACCEPT_BROADCAST_BIT | \ + NXMAC_ACCEPT_MY_UNICAST_BIT | NXMAC_ACCEPT_PROBE_REQ_BIT|\ + NXMAC_ACCEPT_BEACON_BIT | NXMAC_ACCEPT_OTHER_MGMT_FRAMES_BIT | \ + NXMAC_ACCEPT_BAR_BIT | NXMAC_ACCEPT_BA_BIT | \ + NXMAC_ACCEPT_DATA_BIT | NXMAC_ACCEPT_Q_DATA_BIT | \ + NXMAC_ACCEPT_QO_S_NULL_BIT | NXMAC_ACCEPT_OTHER_DATA_FRAMES_BIT) +// bl602 has one moer NXMAC_ACCEPT_PROBE_REQ_BIT +#endif + +/// Number of supported Default+Pairwise keys +#if NX_KEY_RAM_CONFIG +#define MM_SEC_MAX_KEY_NBR ((MAC_CORE->encr_ram_config.max) + 1) +#else +#define MM_SEC_MAX_KEY_NBR 64 +#endif + +static inline void mm_ps_change_ind(uint8_t sta_idx, uint8_t ps_state) { + struct sta_info_tag *sta = sta_info_tab + sta_idx; + + sta->ps_state = ps_state; + struct mm_ps_change_ind *ind = ke_msg_alloc(MM_PS_CHANGE_IND, TASK_API, + TASK_MM, sizeof(struct mm_ps_change_ind)); + + ind->sta_idx = sta_idx; + ind->ps_state = ps_state; + ke_msg_send(ind); +} + +static inline void mm_traffic_req_ind(uint8_t sta_idx, uint8_t pkt_cnt, bool uapsd) { + struct mm_traffic_req_ind *ind = KE_MSG_ALLOC(MM_TRAFFIC_REQ_IND, TASK_API, TASK_MM, mm_traffic_req_ind); + + ind->sta_idx = sta_idx; + ind->pkt_cnt = pkt_cnt; + ind->uapsd = uapsd; + + ke_msg_send(ind); +} + + +#define TASK_IND TASK_SM + +#endif // _MM_H_ diff --git a/src/include/bl602_wifi/lmac/mm/mm_bcn.h b/src/include/bl602_wifi/lmac/mm/mm_bcn.h new file mode 100644 index 0000000..56f5951 --- /dev/null +++ b/src/include/bl602_wifi/lmac/mm/mm_bcn.h @@ -0,0 +1,32 @@ +#ifndef _MM_BCN_H_ +#define _MM_BCN_H_ + +#include + +#include +#include +#include +#include + + +struct mm_bcn_env_tag { + const struct mm_bcn_change_req *param; // +0 + int tx_cfm; // +4 + bool tx_pending; // +8 + bool update_ongoing; // +9 + bool update_pending; // +10 + struct hal_dma_desc_tag dma; // +12 + struct co_list tim_list; // +28 +}; + + +extern struct mm_bcn_env_tag mm_bcn_env; + + +void mm_bcn_init(void); +void mm_bcn_init_vif(struct vif_info_tag *vif_entry); +void mm_bcn_change(const struct mm_bcn_change_req *param); +void mm_tim_update(const struct mm_tim_update_req *param); +void mm_bcn_transmit(void); + +#endif // _MM_BCN_H_ diff --git a/src/include/bl602_wifi/lmac/mm/mm_task.h b/src/include/bl602_wifi/lmac/mm/mm_task.h new file mode 100644 index 0000000..8bc78c5 --- /dev/null +++ b/src/include/bl602_wifi/lmac/mm/mm_task.h @@ -0,0 +1,431 @@ +#ifndef _MM_TASK_H_ +#define _MM_TASK_H_ + +#include +#include + +#include +#include +#include +#include + +#define MM_IDX_MAX 1 + +enum mm_state_tag { + MM_IDLE = 0, + MM_ACTIVE = 1, + MM_GOING_TO_IDLE = 2, + MM_HOST_BYPASSED = 3, + MM_STATE_MAX = 4, +}; + +enum mm_remain_on_channel_op { + MM_ROC_OP_START = 0, + MM_ROC_OP_CANCEL = 1, + MM_ROC_OP_MAX = 2, +}; + +enum mm_msg_tag { + MM_RESET_REQ = 0, + MM_RESET_CFM = 1, + MM_START_REQ = 2, + MM_START_CFM = 3, + MM_VERSION_REQ = 4, + MM_VERSION_CFM = 5, + MM_ADD_IF_REQ = 6, + MM_ADD_IF_CFM = 7, + MM_REMOVE_IF_REQ = 8, + MM_REMOVE_IF_CFM = 9, + MM_STA_ADD_REQ = 10, + MM_STA_ADD_CFM = 11, + MM_STA_DEL_REQ = 12, + MM_STA_DEL_CFM = 13, + MM_SET_FILTER_REQ = 14, + MM_SET_FILTER_CFM = 15, + MM_SET_CHANNEL_REQ = 16, + MM_SET_CHANNEL_CFM = 17, + MM_SET_DTIM_REQ = 18, + MM_SET_DTIM_CFM = 19, + MM_SET_BEACON_INT_REQ = 20, + MM_SET_BEACON_INT_CFM = 21, + MM_SET_BASIC_RATES_REQ = 22, + MM_SET_BASIC_RATES_CFM = 23, + MM_SET_BSSID_REQ = 24, + MM_SET_BSSID_CFM = 25, + MM_SET_EDCA_REQ = 26, + MM_SET_EDCA_CFM = 27, + MM_SET_MODE_REQ = 28, + MM_SET_MODE_CFM = 29, + MM_SET_VIF_STATE_REQ = 30, + MM_SET_VIF_STATE_CFM = 31, + MM_SET_SLOTTIME_REQ = 32, + MM_SET_SLOTTIME_CFM = 33, + MM_SET_IDLE_REQ = 34, + MM_SET_IDLE_CFM = 35, + MM_KEY_ADD_REQ = 36, + MM_KEY_ADD_CFM = 37, + MM_KEY_DEL_REQ = 38, + MM_KEY_DEL_CFM = 39, + MM_BA_ADD_REQ = 40, + MM_BA_ADD_CFM = 41, + MM_BA_DEL_REQ = 42, + MM_BA_DEL_CFM = 43, + MM_PRIMARY_TBTT_IND = 44, + MM_SECONDARY_TBTT_IND = 45, + MM_SET_POWER_REQ = 46, + MM_SET_POWER_CFM = 47, + MM_DENOISE_REQ = 48, + MM_SET_PS_MODE_REQ = 49, + MM_SET_PS_MODE_CFM = 50, + MM_CHAN_CTXT_ADD_REQ = 51, + MM_CHAN_CTXT_ADD_CFM = 52, + MM_CHAN_CTXT_DEL_REQ = 53, + MM_CHAN_CTXT_DEL_CFM = 54, + MM_CHAN_CTXT_LINK_REQ = 55, + MM_CHAN_CTXT_LINK_CFM = 56, + MM_CHAN_CTXT_UNLINK_REQ = 57, + MM_CHAN_CTXT_UNLINK_CFM = 58, + MM_CHAN_CTXT_UPDATE_REQ = 59, + MM_CHAN_CTXT_UPDATE_CFM = 60, + MM_CHAN_CTXT_SCHED_REQ = 61, + MM_CHAN_CTXT_SCHED_CFM = 62, + MM_BCN_CHANGE_REQ = 63, + MM_BCN_CHANGE_CFM = 64, + MM_TIM_UPDATE_REQ = 65, + MM_TIM_UPDATE_CFM = 66, + MM_CONNECTION_LOSS_IND = 67, + MM_CHANNEL_SWITCH_IND = 68, + MM_CHANNEL_PRE_SWITCH_IND = 69, + MM_REMAIN_ON_CHANNEL_REQ = 70, + MM_REMAIN_ON_CHANNEL_CFM = 71, + MM_REMAIN_ON_CHANNEL_EXP_IND = 72, + MM_PS_CHANGE_IND = 73, + MM_TRAFFIC_REQ_IND = 74, + MM_SET_PS_OPTIONS_REQ = 75, + MM_SET_PS_OPTIONS_CFM = 76, + MM_P2P_VIF_PS_CHANGE_IND = 77, + MM_CSA_COUNTER_IND = 78, + MM_CHANNEL_SURVEY_IND = 79, + MM_BFMER_ENABLE_REQ = 80, + MM_SET_P2P_NOA_REQ = 81, + MM_SET_P2P_OPPPS_REQ = 82, + MM_SET_P2P_NOA_CFM = 83, + MM_SET_P2P_OPPPS_CFM = 84, + MM_P2P_NOA_UPD_IND = 85, + MM_CFG_RSSI_REQ = 86, + MM_RSSI_STATUS_IND = 87, + MM_CSA_FINISH_IND = 88, + MM_CSA_TRAFFIC_IND = 89, + MM_MU_GROUP_UPDATE_REQ = 90, + MM_MU_GROUP_UPDATE_CFM = 91, + MM_MONITOR_REQ = 92, + MM_MONITOR_CFM = 93, + MM_MONITOR_CHANNEL_REQ = 94, + MM_MONITOR_CHANNEL_CFM = 95, + MM_FORCE_IDLE_REQ = 96, + MM_SCAN_CHANNEL_START_IND = 97, + MM_SCAN_CHANNEL_END_IND = 98, + MM_MAX = 99, +}; + +#define BCN_MAX_CSA_CPT 2 + +struct mm_monitor_cfm { + uint32_t status; // +0 + uint32_t enable; // +4 + uint32_t data[8]; // +8 +}; + +struct mm_monitor_req { + uint32_t enable; // +0 +}; + +struct mm_monitor_channel_cfm { + uint32_t status; // +0 + uint32_t freq; // +4 + uint32_t data[8]; // +8 +}; + +struct mm_monitor_channel_req { + uint32_t freq; // +0 + uint32_t use_40Mhz; // +4 + uint32_t higher_band; // +8 +}; + +struct mm_start_req { + struct phy_cfg_tag phy_cfg; // +0 + uint32_t uapsd_timeout; // +64 + uint16_t lp_clk_accuracy; // +68 +}; + +struct mm_set_channel_req { + uint8_t band; // +0 + uint8_t type; // +1 + uint16_t prim20_freq; // +2 + uint16_t center1_freq; // +4 + uint16_t center2_freq; // +6 + uint8_t index; // +8 + int8_t tx_power; // +9 +}; + +struct mm_set_channel_cfm { + uint8_t radio_idx; // +0 + int8_t power; // +1 +}; + +struct mm_set_dtim_req { + uint8_t dtim_period; // +0 +}; + +struct mm_set_power_req { + uint8_t inst_nbr; // +0 + int8_t power; // +1 +}; + +struct mm_set_power_cfm { + uint8_t radio_idx; // +0 + int8_t power; // +1 +}; + +struct mm_set_beacon_int_req { + uint16_t beacon_int; // +0 + uint8_t inst_nbr; // +2 +}; + +struct mm_set_basic_rates_req { + uint32_t rates; // +0 + uint8_t inst_nbr; // +4 + uint8_t band; // +5 +}; + +struct mm_set_bssid_req { + struct mac_addr bssid; // +0 + uint8_t inst_nbr; // +6 +}; + +struct mm_set_filter_req { + uint32_t filter; // +0 +}; + +struct mm_add_if_req { + uint8_t type; // +0 + struct mac_addr addr; // +1 + bool p2p; // +7 +}; + +struct mm_set_edca_req { + uint32_t ac_param; // +0 + bool uapsd; // +4 + uint8_t hw_queue; // +5 + uint8_t inst_nbr; // +6 +}; + +struct mm_set_slottime_req { + uint8_t slottime; // +0 +}; + +struct mm_set_mode_req { + uint8_t abgnmode; // +0 +}; + +struct mm_set_vif_state_req { + uint16_t aid; // +0 + bool active; // +2 + uint8_t inst_nbr; // +3 +}; + +struct mm_add_if_cfm { + uint8_t status; // +0 + uint8_t inst_nbr; // +1 +}; + +struct mm_remove_if_req { + uint8_t inst_nbr; // +0 +}; + +struct mm_version_cfm { + uint32_t version_lmac; // +0 + uint32_t version_machw_1; // +4 + uint32_t version_machw_2; // +8 + uint32_t version_phy_1; // +12 + uint32_t version_phy_2; // +16 + uint32_t features; // +20 +}; + +struct mm_sta_add_req { + uint32_t ampdu_size_max_vht; // +0 + uint32_t paid_gid; // +4 + uint16_t ampdu_size_max_ht; // +8 + struct mac_addr mac_addr; // +10 + uint8_t ampdu_spacing_min; // +16 + uint8_t inst_nbr; // +17 + bool tdls_sta; // +18 + int8_t rssi; // +19 + uint32_t tsflo; // +20 + uint32_t tsfhi; // +24 + uint8_t data_rate; // +28 +}; + +struct mm_sta_add_cfm { + uint8_t status; // +0 + uint8_t sta_idx; // +1 + uint8_t hw_sta_idx; // +2 +}; + +struct mm_sta_del_req { + uint8_t sta_idx; // +0 +}; + +struct mm_set_idle_req { + uint8_t hw_idle; // +0 +}; + +struct mm_key_add_req { + uint8_t key_idx; // +0 + uint8_t sta_idx; // +1 + struct mac_sec_key key; // +4 + uint8_t cipher_suite; // +40 + uint8_t inst_nbr; // +41 + uint8_t spp; // +42 + bool pairwise; // +43 +}; + +struct mm_key_add_cfm { + uint8_t status; // +0 + uint8_t hw_key_idx; // +1 +}; +struct mm_key_del_req { + uint8_t hw_key_idx; // +0 +}; + +struct mm_ba_add_req { + uint8_t type; // +0 + uint8_t sta_idx; // +1 + uint8_t tid; // +2 + uint8_t bufsz; // +3 + uint16_t ssn; // +4 +}; + +struct mm_ba_add_cfm { + uint8_t sta_idx; // +0 + uint8_t tid; // +1 + uint8_t status; // +2 +}; + +struct mm_connection_loss_ind { + uint8_t inst_nbr; // +0 +}; + +struct mm_set_ps_mode_req { + uint8_t new_state; // +0 +}; + +struct mm_chan_ctxt_add_req { + uint8_t band; // +0 + uint8_t type; // +1 + uint16_t prim20_freq; // +2 + uint16_t center1_freq; // +4 + uint16_t center2_freq; // +6 + int8_t tx_power; // +8 +}; + +struct mm_chan_ctxt_update_req { + uint8_t chan_index; // +0 + uint8_t band; // +1 + uint8_t type; // +2 + uint16_t prim20_freq; // +4 + uint16_t center1_freq; // +6 + uint16_t center2_freq; // +8 + int8_t tx_power; // +10 +}; + +struct mm_bcn_change_req { + uint32_t bcn_ptr; // +0 + uint16_t bcn_len; // +4 + uint16_t tim_oft; // +6 + uint8_t tim_len; // +8 + uint8_t inst_nbr; // +9 + uint8_t csa_oft[2]; // +10 + uint8_t bcn_buf[0]; // +12 +}; + +struct mm_tim_update_req { + uint16_t aid; // +0 + uint8_t tx_avail; // +2 + uint8_t inst_nbr; // +3 +}; + +struct mm_ps_change_ind { + uint8_t sta_idx; // +0 + uint8_t ps_state; // +1 +}; + +struct mm_traffic_req_ind { + uint8_t sta_idx; // +0 + uint8_t pkt_cnt; // +1 + bool uapsd; // +2 +}; + +struct mm_remain_on_channel_req { + uint8_t op_code; // +0 + uint8_t vif_index; // +1 + uint8_t band; // +2 + uint8_t type; // +3 + uint16_t prim20_freq; // +4 + uint16_t center1_freq; // +6 + uint16_t center2_freq; // +8 + uint32_t duration_ms; // +12 + int8_t tx_power; // +16 +}; + +struct mm_remain_on_channel_cfm { + uint8_t op_code; // +0 + uint8_t status; // +1 + uint8_t chan_ctxt_index; // +2 +}; + +struct mm_set_ps_options_req { + uint8_t vif_index; // +0 + uint16_t listen_interval; // +2 + bool dont_listen_bc_mc; // +4 +}; + +struct mm_csa_counter_ind { + uint8_t vif_index; // +0 + uint8_t csa_count; // +1 +}; + +struct mm_cfg_rssi_req { + uint8_t vif_index; // +0 + int8_t rssi_thold; // +1 + uint8_t rssi_hyst; // +2 +}; + +struct mm_rssi_status_ind { + uint8_t vif_index; // +0 + bool rssi_status; // +1 + int8_t rssi; // +2 +}; + +struct mm_csa_finish_ind { + uint8_t vif_index; // +0 + uint8_t status; // +1 + uint8_t chan_idx; // +2 +}; + +struct mm_csa_traffic_ind { + uint8_t vif_index; // +0 + bool enable; // +1 +}; + +typedef void (*cb_idle_func_ptr)(void); + +struct mm_force_idle_req { + cb_idle_func_ptr cb; // +0 +}; + +extern const struct ke_state_handler mm_state_handler[MM_STATE_MAX]; +extern const struct ke_state_handler mm_default_handler; +extern ke_state_t mm_state[MM_IDX_MAX]; + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/lmac/mm/mm_timer.h b/src/include/bl602_wifi/lmac/mm/mm_timer.h new file mode 100644 index 0000000..48a668c --- /dev/null +++ b/src/include/bl602_wifi/lmac/mm/mm_timer.h @@ -0,0 +1,29 @@ +#ifndef _MM_TIMER_H_ +#define _MM_TIMER_H_ + +#include + +#include + + +typedef void (*cb_timer_func_ptr)(void *); + +struct mm_timer_tag { + struct co_list_hdr list_hdr; // +0 + cb_timer_func_ptr cb; // +4 + void *env; // +8 + uint32_t time; // +12 +}; + +struct mm_timer_env_tag { + struct co_list prog; // +0 +}; + +extern struct mm_timer_env_tag mm_timer_env; + +void mm_timer_init(void); +void mm_timer_set(struct mm_timer_tag *timer, uint32_t value); +void mm_timer_clear(struct mm_timer_tag *timer); +void mm_timer_schedule(int dummy); + +#endif diff --git a/src/include/bl602_wifi/lmac/ps/ps.h b/src/include/bl602_wifi/lmac/ps/ps.h new file mode 100644 index 0000000..68b0b49 --- /dev/null +++ b/src/include/bl602_wifi/lmac/ps/ps.h @@ -0,0 +1,109 @@ +#ifndef _PS_H_ +#define _PS_H_ + +#include +#include + +#include +#include +#include +#include + +#include + +enum ps_dpsm_state_bit_pos { + PS_DPSM_STATE_ON = 0, + PS_DPSM_STATE_PAUSING = 1, + PS_DPSM_STATE_RESUMING = 2, + PS_DPSM_STATE_PAUSE = 3, + PS_DPSM_STATE_SET_MODE_REQ = 4, +}; + +/// Power Save mode setting +enum +{ + /// Power-save off + PS_MODE_OFF, + /// Power-save on - Normal mode + PS_MODE_ON, + /// Power-save on - Dynamic mode + PS_MODE_ON_DYN, + PS_DENOISE, +}; + +struct ps_env_tag { + bool ps_on; // +0 + ke_task_id_t taskid; // +2 + uint32_t prevent_sleep; // +4 + uint8_t cfm_cnt; // +8 + struct mm_timer_tag uapsd_timer; // +12 + bool uapsd_tmr_on; // +28 + bool uapsd_on; // +29 + uint32_t uapsd_timeout; // +32 + uint8_t dpsm_state; // +36 + uint8_t next_mode; // +37 +}; + + +extern struct ps_env_tag ps_env; + +static inline bool ps_uapsd_enabled(void) { + return (ps_env.uapsd_timeout != 0); +} + +static inline bool ps_sleep_check(void) { + // TODO; check if this is correct? + if (!ps_env.ps_on) { + return false; + } + if (ps_env.prevent_sleep) + return false; + for (struct vif_info_tag *cur = (struct vif_info_tag *)co_list_pick(&vif_mgmt_env.used_list); cur; cur = (struct vif_info_tag *)co_list_next(&cur->list_hdr)) { + if (chan_is_on_channel(cur) && cur->prevent_sleep) + return false; // can't sleep + } + return true; // can sleep +} + +void ps_init(void); +void ps_set_mode(uint8_t mode, ke_task_id_t taskid); +void ps_check_beacon(uint32_t tim, uint16_t len, struct vif_info_tag *vif_entry); +void ps_check_frame(uint8_t *frame, uint32_t statinfo, struct vif_info_tag *vif_entry); +void ps_uapsd_set(struct vif_info_tag *vif_entry, uint8_t hw_queue, bool uapsd); +void ps_check_tx_frame(uint8_t staid, uint8_t tid); +void ps_traffic_status_update(uint8_t vif_index, uint8_t new_status); + + +// Definition of bits preventing from going to sleep (per VIF) +/// Station is waiting for beacon reception +#define PS_VIF_WAITING_BCN CO_BIT(0) +/// Station is waiting for broadcast/multicast traffic from AP +#define PS_VIF_WAITING_BCMC CO_BIT(1) +/// Station is waiting for unicast traffic from AP +#define PS_VIF_WAITING_UC CO_BIT(2) +/// Station is waiting for WMM-PS end of service period +#define PS_VIF_WAITING_EOSP CO_BIT(3) +/// Station is waiting for the end of the association procedure +#define PS_VIF_ASSOCIATING CO_BIT(4) +/// P2P GO is supposed to be present +#define PS_VIF_P2P_GO_PRESENT CO_BIT(5) + +// Definition of bits preventing from going to sleep (global) +/// Upload of TX confirmations is ongoing +#define PS_TX_CFM_UPLOADING CO_BIT(0) +/// A scanning process is ongoing +#define PS_SCAN_ONGOING CO_BIT(1) +/// A request for going to IDLE is pending +#define PS_IDLE_REQ_PENDING CO_BIT(2) +/// PSM is paused in order to allow data traffic +#define PS_PSM_PAUSED CO_BIT(3) +/// A CAC period is active +#define PS_CAC_STARTED CO_BIT(4) + +// Station is waiting for data +#define PS_WAITING_ADD_KEY CO_BIT(6) + +/// Mask showing that all ACs UAPSD enabled +#define PS_ALL_UAPSD_ACS 0x0F + +#endif // _PS_H_ diff --git a/src/include/bl602_wifi/lmac/rx/rx_swdesc.h b/src/include/bl602_wifi/lmac/rx/rx_swdesc.h new file mode 100644 index 0000000..d3b451d --- /dev/null +++ b/src/include/bl602_wifi/lmac/rx/rx_swdesc.h @@ -0,0 +1,29 @@ +#ifndef _RX_SWDESC_H_ +#define _RX_SWDESC_H_ + +#include + +#include +#include + + +struct rx_swdesc { + struct co_list_hdr list_hdr; // +0 + struct rx_dmadesc *dma_hdrdesc; // +4 + struct rx_payloaddesc *pd; // +8 + struct rx_pbd *last_pbd; // +12 + struct rx_pbd *spare_pbd; // +16 + uint32_t host_id; // +20 + uint32_t frame_len; // +24 + uint8_t status; // +28 + uint8_t pbd_count; // +29 + uint8_t use_in_tcpip; // +30 +}; + + +extern struct rx_swdesc rx_swdesc_tab[13]; + + +void rx_swdesc_init(void); + +#endif // _RX_SWDESC_H_ diff --git a/src/include/bl602_wifi/lmac/rx/rxl/rxl_cntrl.h b/src/include/bl602_wifi/lmac/rx/rxl/rxl_cntrl.h new file mode 100644 index 0000000..93075f9 --- /dev/null +++ b/src/include/bl602_wifi/lmac/rx/rxl/rxl_cntrl.h @@ -0,0 +1,34 @@ +#ifndef _RXL_CNTRL_H_ +#define _RXL_CNTRL_H_ + +#include + +#include +#include + + +struct rxl_cntrl_env_tag { + struct co_list ready; // +0 + struct rx_dmadesc *first; // +8 + struct rx_dmadesc *last; // +12 + struct rx_dmadesc *free; // +16 + uint32_t packet_stack_cnt; // +20 +}; + + +extern struct rxl_cntrl_env_tag rxl_cntrl_env; + + +void rxl_init(void); +void rxl_reset(void); +void rxl_cntrl_evt(int dummy); +void rxl_timer_int_handler(void); +void rxl_timeout_int_handler(void); +void rxl_mpdu_free(struct rx_swdesc *swdesc); +void rxl_mpdu_transfer(struct rx_swdesc *swdesc); +void rxl_dma_int_handler(void); +void rxl_dma_evt(int dummy); + +/// Threshold of frame upload preparation before which we handle the DMA interrupts +#define RX_FRAME_PREP_THD 4 +#endif // _RXL_CNTRL_H_ diff --git a/src/include/bl602_wifi/lmac/rx/rxl/rxl_hwdesc.h b/src/include/bl602_wifi/lmac/rx/rxl/rxl_hwdesc.h new file mode 100644 index 0000000..8cc023d --- /dev/null +++ b/src/include/bl602_wifi/lmac/rx/rxl/rxl_hwdesc.h @@ -0,0 +1,20 @@ +#ifndef _RXL_HWDESC_H_ +#define _RXL_HWDESC_H_ + +#include + + +struct rxl_hwdesc_env_tag { + struct rx_pbd *last; // +0 + struct rx_pbd *free; // +4 +}; + + +extern struct rxl_hwdesc_env_tag rx_hwdesc_env; + + +void rxl_hwdesc_init(int init); +void rxl_hd_append(struct rx_dmadesc *desc); +void rxl_pd_append(struct rx_pbd *first, struct rx_pbd *last, struct rx_pbd *spare); + +#endif // _RXL_HWDESC_H_ diff --git a/src/include/bl602_wifi/lmac/scan/scan.h b/src/include/bl602_wifi/lmac/scan/scan.h new file mode 100644 index 0000000..5a7db74 --- /dev/null +++ b/src/include/bl602_wifi/lmac/scan/scan.h @@ -0,0 +1,55 @@ +#ifndef _SCAN_H_ +#define _SCAN_H_ + +#include +#include + +#include +#include +#include +#include + + +struct scan_chan_tag { + uint16_t freq; // +0 + uint8_t band; // +2 + uint8_t flags; // +3 + int8_t tx_power; // +4 +}; + +struct scan_probe_req_ie_tag { + struct dma_desc dma_desc; // +0 + struct tx_pbd pbd; // +16 + uint32_t buf[50]; // +36 +}; + +struct scan_start_req; +struct scan_env_tag { + struct hal_dma_desc_tag dma_desc; // +0 + const struct scan_start_req *param; // +16 + uint32_t ds_ie; // +20 + ke_task_id_t req_id; // +24 + uint8_t chan_idx; // +26 + bool abort; // +27 +}; + + +extern struct scan_env_tag scan_env; +extern struct scan_probe_req_ie_tag scan_probe_req_ie; + + +void scan_init(void); +void scan_ie_download(const struct scan_start_req *param); +void scan_set_channel_request(void); +void scan_probe_req_tx(void); +void scan_send_cancel_cfm(uint8_t status, ke_task_id_t dest_id); + +#define SCAN_MAX_IE_LEN 200 + +#define SCAN_PASSIVE_BIT CO_BIT(0) +#define SCAN_DISABLED_BIT CO_BIT(31) + +#define SCAN_ACTIVE_DURATION 90000 +#define SCAN_PASSIVE_DURATION 220000 + +#endif // _SCAN_H_ diff --git a/src/include/bl602_wifi/lmac/scan/scan_task.h b/src/include/bl602_wifi/lmac/scan/scan_task.h new file mode 100644 index 0000000..10c1359 --- /dev/null +++ b/src/include/bl602_wifi/lmac/scan/scan_task.h @@ -0,0 +1,55 @@ +#ifndef _SCAN_TASK_H_ +#define _SCAN_TASK_H_ + +#include +#include + +#include +#include +#include +#include + +#define SCAN_ID_MAX 1 + +enum scan_state_tag { + SCAN_IDLE = 0, + SCAN_WAIT_IE_DWNLD = 1, + SCAN_WAIT_CHANNEL = 2, + SCAN_WAIT_BEACON_PROBE_RSP = 3, + SCAN_STATE_MAX = 4, +}; + +enum scan_msg_tag { + SCAN_START_REQ = 2048, + SCAN_START_CFM = 2049, + SCAN_DONE_IND = 2050, + SCAN_CANCEL_REQ = 2051, + SCAN_CANCEL_CFM = 2052, + SCAN_TIMER = 2053, + SCAN_MAX = 2054, +}; + +struct scan_start_req { + struct scan_chan_tag chan[42]; // +0 + struct mac_ssid ssid[2]; // +252 + struct mac_addr bssid; // +320 + uint32_t add_ies; // +328 + uint16_t add_ie_len; // +332 + uint8_t vif_idx; // +334 + uint8_t chan_cnt; // +335 + uint8_t ssid_cnt; // +336 + bool no_cck; // +337 +}; + +struct scan_start_cfm { + uint8_t status; // +0 +}; + +struct scan_cancel_cfm { + uint8_t status; // +0 +}; + +extern const struct ke_state_handler scan_default_handler; +extern ke_state_t scan_state[SCAN_ID_MAX]; + +#endif // _SCAN_TASK_H_ diff --git a/src/include/bl602_wifi/lmac/sta/sta_mgmt.h b/src/include/bl602_wifi/lmac/sta/sta_mgmt.h new file mode 100644 index 0000000..730d9a7 --- /dev/null +++ b/src/include/bl602_wifi/lmac/sta/sta_mgmt.h @@ -0,0 +1,143 @@ +#ifndef _STA_MGMT_H_ +#define _STA_MGMT_H_ + +#include +#include + +#include +#include + +#include +#include + + +struct vif_info_tag; + +enum sta_mgmt_pol_upd { + STA_MGMT_POL_UPD_RATE = 0, + STA_MGMT_POL_UPD_PROT = 1, + STA_MGMT_POL_UPD_PPDU_TX = 2, + STA_MGMT_POL_UPD_BW = 3, + STA_MGMT_POL_UPD_TX_POWER = 4, + STA_MGMT_POL_UPD_MAX = 5, +}; + +enum sta_ps_traffic { + PS_TRAFFIC_HOST = 1, + PS_TRAFFIC_INT = 2, + PS_TRAFFIC = 3, + UAPSD_TRAFFIC_HOST = 4, + UAPSD_TRAFFIC_INT = 8, + UAPSD_TRAFFIC = 12, +}; + +enum sta_ps_sp { + NO_SERVICE_PERIOD = 0, + PS_SERVICE_PERIOD = 1, + UAPSD_SERVICE_PERIOD_INT = 2, + UAPSD_SERVICE_PERIOD_HOST = 4, + UAPSD_SERVICE_PERIOD = 6, + ANY_SERVICE_PERIOD_INT = 3, + BCN_SERVICE_PERIOD = 8, +}; + +enum { + /// no data traffic could be exchanged with this station + PORT_CLOSED = 0, + /// encryption key is not yet available, only EAP frames could be sent + PORT_CONTROLED, + /// closing status for key is deleted but station is still active + PORT_CLOSING, + /// any data types could be sent + PORT_OPEN +}; + +typedef int sta_ps_sp_t; + +struct sta_mgmt_sec_info { + struct key_info_tag key_info; // +0 + struct key_info_tag *pairwise_key; // +104 + struct key_info_tag **cur_key; // +108 +}; + +struct sta_pol_tbl_cntl { + struct txl_buffer_control *buf_ctrl; // +0 + struct rc_sta_stats *sta_stats; // +4 + uint32_t prot_cfg; // +8 + uint16_t ppdu_tx_cfg; // +12 + uint8_t upd_field; // +14 +}; + +struct sta_mgmt_ba_info { + uint32_t last_tx_time; // +0 + uint32_t last_ba_add_time; // +4 + uint8_t bam_idx_rx; // +8 + uint8_t bam_idx_tx; // +9 + int8_t credit_oft; // +10 +}; + +struct sta_info_tag { + struct co_list_hdr list_hdr; // +0 + uint32_t bcn_int; // +4 + uint32_t ampdu_size_max_vht; // +8 + uint16_t ampdu_size_max_ht; // +12 + uint32_t paid_gid; // +16 + uint8_t ampdu_spacing_min; // +20 + uint16_t drift; // +22 + uint16_t aid; // +24 + uint8_t inst_nbr; // +26 + uint8_t staid; // +27 + uint8_t ps_state; // +28 + bool valid; // +29 + struct mac_addr mac_addr; // +30 + int8_t rssi; // +36 + uint32_t tsflo; // +40 + uint32_t tsfhi; // +44 + uint8_t data_rate; // +48 + uint8_t ctrl_port_state; // +49 + enum sta_ps_traffic traffic_avail; // +50 + sta_ps_sp_t ps_service_period; // +52 + uint16_t ctrl_port_ethertype; // +56 + struct sta_mgmt_sec_info sta_sec_info; // +64 + struct mac_sta_info info; // +176 + uint16_t seq_nbr[TID_MAX]; // +248 + struct sta_pol_tbl_cntl pol_tbl; // +268 + struct sta_mgmt_ba_info ba_info[TID_MAX]; // +284 + uint16_t rx_nqos_last_seqcntl; // +392 + uint16_t rx_qos_last_seqcntl[TID_MAX]; // +394 + struct co_list tx_desc_post; // +412 + void *suppData; // +420 + uint32_t time_last_seen; // +424 +}; + +struct sta_info_env_tag { + struct co_list free_sta_list; // +0 +}; + + +extern struct sta_info_env_tag sta_info_env; +// this is 5, not 12.. IDK why it's 12 in header.. +extern struct sta_info_tag sta_info_tab[STA_MAX]; + + +uint8_t sta_mgmt_get_port_state(uint8_t sta_idx); +uint16_t sta_mgmt_get_port_ethertype(uint8_t sta_idx); +void sta_mgmt_init(void); +uint8_t sta_mgmt_register(const struct mm_sta_add_req *param, uint8_t *sta_idx); +void sta_mgmt_unregister(uint8_t sta_idx); +void sta_mgmt_add_key(const struct mm_key_add_req *param, uint8_t hw_key_idx); +void sta_mgmt_del_key(struct sta_info_tag *sta); +uint16_t sta_mgmt_get_tx_ssn_and_inc(uint8_t sta_idx, uint8_t tid); +struct mac_addr *sta_mgmt_get_peer_addr(uint8_t sta_idx); +uint8_t sta_mgmt_get_vif_idx(uint8_t sta_idx); +int sta_mgmt_send_postponed_frame(struct vif_info_tag *p_vif_entry, struct sta_info_tag *p_sta_entry, int limit); + + +static inline bool sta_mgmt_is_valid(uint8_t sta_idx) { + if (sta_idx >= STA_MAX) + return false; + + return (sta_info_tab[sta_idx].valid); +} + +#endif diff --git a/src/include/bl602_wifi/lmac/td/td.h b/src/include/bl602_wifi/lmac/td/td.h new file mode 100644 index 0000000..327b0ea --- /dev/null +++ b/src/include/bl602_wifi/lmac/td/td.h @@ -0,0 +1,47 @@ +#ifndef _TD_H_ +#define _TD_H_ + +#include +#include + +#include + + +enum td_status_bit { + TD_STATUS_TX = 0, + TD_STATUS_RX = 1, + TD_STATUS_TX_PS = 2, + TD_STATUS_RX_PS = 3, +}; + +struct td_env_tag { + struct mm_timer_tag td_timer; // +0 + uint32_t pck_cnt_tx; // +16 + uint32_t pck_cnt_rx; // +20 + uint32_t pck_cnt_tx_ps; // +24 + uint32_t pck_cnt_rx_ps; // +28 + uint8_t vif_index; // +32 + uint8_t status; // +33 + bool is_on; // +34 + bool has_active_chan; // +35 +}; + +extern struct td_env_tag td_env[NX_VIRT_DEV_MAX]; + +void td_init(void); +void td_reset(uint8_t vif_index); +void td_start(uint8_t vif_index); +void td_pck_ind(uint8_t vif_index, uint8_t sta_index, bool rx); +void td_pck_ps_ind(uint8_t vif_index, bool rx); + +static inline uint8_t td_get_status(uint8_t vif_index) { + return (td_env[vif_index].status & (CO_BIT(TD_STATUS_TX) | CO_BIT(TD_STATUS_RX))); +} + +static inline uint8_t td_get_ps_status(uint8_t vif_index) { + return (td_env[vif_index].status & (CO_BIT(TD_STATUS_TX_PS) | CO_BIT(TD_STATUS_RX_PS))); +} + +#define TD_DEFAULT_INTV_US 1000000 + +#endif // _TD_H_ diff --git a/src/include/bl602_wifi/lmac/tpc/tpc.h b/src/include/bl602_wifi/lmac/tpc/tpc.h new file mode 100644 index 0000000..49cd846 --- /dev/null +++ b/src/include/bl602_wifi/lmac/tpc/tpc.h @@ -0,0 +1,69 @@ +#ifndef _TPC_H_ +#define _TPC_H_ + +#include + +#include + +/** + ****************************************************************************** + * @defgroup TPC TPC + * @ingroup TX + * @brief LMAC Transmit Power Control module. + * @{ + ****************************************************************************** + */ + +/** + * @brief Set power level to be used for HW generated frame. + * + * Configure NXMAC_MAX_POWER_LEVEL register with the specified Tx power by + * converting it to a radio idx first. + * + * @param[in] pwr TX power (in dBm) + */ +void tpc_update_tx_power(int8_t pwr); + +/** + * @brief Get TX power for a VIF + * + * Return the TX power to use on the vif, taking into account all constraint + * + * @param[in] vif Pointer on vif structure to update + * + * @return The idx to use in policy table to configure TX power for this vif. + */ +uint8_t tpc_get_vif_tx_power(struct vif_info_tag *vif); +uint8_t tpc_get_vif_tx_power_vs_rate(uint32_t rate_config); + +/** + * @brief Configure TX power for a specific vif + * + * Configure a TX power for a vif, and returned the actual power set (if request + * is not possible) and the corresponding radio index (to be set in policy table) + * + * @param[in/out] vif Pointer on vif structure to update + * @param[in/out] pwr Tx power to set for the vif (updated with the actual TX + * power set) + * @param[out] idx Radio idx corresponding to the TX power set + */ +void tpc_update_vif_tx_power(struct vif_info_tag *vif, int8_t *pwr, uint8_t *idx); + + +//#if NX_TX_FRAME +/** + * @brief Set power level to be used for FW generated frame. + * + * Update tx power in policy table used by the frame. + * + * @param[in] vif Pointer on vif that send the frame + * @param[in] frame Pointer on frame to be sent + */ +void tpc_update_frame_tx_power(struct vif_info_tag *vif, + struct txl_frame_desc_tag *frame); +//#endif /* NX_TX_FRAME */ + +/** + * @} + */ +#endif // _TPC_H_ diff --git a/src/include/bl602_wifi/lmac/tx/tx_swdesc.h b/src/include/bl602_wifi/lmac/tx/tx_swdesc.h new file mode 100644 index 0000000..3c8fcae --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/tx_swdesc.h @@ -0,0 +1,75 @@ +#ifndef _TX_SWDESC_H_ +#define _TX_SWDESC_H_ + +#include +#include + +#include +#include +#include + + +struct hostdesc { + uint32_t pbuf_addr; // +0 + uint32_t packet_addr; // +4 + uint16_t packet_len; // +8 + uint32_t status_addr; // +12 + struct mac_addr eth_dest_addr; // +16 + struct mac_addr eth_src_addr; // +22 + uint16_t ethertype; // +28 + uint16_t pn[4]; // +30 + uint16_t sn; // +38 + uint16_t timestamp; // +40 + uint8_t tid; // +42 + uint8_t vif_idx; // +43 + uint8_t staid; // +44 + uint16_t flags; // +46 + uint32_t pbuf_chained_ptr[4]; // +48 + uint32_t pbuf_chained_len[4]; // +64 +}; + +struct umacdesc { + struct txl_buffer_control *buf_control; // +0 + uint32_t buff_offset; // +4 + uint16_t payl_len; // +8 + uint8_t head_len; // +10 + uint8_t hdr_len_802_2; // +11 + uint8_t tail_len; // +12 +}; + +struct lmacdesc { + struct tx_agg_desc *agg_desc; // +0 + struct txl_buffer_tag *buffer; // +4 + struct tx_hw_desc *hw_desc; // +8 +}; + +struct txdesc { + struct co_list_hdr list_hdr; // +0 + struct hostdesc host; // +4 + struct umacdesc umac; // +84 + struct lmacdesc lmac; // +100 + struct tx_hw_desc hw_desc; // +112 + struct tx_cfm_tag hw_cfm; // +184 + uint32_t buf[0]; // +204 +}; + +struct txdesc_host { + uint32_t ready; // +0 + struct hostdesc host; // +4 + uint32_t pad_txdesc[55]; // +84 + uint32_t pad_buf[128]; // +304 +}; + + +extern struct txdesc *txdesc_array; +extern const int nx_txdesc_cnt[5]; + + +static inline bool is_int_frame(struct txdesc *txdesc) { + return txdesc->host.packet_addr == 0; +} +static inline bool is_qos_data(struct txdesc *txdesc) { + return txdesc->host.tid != 0xFF; +} + +#endif diff --git a/src/include/bl602_wifi/lmac/tx/txl/txl_buffer.h b/src/include/bl602_wifi/lmac/tx/txl/txl_buffer.h new file mode 100644 index 0000000..a6a4c1d --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/txl/txl_buffer.h @@ -0,0 +1,95 @@ +#ifndef _TXL_BUFFER_H_ +#define _TXL_BUFFER_H_ + +#include + +#include +#include + +#include + + +struct txl_buffer_hw_desc_tag { + struct dma_desc dma_desc; // +0 + struct tx_pbd pbd; // +16 +}; + +struct txl_buffer_list_tag { + struct txl_buffer_tag *first; // +0 + struct txl_buffer_tag *last; // +4 +}; + +struct txl_buffer_idx_tag { + uint32_t used_area; // +0 + uint32_t free; // +4 + uint32_t free_size; // +8 + uint32_t last; // +12 + uint32_t next_needed; // +16 + uint32_t buf_size; // +20 + uint32_t *pool; // +24 + struct txl_buffer_hw_desc_tag *desc; // +28 + uint8_t count; // +32 +}; + +struct txl_buffer_control { + union { + struct tx_policy_tbl policy_tbl; + struct tx_compressed_policy_tbl comp_pol_tbl; + }; // +0 + uint32_t mac_control_info; // +52 + uint32_t phy_control_info; // +56 +}; + +struct txl_buffer_env_tag { + struct txl_buffer_idx_tag buf_idx[5]; // +0 + struct txl_buffer_list_tag list[5]; // +180 +}; + +struct txl_buffer_tag { + uint32_t length; // +0 + uint32_t lenheader; // +4 + uint32_t lenpad; // +8 + uint32_t flags; // +12 + struct txl_buffer_tag *next; // +16 + struct txdesc *txdesc; // +20 + struct dma_desc dma_desc[1]; // +24 + struct dma_desc dma_desc_pat; // +40 + struct tx_pbd tbd; // +56 + struct tx_pbd tbd_body[8]; // +76 + uint8_t user_idx; // +236 + struct txl_buffer_control buffer_control; // +240 + struct tx_pbd tkip_mic_icv_pbd; // +300 + uint8_t tkip_mic_icv[12]; // +320 + uint32_t payload[0]; // +332 +}; + +extern struct txl_buffer_env_tag txl_buffer_env; +extern struct txl_buffer_control txl_buffer_control_desc[NX_REMOTE_STA_MAX]; // this should be 3... instead of 10 +extern struct txl_buffer_control txl_buffer_control_desc_bcmc[NX_VIRT_DEV_MAX]; + +static inline void txl_buffer_push(uint8_t access_category, struct txl_buffer_tag *buf) { + struct txl_buffer_list_tag *list = &txl_buffer_env.list[access_category]; + if (!list->first) { + list->first = buf; + } else { + list->last->next = buf; + } + list->last = buf; + buf->next = NULL; +} +//struct txl_buffer_tag *txl_buffer_pop(uint8_t access_category); +static inline struct txl_buffer_tag *txl_buffer_get(struct txdesc *txdesc) { + return txdesc->lmac.buffer; +} + +//struct txl_buffer_control *txl_buffer_control_get(struct txdesc *txdesc); +// void *txl_buffer_payload_get(struct txdesc *txdesc); +//void txl_buffer_control_copy(struct txdesc *txdesc, struct txl_buffer_tag *buf); +//void txl_buffer_mic_compute(struct txdesc *txdesc, uint32_t *mic_key, uint32_t start, uint32_t len, uint8_t access_category); +void txl_buffer_init(void); +void txl_buffer_reinit(void); +void txl_buffer_reset(void); +struct txl_buffer_tag *txl_buffer_alloc(struct txdesc *txdesc, uint8_t access_category, uint8_t user_idx); +void txl_buffer_update_thd(struct txdesc *txdesc); + +#endif diff --git a/src/include/bl602_wifi/lmac/tx/txl/txl_cfm.h b/src/include/bl602_wifi/lmac/tx/txl/txl_cfm.h new file mode 100644 index 0000000..1386de1 --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/txl/txl_cfm.h @@ -0,0 +1,24 @@ +#ifndef _TXL_CFM_H_ +#define _TXL_CFM_H_ + +#include + +#include +#include + + +extern const uint32_t txl_cfm_evt_bit[5]; + +struct txl_cfm_env_tag { + struct co_list cfmlist[5]; // +0 +}; + +extern struct txl_cfm_env_tag txl_cfm_env; + + +void txl_cfm_init(void); +void txl_cfm_push(struct txdesc *txdesc, uint32_t status, uint8_t access_category); +void txl_cfm_flush(uint8_t access_category, struct co_list *list, uint32_t status); +void txl_cfm_evt(int access_category); + +#endif // _TXL_CFM_H_ diff --git a/src/include/bl602_wifi/lmac/tx/txl/txl_cntrl.h b/src/include/bl602_wifi/lmac/tx/txl/txl_cntrl.h new file mode 100644 index 0000000..a8314b5 --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/txl/txl_cntrl.h @@ -0,0 +1,88 @@ +#ifndef _TXL_CNTRL_H_ +#define _TXL_CNTRL_H_ + +#include +#include + +#include +#include +#include + +#include +#include + + +/// Tx trigger descriptor status check states +enum +{ + /// State for checking MPDU THD done status + THD_CHK_STATE, + /// State for checking BAR THD done status + ATHD_CHK_STATE, +}; + + +struct txl_list { + struct tx_hd *last_frame_exch; // +0 + struct co_list transmitting; // +4 + uint16_t bridgedmacnt; // +12 + uint8_t chk_state; // +14 +}; + +struct txl_cntrl_env_tag { + struct txl_list txlist[5]; // +0 + uint32_t pck_cnt; // +80 + uint16_t seqnbr; // +84 + bool reset; // +86 +}; + + +extern const uint32_t txl_prep_evt_bit[5]; +extern struct txl_cntrl_env_tag txl_cntrl_env; + + +bool txl_sleep_check(void); +void txl_cntrl_init(void); +void txl_reset(void); +bool txl_cntrl_tx_check(struct vif_info_tag *p_vif_entry); +bool txl_cntrl_push(struct txdesc *txdesc, uint8_t access_category); +bool txl_cntrl_push_int(struct txdesc *txdesc, uint8_t access_category); +bool txl_cntrl_push_int_force(struct txdesc *txdesc, uint8_t access_category); +void txl_cntrl_halt_ac(uint8_t access_category); +void txl_cntrl_flush_ac(uint8_t access_category, uint32_t status); +void txl_cntrl_clear_bcn_ac(void); +void txl_cntrl_clear_all_ac(void); +void txl_cntrl_inc_pck_cnt(void); +void txl_payload_handle(void); +void txl_transmit_trigger(void); + +/* + * DEFINES + **************************************************************************************** + */ +/// AC0 queue timeout +#define TX_AC0_TIMEOUT 200000 +/// AC1 queue timeout +#define TX_AC1_TIMEOUT 2000000 +/// AC2 queue timeout +#define TX_AC2_TIMEOUT 400000 +/// AC3 queue timeout +#define TX_AC3_TIMEOUT 200000 +/// BCN queue timeout +#define TX_BCN_TIMEOUT 50000 + +/// Conversion from Access Category to corresponding TX timer +#define TX_AC2TIMER(ac) ((ac) + HAL_AC0_TIMER) + +/// Index of the beacon queue +#define AC_BCN AC_MAX + +#define TX_NTX_2_ANTENNA_SET(ntx) ((CO_BIT((ntx) + 1) - 1) << ANTENNA_SET_PT_OFT) + +static inline uint16_t txl_get_seq_ctrl(void) { + txl_cntrl_env.seqnbr++; + + return (txl_cntrl_env.seqnbr << MAC_SEQCTRL_NUM_OFT); +} + +#endif diff --git a/src/include/bl602_wifi/lmac/tx/txl/txl_frame.h b/src/include/bl602_wifi/lmac/tx/txl/txl_frame.h new file mode 100644 index 0000000..4b21dbc --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/txl/txl_frame.h @@ -0,0 +1,134 @@ +#ifndef _TXL_FRAME_H_ +#define _TXL_FRAME_H_ + +#include +#include + +#include +#include +#include + +#include + +#include + +enum +{ + /// Default TX parameters for 2.4GHz - 1Mbps, no protection + TX_DEFAULT_24G, + /// Default TX parameters for 5GHz - 6Mbps, no protection + TX_DEFAULT_5G, + /// Default TX parameters for NDPA and BRP transmissions + TX_DEFAULT_NDPA_BRP, + /// Default TX parameters for NDP transmissions + TX_DEFAULT_NDP, + /// Custom TX parameters + TX_CUSTOM +}; + +/// Type of frame descriptor +enum { + /// Internal frame descriptor, i.e part of the generic frame module + TX_INT, + /// External frame descriptor + TX_EXT +}; + +typedef void (*cfm_func_ptr)(void *, uint32_t); + +struct txl_frame_cfm_tag { + cfm_func_ptr cfm_func; // +0 + void *env; // +4 +}; + +struct txl_frame_desc_tag { + struct txdesc txdesc; // +0 + struct txl_frame_cfm_tag cfm; // +204 +716 + uint8_t type; // +212 + bool postponed; // +213 + bool keep_desc; // +214 +}; + +struct txl_frame_env_tag { + struct co_list desc_free; // +0 + struct co_list desc_done; // +8 +}; + +extern struct txl_frame_env_tag txl_frame_env; + +/// TX frame buffer pool +// (332 + NX_TXFRAME_LEN) / 4 == 147 +// NX_TXFRAME_LEN == 256 +extern uint32_t txl_frame_pool[NX_TXFRAME_CNT][(sizeof(struct txl_buffer_tag) + NX_TXFRAME_LEN) / 4]; + +#if NX_BCN_AUTONOMOUS_TX +/// Pool of TIM IE buffers +// extern uint32_t txl_tim_ie_pool[NX_VIRT_DEV_MAX][CO_ALIGN4_HI(MAC_TIM_BMP_OFT + 1)/4]; +/// Pool of TIM virtual bitmap +// extern uint32_t txl_tim_bitmap_pool[NX_VIRT_DEV_MAX][CO_ALIGN4_HI(MAC_TIM_SIZE)/4]; + +/// TODO: this could be a pool +extern uint8_t txl_tim_ie_pool[CO_ALIGN4_HI(MAC_TIM_BMP_OFT + 1)]; +extern uint8_t txl_tim_bitmap_pool[CO_ALIGN4_HI(MAC_TIM_SIZE)]; + +/// Pool of TIM descriptors +//extern struct tx_pbd txl_tim_desc[NX_VIRT_DEV_MAX][2]; +/// TODO: this could also be a pool? +extern struct tx_pbd txl_tim_desc[2]; + +/// Beacon buffer pool +// 211 == (332 + NX_BCNFRAME_LEN) / 4 +// extern uint32_t txl_bcn_pool[NX_VIRT_DEV_MAX][(sizeof(struct txl_buffer_tag) + NX_BCNFRAME_LEN) / 4]; +/// TODO: this could also be a pool? +extern uint8_t txl_bcn_pool[(sizeof(struct txl_buffer_tag) + NX_BCNFRAME_LEN)]; +/// TX beacon header descriptor pool +/// TODO: and many of the following?? +//extern struct tx_hw_desc txl_bcn_hwdesc_pool[NX_VIRT_DEV_MAX]; +extern struct tx_hw_desc txl_bcn_hwdesc_pool; +/// TX payload buffer descriptor for the post-TIM part of the beacon +//extern struct tx_pbd txl_bcn_end_desc[NX_VIRT_DEV_MAX]; +extern struct tx_pbd txl_bcn_end_desc; +//extern struct txl_buffer_control txl_bcn_buf_ctrl[NX_VIRT_DEV_MAX]; +extern struct txl_buffer_control txl_bcn_buf_ctrl; + +#if (NX_P2P_GO) +/// Pool of P2P NOA payload descriptors +extern struct tx_pbd txl_p2p_noa_desc[NX_VIRT_DEV_MAX]; +/// Pool of P2P NOA Attributes +extern uint16_t txl_p2p_noa_ie_pool[NX_VIRT_DEV_MAX][P2P_NOA_IE_BUFFER_LEN]; +#endif //(NX_P2P_GO) + +#if (RW_MESH_EN) +// Payload Descriptor for additional IEs of Mesh Beacon +extern struct tx_pbd txl_mesh_add_ies_desc[RW_MESH_VIF_NB]; +// Buffer containing the additional IEs of Mesh Beacon +extern struct mesh_add_ies_tag txl_mesh_add_ies[RW_MESH_VIF_NB]; +#endif //(RW_MESH_EN) +#endif //(NX_BCN_AUTONOMOUS_TX) + +/// TX frame header descriptor pool +extern struct tx_hw_desc txl_frame_hwdesc_pool[NX_TXFRAME_CNT]; + +/// Default policy table for 2.4GHz band +extern struct txl_buffer_control txl_buffer_control_24G; + +extern struct txl_buffer_control txl_frame_buf_ctrl[NX_TXFRAME_CNT]; +extern struct tx_cfm_tag txl_bcn_hwdesc_cfms[NX_VIRT_DEV_MAX]; + +extern struct tx_cfm_tag txl_frame_hwdesc_cfms[NX_TXFRAME_CNT]; + +extern struct txl_buffer_control txl_frame_buf_ctrl[NX_TXFRAME_CNT]; + +void txl_frame_init(bool reset); +void txl_frame_init_desc(struct txl_frame_desc_tag *frame, struct txl_buffer_tag *buffer, struct tx_hw_desc *hwdesc, struct txl_buffer_control *bufctrl); +struct txl_frame_desc_tag *txl_frame_get(int type, int len); +bool txl_frame_push(struct txl_frame_desc_tag *frame, uint8_t ac); +bool txl_frame_push_force(struct txl_frame_desc_tag *frame, uint8_t ac); +void txl_frame_cfm(struct txdesc *txdesc); +void txl_frame_release(struct txdesc *txdesc, bool postponed); +void txl_frame_evt(int dummy); +uint8_t txl_frame_send_null_frame(uint8_t sta_idx, cfm_func_ptr cfm, void *env); +uint8_t txl_frame_send_qosnull_frame(uint8_t sta_idx, uint16_t qos, cfm_func_ptr cfm, void *env); +uint8_t txl_frame_send_eapol_frame(uint8_t sta_idx, cfm_func_ptr cfm, void *cfm_env, uint8_t *pBuf, uint32_t pBuf_len); + +#endif diff --git a/src/include/bl602_wifi/lmac/tx/txl/txl_hwdesc.h b/src/include/bl602_wifi/lmac/tx/txl/txl_hwdesc.h new file mode 100644 index 0000000..12d1bc8 --- /dev/null +++ b/src/include/bl602_wifi/lmac/tx/txl/txl_hwdesc.h @@ -0,0 +1,7 @@ +#ifndef _TXL_HWDESC_H_ +#define _TXL_HWDESC_H_ + +void txl_hwdesc_init(void); +void txl_hwdesc_reset(void); + +#endif diff --git a/src/include/bl602_wifi/lmac/vif/vif_mgmt.h b/src/include/bl602_wifi/lmac/vif/vif_mgmt.h new file mode 100644 index 0000000..c021fc0 --- /dev/null +++ b/src/include/bl602_wifi/lmac/vif/vif_mgmt.h @@ -0,0 +1,150 @@ +#ifndef _VIF_MGMT_H_ +#define _VIF_MGMT_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +enum VIF_AP_BCMC_STATUS { + VIF_AP_BCMC_BUFFERED = 1, + VIF_AP_BCMC_MOREDATA = 2, +}; + +struct vif_info_tag { + struct co_list_hdr list_hdr; // +0 + uint32_t prevent_sleep; // +4 + uint32_t txq_params[4]; // +8 + struct mm_timer_tag tbtt_timer; // +24 + struct mm_timer_tag tmr_bcn_to; // +40 + struct mac_addr bssid; // +56 + struct chan_ctxt_tag *chan_ctxt; // +64 + struct chan_tbtt_tag tbtt_switch; // +68 + struct mac_addr mac_addr; // +80 + /// Type of the interface (@ref VIF_STA, @ref VIF_IBSS, @ref VIF_MESH_POINT or @ref VIF_AP) + uint8_t type; // +86 + uint8_t index; // +87 + bool active; // +88 + int8_t tx_power; // +89 + int8_t user_tx_power; // +90 + union { + struct { + uint16_t listen_interval; // +0 + bool dont_wait_bcmc; // +2 + uint8_t ps_retry; // +3 + uint8_t ap_id; // +4 + uint32_t uapsd_last_rxtx; // +8 + uint8_t uapsd_queues; // +12 + uint32_t mon_last_tx; // +16 + uint32_t mon_last_crc; // +20 + uint8_t beacon_loss_cnt; // +24 + int8_t rssi; // +25 + int8_t rssi_thold; // +26 + uint8_t rssi_hyst; // +27 + bool rssi_status; // +28 + uint8_t csa_count; // +29 + bool csa_occured; // +30 + } sta; + struct { + uint32_t dummy; // +0 + struct txl_frame_desc_tag bcn_desc; // +4 + uint16_t bcn_len; // +220 + uint16_t tim_len; // +222 + uint16_t tim_bitmap_set; // +224 + uint16_t bcn_int; // +226 + uint8_t bcn_tbtt_ratio; // +228 + uint8_t bcn_tbtt_cnt; // +229 + bool bcn_configured; // +230 + uint8_t dtim_count; // +231 + uint8_t tim_n1; // +232 + uint8_t tim_n2; // +233 + uint8_t bc_mc_status; // +234 + uint8_t csa_count; // +235 + uint8_t csa_oft[2]; // +236 + uint8_t ps_sta_cnt; // +238 + uint16_t ctrl_port_ethertype; // +240 + } ap; + } u; // +92 + struct co_list sta_list; // +336 + struct mac_bss_info bss_info; // +344 + struct key_info_tag key_info[4]; // +544 + struct key_info_tag *default_key; // +960 + uint32_t flags; // +964 + struct mm_chan_ctxt_add_req csa_channel; // +968 +}; + +struct vif_mgmt_env_tag { + struct co_list free_list; // +0 + struct co_list used_list; // +8 + uint8_t vif_sta_cnt; // +16 + uint8_t vif_ap_cnt; // +17 + uint8_t low_bcn_int_idx; // +18 +}; + + +extern struct vif_mgmt_env_tag vif_mgmt_env; +extern struct vif_info_tag vif_info_tab[NX_VIRT_DEV_MAX]; + + +void vif_mgmt_init(void); +void vif_mgmt_reset(void); +uint8_t vif_mgmt_register(const struct mac_addr *mac_addr, uint8_t vif_type, bool p2p, uint8_t *vif_idx); +void vif_mgmt_unregister(uint8_t vif_idx); +void vif_mgmt_add_key(const struct mm_key_add_req *param, uint8_t hw_key_idx); +void vif_mgmt_del_key(struct vif_info_tag *vif, uint8_t keyid); +void vif_mgmt_send_postponed_frame(struct vif_info_tag *p_vif_entry); +void vif_mgmt_bcn_to_prog(struct vif_info_tag *p_vif_entry); +void vif_mgmt_bcn_recv(struct vif_info_tag *p_vif_entry); +void vif_mgmt_set_ap_bcn_int(struct vif_info_tag *p_vif_entry, uint16_t bcn_int); +void vif_mgmt_switch_channel(struct vif_info_tag *p_vif_entry); +struct vif_info_tag *vif_mgmt_get_first_ap_inf(void); + +static inline int vif_mgmt_used_cnt(void) { + return vif_mgmt_env.vif_ap_cnt + vif_mgmt_env.vif_sta_cnt; +} + +static inline struct vif_info_tag *vif_mgmt_first_used(void) { + return (struct vif_info_tag *) co_list_pick(&vif_mgmt_env.used_list); +} + +static inline struct vif_info_tag *vif_mgmt_next(struct vif_info_tag *vif_entry) { + return (struct vif_info_tag *) co_list_next(&vif_entry->list_hdr); +} + +static inline uint8_t vif_mgmt_get_type(uint8_t vif_idx) { + return vif_info_tab[vif_idx].type; +} + +static inline struct mac_addr *vif_mgmt_get_addr(uint8_t vif_idx) { + return &vif_info_tab[vif_idx].mac_addr; +} + +enum { + /// ESS STA interface + VIF_STA, + /// IBSS STA interface + VIF_IBSS, + /// AP interface + VIF_AP, + /// Mesh Point interface + VIF_MESH_POINT, + /// Unknown type + VIF_UNKNOWN +}; + +/// Macro defining an invalid VIF index +#define INVALID_VIF_IDX 0xFF + +/// Macro defining an unknown tx power +#define VIF_UNDEF_POWER 0x7F + +#define VIF_MGMT_BCN_TO_DUR (10000) + +#endif // __VIF_MGMT_H__ diff --git a/src/include/bl602_wifi/modules/common/co_dlist.h b/src/include/bl602_wifi/modules/common/co_dlist.h new file mode 100644 index 0000000..f89d6e0 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_dlist.h @@ -0,0 +1,22 @@ +#ifndef _CO_DLIST_H_ +#define _CO_DLIST_H_ + +#include +#include + + +struct co_dlist_hdr { + struct co_dlist_hdr *next; // +0 + struct co_dlist_hdr *prev; // +4 +}; + +struct co_dlist { + struct co_dlist_hdr *first; // +0 + struct co_dlist_hdr *last; // +4 + uint32_t cnt; // +8 +}; + + +bool co_dlist_is_empty(const struct co_dlist *list); + +#endif // _CO_DLIST_H_ diff --git a/src/include/bl602_wifi/modules/common/co_endian.h b/src/include/bl602_wifi/modules/common/co_endian.h new file mode 100644 index 0000000..df49357 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_endian.h @@ -0,0 +1,57 @@ +#ifndef _CO_ENDIAN_H_ +#define _CO_ENDIAN_H_ + +#include +#include + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define LE 1 +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define BE 1 +#else +// RISCV is always little endian, so we can use this as a default +#define LE 1 +#endif + +#define co_bswap16(val) __builtin_bswap16(val) +#define co_bswap32(val) __builtin_bswap32(val) + +static inline uint16_t co_htons(uint16_t hostshort) { +#if BE + return hostshort; +#elif LE + return co_bswap16(hostshort); +#else + STATIC_ASSERT(0, unknown_endian); +#endif +} + +static inline uint32_t co_htowl(uint32_t hostlong) { +#if LE + return hostshort; +#elif BE + return co_bswap32(hostshort); +#else + STATIC_ASSERT(0, unknown_endian); +#endif +} + +static inline uint16_t co_htows(uint16_t hostshort) { +#if LE + return hostshort; +#elif BE + return co_bswap16(hostshort); +#else + STATIC_ASSERT(0, unknown_endian); +#endif +} + +static inline uint16_t co_ntohs(uint16_t netshort) { + return co_htons(netshort); +} + +static inline uint16_t co_wtohs(uint16_t wlanshort) { + return co_htows(wlanshort); +} + +#endif // _CO_ENDIAN_H_ diff --git a/src/include/bl602_wifi/modules/common/co_list.h b/src/include/bl602_wifi/modules/common/co_list.h new file mode 100644 index 0000000..12e1d22 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_list.h @@ -0,0 +1,42 @@ +#ifndef _CO_LIST_H_ +#define _CO_LIST_H_ + +#include +#include +#include + +struct co_list_hdr { + struct co_list_hdr *next; // +0 +}; // :47:8 + +struct co_list { + struct co_list_hdr *first; // +0 + struct co_list_hdr *last; // +4 +}; // :54:8 + + +void co_list_init(struct co_list *list); +void co_list_push_back(struct co_list *list, struct co_list_hdr *list_hdr); +struct co_list_hdr *co_list_pop_front(struct co_list *list); +void co_list_extract(struct co_list *list, struct co_list_hdr *list_hdr); +void co_list_insert(struct co_list *const list, struct co_list_hdr *const element, bool (*cmp)(const struct co_list_hdr*, const struct co_list_hdr*)); +void co_list_insert_after(struct co_list *const list, struct co_list_hdr *const prev_element, struct co_list_hdr* const element); +void co_list_insert_before(struct co_list *const list, struct co_list_hdr *const next_element, struct co_list_hdr* const element); +void co_list_remove(struct co_list *list, struct co_list_hdr *prev_element, struct co_list_hdr *element); +void co_list_concat(struct co_list *list1, struct co_list *list2); +bool co_list_find(struct co_list *list, struct co_list_hdr *list_hdr); +uint32_t co_list_cnt(const struct co_list *const list); + +static inline struct co_list_hdr* co_list_pick(struct co_list const* const list) { + return list->first; +} + +static inline struct co_list_hdr* co_list_next(struct co_list_hdr const* const list_hdr) { + return list_hdr->next; +} + +static inline bool co_list_is_empty(const struct co_list *const list) { + return list->first == NULL; +} + +#endif // _CO_LIST_H_ diff --git a/src/include/bl602_wifi/modules/common/co_math.h b/src/include/bl602_wifi/modules/common/co_math.h new file mode 100644 index 0000000..92b5f74 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_math.h @@ -0,0 +1,44 @@ +#ifndef _CO_MATH_H_ +#define _CO_MATH_H_ + +#include + + +static inline uint32_t co_clz(uint32_t val) { return __builtin_clz(val); }; + +extern long unsigned int next; + +static inline int mini_rand(void) { + next = next * 0x41c64e6d + 0x3039; + return next >> 0x10; +} + +static inline uint16_t co_rand_hword(void) { + return mini_rand() & 0xffff; +} + +static inline uint32_t co_rand_word(void) { + /// TODO: this is not a good random number generator + /// as it only generate 16 bits of randomness + /// and very insecure.. + /// but we will see.. + return mini_rand(); +} + +static inline uint32_t co_min(uint32_t a, uint32_t b) { + return (ab)?a:b; +} + +uint32_t co_crc32(uint32_t addr, uint32_t len, uint32_t crc); + +#define CO_BIT(x) (1UL<<(x)) +#define CO_ALIGN4_HI(x) (((x) + 3ul) & ~3ul) +#define CO_ALIGN4_LO(x) ((x) & ~3ul) +#define CO_ALIGN2_HI(x) (((x) + 1ul) & ~ 1ul) +#define CO_ALIGN2_LO(x) ((x) & ~1ul) + +#endif // _CO_MATH_H_ diff --git a/src/include/bl602_wifi/modules/common/co_pool.h b/src/include/bl602_wifi/modules/common/co_pool.h new file mode 100644 index 0000000..deaf910 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_pool.h @@ -0,0 +1,17 @@ +#ifndef _CO_POOL_H_ +#define _CO_POOL_H_ + +#include + + +struct co_pool_hdr { + struct co_pool_hdr *next; // +0 + void *element; // +4 +}; + +struct co_pool { + struct co_pool_hdr *first_ptr; // +0 + uint32_t freecnt; // +4 +}; + +#endif // _CO_POOL_H_ diff --git a/src/include/bl602_wifi/modules/common/co_status.h b/src/include/bl602_wifi/modules/common/co_status.h new file mode 100644 index 0000000..6fd3dfb --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_status.h @@ -0,0 +1,34 @@ +#ifndef _CO_STATUS_H_ +#define _CO_STATUS_H_ +/* + * DEFINITIONS + **************************************************************************************** + */ +/// Status/error codes used in the MAC software. +enum +{ + /// Successful + CO_OK, + /// Unuccessful + CO_FAIL, + /// Empty + CO_EMPTY, + /// Full + CO_FULL, + /// Bad parameters supplied + CO_BAD_PARAM, + /// Element not found + CO_NOT_FOUND, + /// No more element available + CO_NO_MORE_ELT_AVAILABLE, + /// No element currently in use + CO_NO_ELT_IN_USE, + /// Busy + CO_BUSY, + /// Operation already in progress + CO_OP_IN_PROGRESS, +}; + +/// @} +#endif + diff --git a/src/include/bl602_wifi/modules/common/co_utils.h b/src/include/bl602_wifi/modules/common/co_utils.h new file mode 100644 index 0000000..23a45de --- /dev/null +++ b/src/include/bl602_wifi/modules/common/co_utils.h @@ -0,0 +1,110 @@ +#ifndef _CO_UTILS_H_ +#define _CO_UTILS_H_ + +#include +#include + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +static inline uint16_t co_read16(const void *ptr16) { + return *((uint16_t*)ptr16); +} + +static inline void co_write16(const void *ptr16, uint32_t value) { + *((uint16_t*)ptr16) = value; +} + +static inline void co_copy32(uint32_t *dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; i += 4) { + *(dst + (i/4)) = *(src + (i/4)); + } +} + +static inline uint8_t co_read8p(uint32_t addr) { + return *((uint8_t*)addr); +} + +static inline void co_write8p(uint32_t addr, uint8_t value) { + *((uint8_t*)addr) = value; +} + +static inline uint16_t co_read16p(uint32_t addr) { + return *((uint16_t*)addr); +} + +static inline void co_write16p(uint32_t addr, uint32_t value) { + *((uint16_t*)addr) = value; +} + +static inline uint32_t co_read32p(uint32_t addr) { + return *((uint32_t*)addr); +} + +static inline void co_write32p(uint32_t addr, uint32_t value){ + *((uint32_t*)addr) = value; +} + +static inline bool co_cmp8p(uint32_t pkd, const uint8_t *ptr, uint32_t len) { + for (int i = 0; i < len; i++) { + if (co_read8p(pkd + i) != ((*(ptr+i)) & 0xff)) { + return false; + } + } + return true; +} + +static inline void co_pack8p(uint32_t dst, const uint8_t *src, uint32_t len) { + for (int i = 0; i < len; i++) { + co_write8p(dst + i, *(src + i)); + } +} + +static inline void co_unpack8p(uint8_t *dst, uint32_t src, uint32_t len) { + for (int i = 0; i < len; i++) { + *(dst + i) = co_read8p(src + i); + } +} + +static inline void co_copy8p(uint32_t dst, uint32_t src, uint32_t len) { + for (int i = 0; i < len; i++) { + co_write8p(dst + i, co_read8p(src + i)); + } +} + +/** + **************************************************************************************** + * @brief Get the index of an element in an array. + * @param[in] __element_ptr Pointer to the element + * @param[in] __array_ptr Pointer to the array + * @return The index of the element + **************************************************************************************** + */ +#define CO_GET_INDEX(__element_ptr, __array_ptr) ((__element_ptr) - (__array_ptr)) + +/// Length of a char in bytes +#define CHAR_LEN (CHAR_BIT/8) + +/** + **************************************************************************************** + * @brief Converts a CPU pointer into a HW address + * This macro is used to convert a SW pointer into the corresponding HW address. With CPUs + * having native byte support, the value returned will be the same as the pointer passed. + * With TL4, the value returned is the pointer multiplied by 2. + * @param[in] ptr Pointer to be converted + * @return The corresponding HW address + **************************************************************************************** + */ +#define CPU2HW(ptr) (((uint32_t)(ptr)) * CHAR_LEN) + +/** + **************************************************************************************** + * @brief Converts a HW address into a CPU pointer + * This macro is doing the reverse operation as @ref CPU2HW. + * @param[in] ptr Address to be converted + * @return The corresponding CPU pointer + **************************************************************************************** + */ +#define HW2CPU(ptr) ((void *)(((uint32_t)(ptr)) / CHAR_LEN)) +#endif // _CO_UTILS_H_ diff --git a/src/include/bl602_wifi/modules/common/notifier.h b/src/include/bl602_wifi/modules/common/notifier.h new file mode 100644 index 0000000..1ef5706 --- /dev/null +++ b/src/include/bl602_wifi/modules/common/notifier.h @@ -0,0 +1,18 @@ +#ifndef _NOTIFIER_H_ +#define _NOTIFIER_H_ + +struct notifier_block { + int (*cb)(struct notifier_block *, int, void *); // +0 + struct notifier_block *next; // +4 + int priority; // +8 +}; + + +int notifier_chain_regsiter(struct notifier_block **list, struct notifier_block *n); +int notifier_chain_regsiter_fromCritical(struct notifier_block **list, struct notifier_block *n); +int notifier_chain_unregsiter(struct notifier_block **list, struct notifier_block *n); +int notifier_chain_unregsiter_fromCritical(struct notifier_block **list, struct notifier_block *n); +int notifier_chain_call(struct notifier_block **list, int event, void *env); +int notifier_chain_call_fromeCritical(struct notifier_block **list, int event, void *env); + +#endif // _NOTIFIER_H_ diff --git a/src/include/bl602_wifi/modules/dbg/dbg.h b/src/include/bl602_wifi/modules/dbg/dbg.h new file mode 100644 index 0000000..9bd341b --- /dev/null +++ b/src/include/bl602_wifi/modules/dbg/dbg.h @@ -0,0 +1,48 @@ +#ifndef _DBG_H_ +#define _DBG_H_ + +#include + + +enum dbg_mod_tag { + DBG_MOD_IDX_KE = 0, + DBG_MOD_IDX_DBG = 1, + DBG_MOD_IDX_IPC = 2, + DBG_MOD_IDX_DMA = 3, + DBG_MOD_IDX_MM = 4, + DBG_MOD_IDX_TX = 5, + DBG_MOD_IDX_RX = 6, + DBG_MOD_IDX_PHY = 7, + DBG_MOD_IDX_MAX = 8, +}; + +enum dbg_sev_tag { + DBG_SEV_IDX_NONE = 0, + DBG_SEV_IDX_CRT = 1, + DBG_SEV_IDX_ERR = 2, + DBG_SEV_IDX_WRN = 3, + DBG_SEV_IDX_INF = 4, + DBG_SEV_IDX_VRB = 5, + DBG_SEV_IDX_MAX = 6, + DBG_SEV_ALL = 7, +}; + +#define DBG_SEV_MIN (31 - DBG_SEV_IDX_VRB) +#define DBG_SEV_MAX 32 + + +void dbg_test_print(const char *fmt, ...); + + +struct debug_env_tag { + uint32_t filter_module; // +0 + uint32_t filter_severity; // +4 +}; + + +extern struct debug_env_tag dbg_env; + + +void dbg_init(void); + +#endif // _DBG_H_ diff --git a/src/include/bl602_wifi/modules/dbg/dbg_task.h b/src/include/bl602_wifi/modules/dbg/dbg_task.h new file mode 100644 index 0000000..7f44b0b --- /dev/null +++ b/src/include/bl602_wifi/modules/dbg/dbg_task.h @@ -0,0 +1,57 @@ +#ifndef _DBG_TASK_H_ +#define _DBG_TASK_H_ + +#include + +enum dbg_msg_tag { + DBG_MEM_READ_REQ = 1024, + DBG_MEM_READ_CFM = 1025, + DBG_MEM_WRITE_REQ = 1026, + DBG_MEM_WRITE_CFM = 1027, + DBG_SET_MOD_FILTER_REQ = 1028, + DBG_SET_MOD_FILTER_CFM = 1029, + DBG_SET_SEV_FILTER_REQ = 1030, + DBG_SET_SEV_FILTER_CFM = 1031, + DBG_ERROR_IND = 1032, + DBG_GET_SYS_STAT_REQ = 1033, + DBG_GET_SYS_STAT_CFM = 1034, + DBG_SYS_STAT_TIMER = 1035, +}; + +struct dbg_mem_read_req { + uint32_t memaddr; // +0 +}; + +struct dbg_mem_read_cfm { + uint32_t memaddr; // +0 + uint32_t memdata; // +4 +}; + +struct dbg_mem_write_req { + uint32_t memaddr; // +0 + uint32_t memdata; // +4 +}; + +struct dbg_mem_write_cfm { + uint32_t memaddr; // +0 + uint32_t memdata; // +4 +}; + +struct dbg_set_mod_filter_req { + uint32_t mod_filter; // +0 +}; + +struct dbg_set_sev_filter_req { + uint32_t sev_filter; // +0 +}; + +struct dbg_get_sys_stat_cfm { + uint32_t cpu_sleep_time; // +0 + uint32_t doze_time; // +4 + uint32_t stats_time; // +8 +}; + + +extern const struct ke_state_handler dbg_default_handler; + +#endif // _DBG_TASK_H_ diff --git a/src/include/bl602_wifi/modules/ke/ke_env.h b/src/include/bl602_wifi/modules/ke/ke_env.h new file mode 100644 index 0000000..1516f77 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_env.h @@ -0,0 +1,21 @@ +#ifndef _KE_ENV_H_ +#define _KE_ENV_H_ + +#include + +#include + + +typedef uint32_t evt_field_t; + +struct ke_env_tag { + volatile evt_field_t evt_field; // +0 + struct co_list queue_sent; // +4 + struct co_list queue_saved; // +12 + struct co_list queue_timer; // +20 + struct mblock_free *mblock_first; // +28 +}; + +extern struct ke_env_tag ke_env; + +#endif diff --git a/src/include/bl602_wifi/modules/ke/ke_event.h b/src/include/bl602_wifi/modules/ke/ke_event.h new file mode 100644 index 0000000..d87d50d --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_event.h @@ -0,0 +1,41 @@ +#ifndef _KE_EVENT_H_ +#define _KE_EVENT_H_ + +#include +#include + +#define EVENT_DEF(name, _, __) KE_EVT_##name, +enum { + #include "ke_events_list.h" + KE_EVT_MAX = 27 +}; +#undef EVENT_DEF +#define EVENT_DEF(name, _, __) KE_EVT_##name##_BIT = CO_BIT(31 - KE_EVT_##name), +enum { +#include "ke_events_list.h" +}; +#undef EVENT_DEF +#define KE_EVT_TXCFM_MASK ( KE_EVT_TXCFM_AC0_BIT \ + | KE_EVT_TXCFM_AC1_BIT \ + | KE_EVT_TXCFM_AC2_BIT \ + | KE_EVT_TXCFM_AC3_BIT \ + | KE_EVT_TXCFM_BCN_BIT) + +#define KE_EVT_IPC_EMB_TXDESC_MASK ( KE_EVT_IPC_EMB_TXDESC_AC0_BIT \ + | KE_EVT_IPC_EMB_TXDESC_AC1_BIT \ + | KE_EVT_IPC_EMB_TXDESC_AC2_BIT \ + | KE_EVT_IPC_EMB_TXDESC_AC3_BIT \ + | KE_EVT_IPC_EMB_TXDESC_BCN_BIT) + + +static inline evt_field_t ke_evt_get(void) { + return ke_env.evt_field; +} + +void ke_evt_set(const evt_field_t event); +void ke_evt_clear(const evt_field_t event); +void ke_evt_schedule(void); +void ke_init(void); +void ke_flush(void); + +#endif diff --git a/src/include/bl602_wifi/modules/ke/ke_events_list.h b/src/include/bl602_wifi/modules/ke/ke_events_list.h new file mode 100644 index 0000000..f83b2f0 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_events_list.h @@ -0,0 +1,28 @@ +EVENT_DEF(RESET, bl_reset_evt, 0) +EVENT_DEF(MAIN, bl_event_handle, 1) +EVENT_DEF(SWDESC_UPLOAD, rxu_swdesc_upload_evt, 0) +EVENT_DEF(DMA_UL, hal_dma_evt, 1) +EVENT_DEF(MM_TIMER, mm_timer_schedule, 0) +EVENT_DEF(KE_TIMER, ke_timer_schedule, 0) +EVENT_DEF(IPC_EMB_MSG, ipc_emb_msg_evt, 0) +EVENT_DEF(KE_MESSAGE, ke_task_schedule, 0) +EVENT_DEF(HW_IDLE, mm_hw_idle_evt, 0) +EVENT_DEF(PRIMARY_TBTT, mm_tbtt_evt, 0) +EVENT_DEF(SECONDARY_TBTT, mm_tbtt_evt, 0) +EVENT_DEF(RX_DMA, rxl_dma_evt, 0) +EVENT_DEF(RXUREADY, rxu_cntrl_evt, 0) +EVENT_DEF(RXLREADY, rxl_cntrl_evt, 0) +EVENT_DEF(TXFRAME_CFM, txl_frame_evt, 0) +EVENT_DEF(TXCFM_BCN, txl_cfm_evt, 4) +EVENT_DEF(TXCFM_AC3, txl_cfm_evt, 3) +EVENT_DEF(TXCFM_AC2, txl_cfm_evt, 2) +EVENT_DEF(TXCFM_AC1, txl_cfm_evt, 1) +EVENT_DEF(TXCFM_AC0, txl_cfm_evt, 0) +EVENT_DEF(IPC_EMB_TXDESC_BCN, ipc_emb_tx_evt, 4) +EVENT_DEF(IPC_EMB_TXDESC_AC3, ipc_emb_tx_evt, 3) +EVENT_DEF(IPC_EMB_TXDESC_AC2, ipc_emb_tx_evt, 2) +EVENT_DEF(IPC_EMB_TXDESC_AC1, ipc_emb_tx_evt, 1) +EVENT_DEF(IPC_EMB_TXDESC_AC0, ipc_emb_tx_evt, 0) +EVENT_DEF(DMA_DL, hal_dma_evt, 0) +EVENT_DEF(EVM_VIA_MAC_TEST, bl_fw_statistic_dump, 0) +// my guess, it's bl_fw_statistic_dump \ No newline at end of file diff --git a/src/include/bl602_wifi/modules/ke/ke_mem.h b/src/include/bl602_wifi/modules/ke/ke_mem.h new file mode 100644 index 0000000..07df734 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_mem.h @@ -0,0 +1,11 @@ +#ifndef _KE_MEM_H_ +#define _KE_MEM_H_ + +#include + + +struct mblock_free *ke_mem_init(void); +void *ke_malloc(uint32_t size); +void ke_free(void *mem_ptr); + +#endif // _KE_MEM_H_ diff --git a/src/include/bl602_wifi/modules/ke/ke_msg.h b/src/include/bl602_wifi/modules/ke/ke_msg.h new file mode 100644 index 0000000..ba78201 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_msg.h @@ -0,0 +1,57 @@ +#ifndef _KE_MSG_H_ +#define _KE_MSG_H_ + +#include +#include +#include + +#include + + +typedef uint16_t ke_task_id_t; +typedef uint16_t ke_state_t; +typedef uint16_t ke_msg_id_t; + +struct ke_msg { + struct co_list_hdr hdr; // +0 + ke_msg_id_t id; // +4 + ke_task_id_t dest_id; // +6 + ke_task_id_t src_id; // +8 + uint16_t param_len; // +10 + uint32_t param[]; // +12 +}; + +STATIC_ASSERT(sizeof(struct ke_msg) == 12, ke_msg_must_has_sizeof_12); + +enum ke_msg_status_tag { + KE_MSG_CONSUMED = 0, + KE_MSG_NO_FREE = 1, + KE_MSG_SAVED = 2 +}; + +/// Retrieves task type from task id. +#define KE_TYPE_GET(ke_task_id) ((ke_task_id) & 0xff) + +/// Retrieves task index number from task id. +#define KE_IDX_GET(ke_task_id) (((ke_task_id) >> 8) & 0xff) +static inline struct ke_msg *ke_param2msg(const void *param_ptr) { + if (!param_ptr) + return 0; + + return ((struct ke_msg*) param_ptr) - 1; +} + +static inline void *ke_msg2param(const struct ke_msg *msg) { + if (!msg) + return 0; + return (void *)&(msg->param); +} + +void *ke_msg_alloc(const ke_msg_id_t id, const ke_task_id_t dest_id, const ke_task_id_t src_id, const uint16_t param_len); +#define KE_MSG_ALLOC(id, dest_id, src_id, type) ((struct type*) ke_msg_alloc(id, dest_id, src_id, sizeof(struct type))) +void ke_msg_send(const void *param_ptr); +void ke_msg_send_basic(const ke_msg_id_t id, const ke_task_id_t dest_id, const ke_task_id_t src_id); +void ke_msg_forward_and_change_id(const void *param_ptr, const ke_msg_id_t msg_id, const ke_task_id_t dest_id, const ke_task_id_t src_id); +void ke_msg_free(const struct ke_msg *msg); + +#endif // _KE_MSG_H_ diff --git a/src/include/bl602_wifi/modules/ke/ke_queue.h b/src/include/bl602_wifi/modules/ke/ke_queue.h new file mode 100644 index 0000000..5231645 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_queue.h @@ -0,0 +1,16 @@ +#ifndef _KE_QUEUE_H_ +#define _KE_QUEUE_H_ + +#include + +static inline void ke_queue_push(struct co_list* const queue, struct co_list_hdr* const element) { + co_list_push_back(queue, element); +} + +static inline struct co_list_hdr *ke_queue_pop(struct co_list* const queue) { + return co_list_pop_front(queue); +} + +struct co_list_hdr *ke_queue_extract(struct co_list* const queue, bool (*func)(const struct co_list_hdr*, uint32_t), uint32_t arg); + +#endif // _KE_QUEUE_H_ diff --git a/src/include/bl602_wifi/modules/ke/ke_task.h b/src/include/bl602_wifi/modules/ke/ke_task.h new file mode 100644 index 0000000..99af315 --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_task.h @@ -0,0 +1,81 @@ +#ifndef _KE_TASK_H_ +#define _KE_TASK_H_ + +#include +#include + +#include +#include + +// based on TASK_DESC +enum +{ + TASK_NONE = (uint8_t) -1, + + /// MAC Management task. + TASK_MM = 0, + TASK_DBG = 1, + /// SCAN task + TASK_SCAN = 2, + /// TDLS task + TASK_TDLS = 3, // maybe, not used anyway + /// SCAN task + TASK_SCANU = 4, + /// SCAN task + TASK_ME = 5, + /// SM task + TASK_SM = 6, + /// APM task + TASK_APM = 7, + /// BAM task + TASK_BAM = 8, + /// MESH task + TASK_MESH = 9, // maybe, not used anyway + TASK_HOSTAPD = 10, + /// RXU task + TASK_RXU = 11, // maybe, not used anyway + /// CFG task + TASK_CFG = 12, + TASK_LAST_EMB = TASK_CFG, // Last task + // nX API task + TASK_API = 13, // maybe, not used anyway + TASK_MAX, // max == 14 +}; + +#define DRV_TASK_ID 100 + +typedef int (*ke_msg_func_t)(const ke_msg_id_t, const void *, const ke_task_id_t, const ke_task_id_t); + +struct ke_msg_handler { + ke_msg_id_t id; // +0 + ke_msg_func_t func; // +4 +}; + +struct ke_state_handler { + const struct ke_msg_handler *msg_table; // +0 + uint16_t msg_cnt; // +4 +}; + +struct ke_task_desc { + const struct ke_state_handler *state_handler; // +0 + const struct ke_state_handler *default_handler; // +4 + ke_state_t *state; // +8 + uint16_t state_max; // +12 + uint16_t idx_max; // +14 +}; + +static inline bool ke_task_local(const ke_task_id_t id) { + ASSERT_ERR(id <= TASK_MAX); + return id <= TASK_LAST_EMB; +}; +ke_state_t ke_state_get(const ke_task_id_t id); +void ke_state_set(const ke_task_id_t id, const ke_state_t state_id); +void ke_task_schedule(int dummy); + + +#define KE_STATE_HANDLER(hdl) {hdl, sizeof(hdl)/sizeof(struct ke_msg_handler)} + +/// Helps writing empty states. +#define KE_STATE_HANDLER_NONE {NULL, 0} + +#endif // __KE_TASK_H__ diff --git a/src/include/bl602_wifi/modules/ke/ke_timer.h b/src/include/bl602_wifi/modules/ke/ke_timer.h new file mode 100644 index 0000000..6f08c6d --- /dev/null +++ b/src/include/bl602_wifi/modules/ke/ke_timer.h @@ -0,0 +1,42 @@ +#ifndef _KE_TIMER_H_ +#define _KE_TIMER_H_ + +#include +#include + +#include +#include + +#include + +struct ke_timer { + struct ke_timer *next; // +0 + ke_msg_id_t id; // +4 + ke_task_id_t task; // +6 + uint32_t time; // +8 +}; + + +void ke_timer_set(const ke_msg_id_t timer_id, const ke_task_id_t task_id, const uint32_t delay); +void ke_timer_clear(const ke_msg_id_t timer_id, const ke_task_id_t task_id); + +void ke_timer_schedule(int dummy); + +#define KE_TIMER_DELAY_MAX 300000000 +/// Standard Multiplier +#define MILLI2MICRO 1000 + +static inline bool ke_time_abs_cmp(uint32_t time1, uint32_t time2) { + uint32_t diff = time1 - time2; + return (((int32_t)diff) < 0); +} + +static inline uint32_t ke_time() { + return hal_machw_time(); +} + +static inline bool ke_time_past(uint32_t time) { + return ke_time_abs_cmp(time, ke_time()); +} + +#endif // _KE_TIMER_H_ diff --git a/src/include/bl602_wifi/modules/mac/mac.h b/src/include/bl602_wifi/modules/mac/mac.h new file mode 100644 index 0000000..2903e99 --- /dev/null +++ b/src/include/bl602_wifi/modules/mac/mac.h @@ -0,0 +1,168 @@ +#ifndef _MAC_H_ +#define _MAC_H_ + +#include +#include + +#include + +#include + +enum { + AC_BK = 0, + AC_BE, + AC_VI, + AC_VO, + AC_MAX +}; + +enum { + TID_0, + TID_1, + TID_2, + TID_3, + TID_4, + TID_5, + TID_6, + TID_7, + TID_MGT, + TID_MAX +}; + +/// SCAN type +enum { + SCAN_PASSIVE, + SCAN_ACTIVE +}; + +enum { + MAC_RATE_1MBPS = 2, + MAC_RATE_2MBPS = 4, + MAC_RATE_5_5MBPS = 11, + MAC_RATE_6MBPS = 12, + MAC_RATE_9MBPS = 18, + MAC_RATE_11MBPS = 22, + MAC_RATE_12MBPS = 24, + MAC_RATE_18MBPS = 36, + MAC_RATE_24MBPS = 48, + MAC_RATE_36MBPS = 72, + MAC_RATE_48MBPS = 96, + MAC_RATE_54MBPS = 108 +}; + +#define MAC_QOS_INFO_STA_UAPSD_ENABLED_VO CO_BIT(0) +#define MAC_QOS_INFO_STA_UAPSD_ENABLED_VI CO_BIT(1) +#define MAC_QOS_INFO_STA_UAPSD_ENABLED_BK CO_BIT(2) +#define MAC_QOS_INFO_STA_UAPSD_ENABLED_BE CO_BIT(3) +#define MAC_QOS_INFO_STA_UAPSD_ENABLED_ALL 0x0F + +#define MAC_QOS_INFO_AP_UAPSD_ENABLED CO_BIT(7) + +#define MAC_DEFAULT_KEY_COUNT 4 +#define MAC_DEFAULT_MFP_KEY_COUNT 6 + +#define MAC_SEC_KEY_LEN 32 // TKIP keys 256 bits (max length) with MIC keys + +/// duration of a Time Unit in microseconds +#define TU_DURATION 1024 + +struct PACKED mac_addr { + uint16_t array[3]; // +0 +}; + +/// Check if MAC address is a group address: test the multicast bit. +#define MAC_ADDR_GROUP(mac_addr_ptr) ((*((uint8_t *)(mac_addr_ptr))) & 1) + +typedef struct PACKED mac_addr_unpack { + uint8_t array[6]; // +0 +} mac_addr_unpack; + +struct mac_ssid { + uint8_t length; // +0 + uint8_t array[32]; // +1 + uint8_t array_tail[1]; // +33 +}; + +struct mac_rateset { + uint8_t length; // +0 + uint8_t array[12]; // +1 +}; + +struct key_info_tag { + uint64_t rx_pn[9]; // +0 + uint64_t tx_pn; // +72 + union { + struct { + uint32_t tx_key[2]; // +0 + uint32_t rx_key[2]; // +8 + } mic; + struct { + uint32_t key[4]; // +0 + } mfp; + } u; // +80 + uint8_t cipher; // +96 + uint8_t key_idx; // +97 + uint8_t hw_key_idx; // +98 + bool valid; // +99 +}; + +struct mac_sec_key { + uint8_t length; // +0 + uint32_t array[8]; // +4 +}; + +struct mac_htcapability { + uint16_t ht_capa_info; // +0 + uint8_t a_mpdu_param; // +2 + uint8_t mcs_rate[16]; // +3 + uint16_t ht_extended_capa; // +20 + uint32_t tx_beamforming_capa; // +24 + uint8_t asel_capa; // +28 +}; + +struct mac_vhtcapability { + uint32_t vht_capa_info; // +0 + uint16_t rx_mcs_map; // +4 + uint16_t rx_highest; // +6 + uint16_t tx_mcs_map; // +8 + uint16_t tx_highest; // +10 +}; + +struct mac_edca_param_set { + uint8_t qos_info; // +0 + uint8_t acm; // +1 + uint32_t ac_param[4]; // +4 +}; + +struct mac_scan_result { + struct mac_addr bssid; // +0 + struct mac_ssid ssid; // +6 + uint16_t bsstype; // +40 + struct scan_chan_tag *chan; // +44 + uint16_t beacon_period; // +48 + uint16_t cap_info; // +50 + bool valid_flag; // +52 + int8_t rssi; // +53 + int8_t ppm_rel; // +54 + int8_t ppm_abs; // +55 +}; + +struct mac_sta_info { + struct mac_rateset rate_set; // +0 + struct mac_htcapability ht_cap; // +16 + struct mac_vhtcapability vht_cap; // +48 + uint32_t capa_flags; // +60 + uint8_t phy_bw_max; // +64 + uint8_t bw_cur; // +65 + uint8_t uapsd_queues; // +66 + uint8_t max_sp_len; // +67 + uint8_t stbc_nss; // +68 +}; + +extern const uint8_t mac_tid2ac[]; +extern const uint8_t mac_ac2uapsd[4]; +extern const uint8_t mac_id2rate[]; +extern const struct mac_addr mac_addr_bcst; + +void bl60x_current_time_us(long long *time_now); +#endif diff --git a/src/include/bl602_wifi/modules/mac/mac_common.h b/src/include/bl602_wifi/modules/mac/mac_common.h new file mode 100644 index 0000000..25ae821 --- /dev/null +++ b/src/include/bl602_wifi/modules/mac/mac_common.h @@ -0,0 +1,54 @@ +#ifndef _MAC_COMMON_H_ +#define _MAC_COMMON_H_ +#include +/* + * DEFINES + **************************************************************************************** + */ +///Maximum number of scan results that can be stored. +#define MAX_BSS_LIST 32 + +/// Error code for invalid TID. +#define INVALID_TID_IDX 0xFF + +/// Error code for invalid access category. +#define INVALID_ACCESS_CATEGORY 0xFF + +/// Maximum number of traffic streams per station. +#define MAC_TID_MAX 16 + +/// Station indexes. +enum +{ + /// BROADCAST/GROUP DATA TX STA Index for first virtual AP. + BROADCAST_STA_IDX_MIN = NX_REMOTE_STA_MAX, + /// BROADCAST/GROUP DATA TX STA Index for last virtual AP. + BROADCAST_STA_IDX_MAX = NX_REMOTE_STA_MAX + NX_VIRT_DEV_MAX - 1, + /// Maximum number of supported STA + STA_MAX, + + /// Invalid STA Index used for error checking. + INVALID_STA_IDX = 0xFF +}; + +/// Macro giving the BCMC station index for the VIF index passed as parameter +#define VIF_TO_BCMC_IDX(idx) (BROADCAST_STA_IDX_MIN + (idx)) +// for some reason here the value is 3 +//#define VIF_TO_BCMC_IDX(idx) (3 + (idx)) + +/// Maximum size of the frame body for frames that are internally carried. +#define MAC_FRAME_LEN 512 + +/// MAC Frame structure. +struct mac_frame +{ + /// Actual length of the frame. + uint16_t length; + /// Array containing the frame body. + uint8_t array[MAC_FRAME_LEN]; +}; + +/// @} + +#endif + diff --git a/src/include/bl602_wifi/modules/mac/mac_frame.h b/src/include/bl602_wifi/modules/mac/mac_frame.h new file mode 100644 index 0000000..e511ed1 --- /dev/null +++ b/src/include/bl602_wifi/modules/mac/mac_frame.h @@ -0,0 +1,414 @@ +#ifndef _MAC_FRAME_H_ +#define _MAC_FRAME_H_ + +#include + +#include + +struct PACKED mac_hdr_ctrl { + uint16_t fctl; // +0 + uint16_t durid; // +2 + struct mac_addr addr1; // +4 + struct mac_addr addr2; // +10 +}; + +struct PACKED mac_hdr { + uint16_t fctl; // +0 + uint16_t durid; // +2 + struct mac_addr addr1; // +4 + struct mac_addr addr2; // +10 + struct mac_addr addr3; // +16 + uint16_t seq; // +22 +}; + +struct PACKED mac_hdr_qos { + uint16_t fctl; // +0 + uint16_t durid; // +2 + struct mac_addr addr1; // +4 + struct mac_addr addr2; // +10 + struct mac_addr addr3; // +16 + uint16_t seq; // +22 + uint16_t qos; // +24 +}; + +struct PACKED mac_hdr_long { + uint16_t fctl; // +0 + uint16_t durid; // +2 + struct mac_addr addr1; // +4 + struct mac_addr addr2; // +10 + struct mac_addr addr3; // +16 + uint16_t seq; // +22 + struct mac_addr addr4; // +24 +}; + +struct PACKED mac_hdr_long_qos { + uint16_t fctl; // +0 + uint16_t durid; // +2 + struct mac_addr addr1; // +4 + struct mac_addr addr2; // +10 + struct mac_addr addr3; // +16 + uint16_t seq; // +22 + struct mac_addr addr4; // +24 + uint16_t qos; // +30 +}; + +struct PACKED eth_hdr { + struct mac_addr da; // +0 + struct mac_addr sa; // +6 + uint16_t len; // +12 +}; + +struct PACKED bcn_frame { + struct mac_hdr h; // +0 + uint64_t tsf; // +24 + uint16_t bcnint; // +32 + uint16_t capa; // +34 + uint8_t variable[0]; // +36 +}; + +struct PACKED preq_frame { + struct mac_hdr h; // +0 + uint8_t payload[0]; // +24 +}; + +/* +struct PACKED aux_sec_hdr { + uint8_t security_control; // +0 + union { + uint8_t framecounters[4]; + uint32_t framecounter32; + uint32_t framecounter16[2]; + }; // + 1 + uint8_t key_idx[0]; // + 5 +};*/ + +struct PACKED eapol_payload { + union { + struct PACKED { + union { + struct PACKED { + uint8_t snap_dsap; // +0 + uint8_t snap_ssap; // +1 + }; + uint16_t snap; // + 0 + }; + union { + struct PACKED { + uint8_t control; // +2 + uint8_t rfc1042[3]; // +3 + }; + uint32_t ctrl_rfc; // +2 + }; + }; // =6 + struct PACKED { + uint32_t llc; // +0 + uint16_t zero; // +4 + }; // =6 + }; // =6 + uint16_t eth_type; // +6 + uint8_t payload[0]; +}; // =8 + + +/* +* ELEMENT ID DEFINITION (Table 20 page 55) +**************************************************************************************** +*/ +#define MAC_INFOELT_ID_OFT 0 +#define MAC_INFOELT_LEN_OFT 1 +#define MAC_INFOELT_INFO_OFT 2 + +#define MAC_ELTID_SSID 0 +#define MAC_ELTID_RATES 1 +#define MAC_ELTID_FH 2 +#define MAC_ELTID_DS 3 +#define MAC_ELTID_CF 4 +#define MAC_ELTID_TIM 5 +#define MAC_ELTID_IBSS 6 +#define MAC_ELTID_COUNTRY 7 // optional +#define MAC_ELTID_HOP_PARAM 8 // optional +#define MAC_ELTID_HOP_TABLE 9 // optional +#define MAC_ELTID_REQUEST 10 // optional +#define MAC_ELTID_BSS_LOAD 11 +#define MAC_ELTID_EDCA_PARAM 12 + +#define MAC_ELTID_CHALLENGE 16 +#define MAC_ELTID_POWER_CONSTRAINT 32 // Spectrum & Power Management +#define MAC_ELTID_POWER_CAPABILITY 33 // Spectrum & Power Management +#define MAC_POWER_CAPABILITY_IE_LEN 2 // Spectrum & Power Management +#define MAC_ELTID_TPC_REQUEST 34 // Spectrum & Power Management +#define MAC_ELTID_TPC_REPORT 35 // Spectrum & Power Management +#define MAC_ELTID_SUPPORTED_CHANNELS 36 // Spectrum & Power Management +#define MAC_ELTID_CHANNEL_SWITCH 37 // Spectrum & Power Management +#define MAC_ELTID_MEASUREMENT_REQUEST 38 // Spectrum & Power Management +#define MAC_ELTID_MEASUREMENT_REPORT 39 // Spectrum & Power Management +#define MAC_ELTID_QUIET 40 // Spectrum & Power Management +#define MAC_ELTID_IBSS_DFS 41 // Spectrum & Power Management + +#define MAC_ELTID_ERP 42 +#define MAC_ELTID_HT_CAPA 45 +#define MAC_ELTID_QOS_CAPA 46 +#define MAC_ELTID_RSN_IEEE 48 +#define MAC_ELTID_EXT_RATES 50 +#define MAC_ELTID_MDE 54 // Mobility Domain +#define MAC_ELTID_FTE 55 // Fast BSS Transition +#define MAC_ELTID_SUPP_OPER_CLASS 59 +#define MAC_ELTID_EXT_CHANNEL_SWITCH 60 +#define MAC_ELTID_SEC_CH_OFFSET 62 +#define MAC_ELTID_20_40_COEXISTENCE 72 +#define MAC_ELTID_OBSS_SCAN_PARAM 74 +#define MAC_ELTID_MGMT_MIC 76 +#define MAC_ELTID_HT_OPERATION 61 +#define MAC_ELTID_LINK_IDENTIFIER 101 +#define MAC_ELTID_CHANNEL_SWITCH_TIMING 104 +#define MAC_ELTID_PTI_CONTROL 105 +#define MAC_ELTID_TPU_BUFFER_STATUS 106 +#define MAC_ELTID_MESH_CONF 113 +#define MAC_ELTID_MESH_ID 114 +#define MAC_ELTID_MESH_LINK_METRIC_REP 115 +#define MAC_ELTID_CONGESTION_NOTIF 116 +#define MAC_ELTID_MESH_PEER_MGMT 117 +#define MAC_ELTID_MESH_CHAN_SWITCH_PARAM 118 +#define MAC_ELTID_MESH_AWAKE_WINDOW 119 +#define MAC_ELTID_MESH_GANN 125 +#define MAC_ELTID_MESH_RANN 126 +#define MAC_ELTID_EXT_CAPA 127 // This number need to be confirmed. +#define MAC_ELTID_MESH_PREQ 130 +#define MAC_ELTID_MESH_PREP 131 +#define MAC_ELTID_MESH_PERR 132 +#define MAC_ELTID_VHT_CAPA 191 +#define MAC_ELTID_VHT_OPERATION 192 +#define MAC_ELTID_WIDE_BANDWIDTH_CHAN_SWITCH 194 +#define MAC_ELTID_VHT_TRANSMIT_PWR_ENVELOP 195 +#define MAC_ELTID_CHAN_SWITCH_WRP 196 +#define MAC_ELTID_OUI 221 // Proprietary (0xDD) + +/** + * MAC HEADER LENGTH DEFINITIONS + **************************************************************************************** + */ +/// Long MAC Header length (with QoS control field and HT control field) +#define MAC_LONG_QOS_HTC_MAC_HDR_LEN 36 +/// Long MAC Header length (with QoS control field) +#define MAC_LONG_QOS_MAC_HDR_LEN 32 +/// Long MAC Header length (without QoS control field) +#define MAC_LONG_MAC_HDR_LEN 30 +/// Short MAC Header length (with QoS control field and HT control field) +#define MAC_SHORT_QOS_HTC_MAC_HDR_LEN 30 +/// Short MAC Header length (with QoS control field) +#define MAC_SHORT_QOS_MAC_HDR_LEN 26 +/// Short MAC Header length (without QoS control field) +#define MAC_SHORT_MAC_HDR_LEN 24 + +/* +* MANAGEMENT FRAME DESCRIPTION +**************************************************************************************** +*/ +#define MAC_BEACON_MAX_LEN 333 +#define MAC_BEACONINFO_SIZE 78 // size without TIM +#define MAC_TIM_SIZE 251 // max TIM size +// Attention, in a non-AP STA the IBSS +// parameter set is stored in place of +// the TIM -> min size 4 + +// TIM +#define MAC_TIM_ID_OFT 0 +#define MAC_TIM_LEN_OFT 1 +#define MAC_TIM_CNT_OFT 2 +#define MAC_TIM_PERIOD_OFT 3 +#define MAC_TIM_BMPC_OFT 4 +#define MAC_TIM_BMP_OFT 5 +#define MAC_TIM_IE_LEN (5 + MAC_TIM_SIZE) +#define MAC_TIM_BCMC_PRESENT CO_BIT(0) + +/* + * Beacon Frame offset (Table 5 p46) + */ +#define MAC_BEACON_TIMESTAMP_OFT MAC_SHORT_MAC_HDR_LEN // Order 1 +#define MAC_BEACON_INTERVAL_OFT (MAC_SHORT_MAC_HDR_LEN + 8) // Order 2 +#define MAC_BEACON_CAPA_OFT (MAC_SHORT_MAC_HDR_LEN + 10) // Order 3 +#define MAC_BEACON_VARIABLE_PART_OFT (MAC_SHORT_MAC_HDR_LEN + 12) // Order 4 + +/* +* ELEMENT ID DEFINITION (Table 20 page 55) +**************************************************************************************** +*/ +#define MAC_INFOELT_ID_OFT 0 +#define MAC_INFOELT_LEN_OFT 1 +#define MAC_INFOELT_INFO_OFT 2 + + + // Cipher suite selectors + #define MAC_RSNIE_CIPHER_MASK 0x07 + #define MAC_RSNIE_CIPHER_WEP40 0x00 + #define MAC_RSNIE_CIPHER_TKIP 0x01 + #define MAC_RSNIE_CIPHER_CCMP 0x02 + #define MAC_RSNIE_CIPHER_WEP104 0x03 + #define MAC_RSNIE_CIPHER_WPI_SMS4 0x04 + #define MAC_RSNIE_CIPHER_AES_CMAC 0x05 + +/* + * MAC HEADER definitions and OFFSETS + **************************************************************************************** + */ +#define MAC_HEAD_FCTRL_OFT 0 +#define MAC_HEAD_DURATION_OFT 2 +#define MAC_HEAD_DURATION_CFP 0x8000 +#define MAC_HEAD_ADDR1_OFT 4 +#define MAC_HEAD_ADDR2_OFT 10 +#define MAC_HEAD_ADDR3_OFT 16 +#define MAC_HEAD_CTRL_OFT 22 +#define MAC_HEAD_ADDR4_OFT 24 +#define MAC_HEAD_SHORT_QOS_OFT 24 +#define MAC_HEAD_LONG_QOS_OFT 30 +#define MAC_ORIGINAL_ETHTYPE_OFT 36 + +/// SEQUENCE CONTROL FIELD +#define MAC_SEQCTRL_LEN 2 +#define MAC_SEQCTRL_NUM_OFT 4 +#define MAC_SEQCTRL_NUM_MSK 0xFFF0 +#define MAC_SEQCTRL_NUM_MAX (MAC_SEQCTRL_NUM_MSK >> MAC_SEQCTRL_NUM_OFT) +#define MAC_SEQCTRL_FRAG_OFT 0 +#define MAC_SEQCTRL_FRAG_MSK 0x000F + +// MIC and FCS lengths +#define MAC_FCS_LEN 4 +#define MAC_MIC_LEN 8 + +#define MAC_FCTRL_PROTOCOLVERSION_MASK 0x0003 +#define MAC_FCTRL_TYPE_MASK 0x000C +#define MAC_FCTRL_MGT_T 0x0000 +#define MAC_FCTRL_CTRL_T 0x0004 +#define MAC_FCTRL_DATA_T 0x0008 +#define MAC_FCTRL_RSV_T 0x000c + +#define MAC_FCTRL_SUBT_MASK 0x00F0 +/// Management SubType +#define MAC_FCTRL_ASSOCREQ_ST 0x0000 +#define MAC_FCTRL_ASSOCRSP_ST 0x0010 +#define MAC_FCTRL_REASSOCREQ_ST 0x0020 +#define MAC_FCTRL_REASSOCRSP_ST 0x0030 +#define MAC_FCTRL_PROBEREQ_ST 0x0040 +#define MAC_FCTRL_PROBERSP_ST 0x0050 +#define MAC_FCTRL_BEACON_ST 0x0080 +#define MAC_FCTRL_ATIM_ST 0x0090 +#define MAC_FCTRL_DISASSOC_ST 0x00A0 +#define MAC_FCTRL_AUTHENT_ST 0x00B0 +#define MAC_FCTRL_DEAUTHENT_ST 0x00C0 +#define MAC_FCTRL_ACTION_ST 0x00D0 +#define MAC_FCTRL_ACTION_NO_ACK_ST 0x00E0 +/// Control SubTypes +#define MAC_FCTRL_BFM_REPORT_POLL_ST 0x0040 +#define MAC_FCTRL_VHT_NDPA_ST 0x0050 +#define MAC_FCTRL_CTRL_WRAPPER_ST 0x0070 +#define MAC_FCTRL_BAR_ST 0x0080 +#define MAC_FCTRL_BA_ST 0x0090 +#define MAC_FCTRL_PSPOLL_ST 0x00A0 +#define MAC_FCTRL_RTS_ST 0x00B0 +#define MAC_FCTRL_CTS_ST 0x00C0 +#define MAC_FCTRL_ACK_ST 0x00D0 +#define MAC_FCTRL_CFEND_ST 0x00E0 +#define MAC_FCTRL_CFEND_CFACK_ST 0x00F0 + +/// Data SubTypes +/* Decoding the subtypes of data type frames can take advantage of the fact that + * each subtype field bit position is used to indicate a specific modification of + * the basic data frame (subtype 0). Frame control bit 4 is set to 1 in data + * subtypes which include +CF-Ack, bit 5 is set to 1 in data subtypes which include + * +CF-Poll, bit 6 is set to 1 in data subtypes that contain no Frame Body, + * and bit 7 is set to 1 in the QoS data subtypes, which have QoS Control fields in + * their MAC headers. + * + * Usage: check FrameT and FrameSubT individually. If the FrameT is MAC_FCTRL_DATA_T, + * check the following bits of the FrameSubT + */ +#define MAC_CFACK_ST_BIT CO_BIT(4) +#define MAC_CFPOLL_ST_BIT CO_BIT(5) +#define MAC_NODATA_ST_BIT CO_BIT(6) +#define MAC_QOS_ST_BIT CO_BIT(7) + +#define MAC_FCTRL_DATACFACKPOLL_ST (MAC_CFACK_ST_BIT | MAC_CFPOLL_ST_BIT) +#define MAC_FCTRL_TODS 0x0100 +#define MAC_FCTRL_FROMDS 0x0200 +#define MAC_FCTRL_MOREFRAG 0x0400 +#define MAC_FCTRL_RETRY 0x0800 +#define MAC_FCTRL_PWRMGT 0x1000 +#define MAC_FCTRL_MOREDATA 0x2000 +#define MAC_FCTRL_PROTECTEDFRAME 0x4000 +#define MAC_FCTRL_ORDER 0x8000 + +#define MAC_FCTRL_TODS_FROMDS (MAC_FCTRL_TODS | MAC_FCTRL_FROMDS) + +/// FRAME CONTROL : Type information including Type and SubType +#define MAC_FCTRL_TYPESUBTYPE_MASK (MAC_FCTRL_TYPE_MASK | MAC_FCTRL_SUBT_MASK) +#define MAC_FCTRL_ASSOCREQ (MAC_FCTRL_MGT_T | MAC_FCTRL_ASSOCREQ_ST) +#define MAC_FCTRL_ASSOCRSP (MAC_FCTRL_MGT_T | MAC_FCTRL_ASSOCRSP_ST) +#define MAC_FCTRL_REASSOCREQ (MAC_FCTRL_MGT_T | MAC_FCTRL_REASSOCREQ_ST) +#define MAC_FCTRL_REASSOCRSP (MAC_FCTRL_MGT_T | MAC_FCTRL_REASSOCRSP_ST) +#define MAC_FCTRL_PROBEREQ (MAC_FCTRL_MGT_T | MAC_FCTRL_PROBEREQ_ST) +#define MAC_FCTRL_PROBERSP (MAC_FCTRL_MGT_T | MAC_FCTRL_PROBERSP_ST) +#define MAC_FCTRL_BEACON (MAC_FCTRL_MGT_T | MAC_FCTRL_BEACON_ST) +#define MAC_FCTRL_ATIM (MAC_FCTRL_MGT_T | MAC_FCTRL_ATIM_ST) +#define MAC_FCTRL_DISASSOC (MAC_FCTRL_MGT_T | MAC_FCTRL_DISASSOC_ST) +#define MAC_FCTRL_AUTHENT (MAC_FCTRL_MGT_T | MAC_FCTRL_AUTHENT_ST) +#define MAC_FCTRL_DEAUTHENT (MAC_FCTRL_MGT_T | MAC_FCTRL_DEAUTHENT_ST) +#define MAC_FCTRL_ACTION (MAC_FCTRL_MGT_T | MAC_FCTRL_ACTION_ST) +#define MAC_FCTRL_ACTION_NO_ACK (MAC_FCTRL_MGT_T | MAC_FCTRL_ACTION_NO_ACK_ST) +#define MAC_FCTRL_BFM_REPORT_POLL (MAC_FCTRL_CTRL_T | MAC_FCTRL_BFM_REPORT_POLL_ST) +#define MAC_FCTRL_VHT_NDPA (MAC_FCTRL_CTRL_T | MAC_FCTRL_VHT_NDPA_ST) +#define MAC_FCTRL_BA (MAC_FCTRL_CTRL_T | MAC_FCTRL_BA_ST) +#define MAC_FCTRL_BAR (MAC_FCTRL_CTRL_T | MAC_FCTRL_BAR_ST) +#define MAC_FCTRL_PSPOLL (MAC_FCTRL_CTRL_T | MAC_FCTRL_PSPOLL_ST) +#define MAC_FCTRL_RTS (MAC_FCTRL_CTRL_T | MAC_FCTRL_RTS_ST) +#define MAC_FCTRL_CTS (MAC_FCTRL_CTRL_T | MAC_FCTRL_CTS_ST) +#define MAC_FCTRL_ACK (MAC_FCTRL_CTRL_T | MAC_FCTRL_ACK_ST) +#define MAC_FCTRL_CFEND (MAC_FCTRL_CTRL_T | MAC_FCTRL_CFEND_ST) +#define MAC_FCTRL_CFEND_CFACK (MAC_FCTRL_CFEND | MAC_CFACK_ST_BIT) +#define MAC_FCTRL_DATA_CFACK (MAC_FCTRL_DATA_T | MAC_CFACK_ST_BIT) +#define MAC_FCTRL_DATA_CFPOLL (MAC_FCTRL_DATA_T | MAC_CFPOLL_ST_BIT) +#define MAC_FCTRL_DATA_CFACKPOLL (MAC_FCTRL_DATA_T | MAC_FCTRL_DATACFACKPOLL_ST) +#define MAC_FCTRL_NULL_FUNCTION (MAC_FCTRL_DATA_T | MAC_NODATA_ST_BIT) +#define MAC_FCTRL_NULL_CFACK (MAC_FCTRL_NULL_FUNCTION | MAC_CFACK_ST_BIT) +#define MAC_FCTRL_NULL_CFPOLL (MAC_FCTRL_NULL_FUNCTION | MAC_CFPOLL_ST_BIT) +#define MAC_FCTRL_NULL_CFACKPOLL (MAC_FCTRL_NULL_FUNCTION | MAC_FCTRL_DATACFACKPOLL_ST) +#define MAC_FCTRL_QOS_DATA (MAC_FCTRL_DATA_T | MAC_QOS_ST_BIT) +#define MAC_FCTRL_QOS_DATA_CFACK (MAC_FCTRL_QOS_DATA | MAC_CFACK_ST_BIT) +#define MAC_FCTRL_QOS_DATA_CFPOLL (MAC_FCTRL_QOS_DATA | MAC_CFPOLL_ST_BIT) +#define MAC_FCTRL_QOS_DATA_CFACKPOLL (MAC_FCTRL_QOS_DATA | MAC_FCTRL_DATACFACKPOLL_ST) +#define MAC_FCTRL_QOS_NULL (MAC_FCTRL_QOS_DATA | MAC_NODATA_ST_BIT) +#define MAC_FCTRL_QOS_NULL_CFACK (MAC_FCTRL_QOS_DATA | MAC_FCTRL_NULL_CFACK) +#define MAC_FCTRL_QOS_NULL_CFPOLL (MAC_FCTRL_QOS_DATA | MAC_FCTRL_NULL_CFPOLL) +#define MAC_FCTRL_QOS_NULL_CFACKPOLL (MAC_FCTRL_QOS_DATA | MAC_FCTRL_NULL_CFACKPOLL) + +#define MAC_FCTRL_IS(fc, type) (((fc) & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_##type) + +/// Long control frame header length +#define MAC_LONG_CTRLFRAME_LEN 16 +/// Short control frame header length (ACK/CTS) +#define MAC_SHORT_CTRLFRAME_LEN 10 + +/// Maximum size of a beacon frame (default IE + TIM + remaining IE space) +#define MAC_BEACON_SIZE (102 + MAC_TIM_SIZE + 128) +/// Maximum size of a probe request frame +#define MAC_PROBEREQ_SIZE 100 +/// Maximum size of a probe response frame (default IE + remaining IE space) +#define MAC_PROBERSP_SIZE (102 + 128) +/// Size of a NULL frame +#define MAC_NULL_FRAME_SIZE MAC_SHORT_MAC_HDR_LEN +/// Size of a QoS-NULL frame +#define MAC_QOS_NULL_FRAME_SIZE MAC_SHORT_QOS_MAC_HDR_LEN +/// Size of a PS poll +#define MAC_PSPOLL_FRAME_SIZE MAC_LONG_CTRLFRAME_LEN + +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ +#define FRAME_BODY_LLC_H 0x0003AAAA +#define FRAME_BODY_LLC_L 0x0D890000 +#define PAYLOAD_TYPE_TDLS 0x02 + +#define MAC_ENCAPSULATED_LLC_H_OFT 0 +#define MAC_ENCAPSULATED_LLC_L_OFT 4 +#define MAC_ENCAPSULATED_PAYLOAD_TYPE_OFT 8 +#define MAC_ENCAPSULATED_PAYLOAD_OFT 9 + +#endif // _MAC_FRAME_H_ diff --git a/src/include/bl602_wifi/modules/mac/mac_ie.h b/src/include/bl602_wifi/modules/mac/mac_ie.h new file mode 100644 index 0000000..ad4a6ff --- /dev/null +++ b/src/include/bl602_wifi/modules/mac/mac_ie.h @@ -0,0 +1,15 @@ +#ifndef _MAC_IE_H_ +#define _MAC_IE_H_ + +#include + +struct mgmt_ie { + uint8_t element_id; + uint8_t payload_length; + uint8_t payload[0]; +}; + +uint32_t mac_ie_find(uint32_t addr, uint16_t buflen, uint8_t ie_id); +uint32_t mac_vsie_find(uint32_t addr, uint16_t buflen, const uint8_t *oui, uint8_t ouilen); + +#endif // _MAC_IE_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/IEEE_types.h b/src/include/bl602_wifi/modules/supplicant/IEEE_types.h new file mode 100644 index 0000000..00062b8 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/IEEE_types.h @@ -0,0 +1,243 @@ +#ifndef _IEEE_TYPES_H_ +#define _IEEE_TYPES_H_ + +#include + + +typedef enum { + IEEE_8021X_PACKET_TYPE_EAP_PACKET = 0, + IEEE_8021X_PACKET_TYPE_EAPOL_START = 1, + IEEE_8021X_PACKET_TYPE_EAPOL_LOGOFF = 2, + IEEE_8021X_PACKET_TYPE_EAPOL_KEY = 3, + IEEE_8021X_PACKET_TYPE_ASF_ALERT = 4, +} IEEEtypes_8021x_PacketType_e; +typedef enum { + IEEE_8021X_CODE_TYPE_REQUEST = 1, + IEEE_8021X_CODE_TYPE_RESPONSE = 2, + IEEE_8021X_CODE_TYPE_SUCCESS = 3, + IEEE_8021X_CODE_TYPE_FAILURE = 4, +} IEEEtypes_8021x_CodeType_e; +typedef enum { + ELEM_ID_SSID = 0, + ELEM_ID_SUPPORTED_RATES = 1, + ELEM_ID_FH_PARAM_SET = 2, + ELEM_ID_DS_PARAM_SET = 3, + ELEM_ID_CF_PARAM_SET = 4, + ELEM_ID_TIM = 5, + ELEM_ID_IBSS_PARAM_SET = 6, + ELEM_ID_COUNTRY = 7, + ELEM_ID_HOP_PARAM = 8, + ELEM_ID_HOP_TABLE = 9, + ELEM_ID_REQUEST = 10, + ELEM_ID_BSS_LOAD = 11, + ELEM_ID_EDCA_PARAM_SET = 12, + ELEM_ID_TSPEC = 13, + ELEM_ID_TCLAS = 14, + ELEM_ID_SCHEDULE = 15, + ELEM_ID_CHALLENGE_TEXT = 16, + ELEM_ID_POWER_CONSTRAINT = 32, + ELEM_ID_POWER_CAPABILITY = 33, + ELEM_ID_TPC_REQUEST = 34, + ELEM_ID_TPC_REPORT = 35, + ELEM_ID_SUPPORTED_CHANNELS = 36, + ELEM_ID_CHANNEL_SWITCH_ANN = 37, + ELEM_ID_MEASUREMENT_REQ = 38, + ELEM_ID_MEASUREMENT_RPT = 39, + ELEM_ID_QUIET = 40, + ELEM_ID_IBSS_DFS = 41, + ELEM_ID_ERP_INFO = 42, + ELEM_ID_TS_DELAY = 43, + ELEM_ID_TCLAS_PROCESS = 44, + ELEM_ID_HT_CAPABILITY = 45, + ELEM_ID_QOS_CAPABILITY = 46, + ELEM_ID_RSN = 48, + ELEM_ID_EXT_SUPPORTED_RATES = 50, + ELEM_ID_AP_CHANNEL_REPORT = 51, + ELEM_ID_NEIGHBOR_REPORT = 52, + ELEM_ID_RCPI = 53, + ELEM_ID_MOBILITY_DOMAIN = 54, + ELEM_ID_FAST_BSS_TRANS = 55, + ELEM_ID_TIMEOUT_INTERVAL = 56, + ELEM_ID_RIC_DATA = 57, + ELEM_ID_DSE_REGISTERED_LOC = 58, + ELEM_ID_SUPPORTED_REGCLASS = 59, + ELEM_ID_EXT_CHAN_SWITCH_ANN = 60, + ELEM_ID_HT_INFORMATION = 61, + ELEM_ID_SECONDARY_CHAN_OFFSET = 62, + ELEM_ID_BSS_ACCESS_DELAY = 63, + ELEM_ID_ANTENNA_INFO = 64, + ELEM_ID_RSNI = 65, + ELEM_ID_MEAS_PILOT_TX_INFO = 66, + ELEM_ID_BSS_AVAIL_ADM_CAP = 67, + ELEM_ID_BSS_AC_ACCESS_DELAY = 68, + ELEM_ID_RRM_ENABLED_CAP = 70, + ELEM_ID_MULTI_BSSID = 71, + ELEM_ID_2040_BSS_COEXISTENCE = 72, + ELEM_ID_2040_BSS_INTOL_CHRPT = 73, + ELEM_ID_OBSS_SCAN_PARAM = 74, + ELEM_ID_RIC_DESCRIPTOR = 75, + ELEM_ID_MANAGEMENT_MIC = 76, + ELEM_ID_EVENT_REQUEST = 78, + ELEM_ID_EVENT_REPORT = 79, + ELEM_ID_DIAG_REQUEST = 80, + ELEM_ID_DIAG_REPORT = 81, + ELEM_ID_LOCATION_PARAM = 82, + ELEM_ID_NONTRANS_BSSID_CAP = 83, + ELEM_ID_SSID_LIST = 84, + ELEM_ID_MBSSID_INDEX = 85, + ELEM_ID_FMS_DESCRIPTOR = 86, + ELEM_ID_FMS_REQUEST = 87, + ELEM_ID_FMS_RESPONSE = 88, + ELEM_ID_QOS_TRAFFIC_CAP = 89, + ELEM_ID_BSS_MAX_IDLE_PERIOD = 90, + ELEM_ID_TFS_REQUEST = 91, + ELEM_ID_TFS_RESPONSE = 92, + ELEM_ID_WNM_SLEEP_MODE = 93, + ELEM_ID_TIM_BCAST_REQUEST = 94, + ELEM_ID_TIM_BCAST_RESPONSE = 95, + ELEM_ID_COLLOC_INTF_REPORT = 96, + ELEM_ID_CHANNEL_USAGE = 97, + ELEM_ID_TIME_ZONE = 98, + ELEM_ID_DMS_REQUEST = 99, + ELEM_ID_DMS_RESPONSE = 100, + ELEM_ID_LINK_ID = 101, + ELEM_ID_WAKEUP_SCHEDULE = 102, + ELEM_ID_TDLS_CS_TIMING = 104, + ELEM_ID_PTI_CONTROL = 105, + ELEM_ID_PU_BUFFER_STATUS = 106, + ELEM_ID_EXT_CAPABILITIES = 127, + ELEM_ID_VHT_CAPABILITIES = 191, + ELEM_ID_VHT_OPERATION = 192, + ELEM_ID_WIDE_BAND_CHAN_SW = 193, + ELEM_ID_AID = 197, + ELEM_ID_VHT_OP_MODE_NOTIFICATION = 199, + ELEM_ID_VENDOR_SPECIFIC = 221, + ELEM_ID_EXTENSION = 255, + ELEM_ID_EXT_ASSOC_DELAY_INFO = 1, + ELEM_ID_EXT_FILS_REQ_PARAMS = 2, + ELEM_ID_EXT_FILS_KEY_CONFIRM = 3, + ELEM_ID_EXT_FILS_SESSION = 4, + ELEM_ID_EXT_FILS_HLP_CONTAINER = 5, + ELEM_ID_EXT_FILS_IP_ADDR_ASSIGN = 6, + ELEM_ID_EXT_KEY_DELIVERY = 7, + ELEM_ID_EXT_FILS_WRAPPED_DATA = 8, + ELEM_ID_EXT_FTM_SYNC_INFO = 9, + ELEM_ID_EXT_EXTENDED_REQUEST = 10, + ELEM_ID_EXT_ESTIMATED_SERVICE_PARAMS = 11, + ELEM_ID_EXT_FILS_PUBLIC_KEY = 12, + ELEM_ID_EXT_FILS_NONCE = 13, + ELEM_ID_EXT_FUTURE_CHANNEL_GUIDANCE = 14, + ELEM_ID_EXT_OWE_DH_PARAM = 32, + ELEM_ID_EXT_PASSWORD_IDENTIFIER = 33, + ELEM_ID_EXT_HE_CAPABILITIES = 35, + ELEM_ID_EXT_HE_OPERATION = 36, + SUBELEM_ID_REPORTED_FRAME_BODY = 1, + SUBELEM_ID_REPORTING_DETAIL = 2, + SUBELEM_ID_PMK_R1_KEY_HOLDER_ID = 1, + SUBELEM_ID_GTK = 2, + SUBELEM_ID_PMK_R0_KEY_HOLDER_ID = 3, + SUBELEM_ID_IGTK = 4, + ELEM_ID_WAPI = 68, +} IEEEtypes_ElementId_e; +typedef enum { + KDE_DATA_TYPE_RESERVED = 0, + KDE_DATA_TYPE_GTK = 1, + KDE_DATA_TYPE_RESERVED2 = 2, + KDE_DATA_TYPE_MACADDR = 3, + KDE_DATA_TYPE_PMKID = 4, + KDE_DATA_TYPE_SMK = 5, + KDE_DATA_TYPE_NONCE = 6, + KDE_DATA_TYPE_LIFETIME = 7, + KDE_DATA_TYPE_ERROR = 8, + KDE_DATA_TYPE_IGTK = 9, +} IEEEtypes_KDEDataType_e; +typedef enum { + PWR_MODE_ACTIVE = 0, + PWR_MODE_PWR_SAVE = 1, +} IEEEtypes_PwrMgmtMode_e; +typedef UINT8 IEEEtypes_Len_t;typedef UINT8 IEEEtypes_Addr_t;typedef IEEEtypes_Addr_t IEEEtypes_MacAddr_t[6];typedef UINT8 IEEEtypes_SsId_t[32];typedef UINT16 IEEEtypes_BcnInterval_t;typedef UINT8 IEEEtypes_DtimPeriod_t; +typedef struct { + IEEEtypes_ElementId_e ElementId; // +0 + IEEEtypes_Len_t Len; // +1 +} IEEEtypes_InfoElementHdr_t; +typedef struct { + IEEEtypes_ElementId_e ElementId; // +0 + IEEEtypes_Len_t Len; // +1 + IEEEtypes_SsId_t SsId; // +2 +} IEEEtypes_SsIdElement_t; +typedef struct { + IEEEtypes_ElementId_e ElementId; // +0 + IEEEtypes_Len_t Len; // +1 + UINT8 OuiType[4]; // +2 + UINT16 Ver; // +6 + UINT8 GrpKeyCipher[4]; // +8 + UINT16 PwsKeyCnt; // +12 + UINT8 PwsKeyCipherList[4]; // +14 + UINT16 AuthKeyCnt; // +18 + UINT8 AuthKeyList[4]; // +20 +} IEEEtypes_WPAElement_t; +typedef struct { + UINT8 PreAuth:1; // +0 + UINT8 NoPairwise:1; // +0 + UINT8 PtksaReplayCtr:2; // +0 + UINT8 GtksaReplayCtr:2; // +0 + UINT8 MFPR:1; // +0 + UINT8 MFPC:1; // +0 + UINT8 Reserved_8:1; // +1 + UINT8 PeerkeyEnabled:1; // +1 + UINT8 SppAmsduCap:1; // +1 + UINT8 SppAmsduReq:1; // +1 + UINT8 PBAC:1; // +1 + UINT8 Reserved_13_15:3; // +1 +} IEEEtypes_RSNCapability_t; +typedef struct { + IEEEtypes_ElementId_e ElementId; // +0 + IEEEtypes_Len_t Len; // +1 + UINT16 Ver; // +2 + UINT8 GrpKeyCipher[4]; // +4 + UINT16 PwsKeyCnt; // +8 + UINT8 PwsKeyCipherList[4]; // +10 + UINT16 AuthKeyCnt; // +14 + UINT8 AuthKeyList[4]; // +16 + IEEEtypes_RSNCapability_t RsnCap; // +20 + UINT16 PMKIDCnt; // +22 + UINT8 PMKIDList[16]; // +24 + UINT8 GrpMgmtCipher[4]; // +40 +} IEEEtypes_RSNElement_t; +typedef enum { + Band_2_4_GHz = 0, + Band_5_GHz = 1, + Band_4_GHz = 2, +} ChanBand_e; +typedef enum { + ChanWidth_20_MHz = 0, + ChanWidth_10_MHz = 1, + ChanWidth_40_MHz = 2, + ChanWidth_80_MHz = 3, +} ChanWidth_e; +typedef enum { + SECONDARY_CHAN_NONE = 0, + SECONDARY_CHAN_ABOVE = 1, + SECONDARY_CHAN_BELOW = 3, +} Chan2Offset_e; +typedef enum { + MANUAL_MODE = 0, + ACS_MODE = 1, +} ScanMode_e; +typedef struct { + ChanBand_e chanBand:2; // +0 + ChanWidth_e chanWidth:2; // +0 + Chan2Offset_e chan2Offset:2; // +0 + ScanMode_e scanMode:2; // +0 +} BandConfig_t; +typedef struct { + BandConfig_t bandConfig; // +0 + UINT8 chanNum; // +1 +} ChanBandInfo_t; +typedef struct { + IEEEtypes_MacAddr_t da; // +0 + IEEEtypes_MacAddr_t sa; // +6 + UINT16 type; // +12 +} ether_hdr_t; + +#endif // __IEEE_TYPES_H__ diff --git a/src/include/bl602_wifi/modules/supplicant/KeyApiStaDefs.h b/src/include/bl602_wifi/modules/supplicant/KeyApiStaDefs.h new file mode 100644 index 0000000..b59e4d9 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/KeyApiStaDefs.h @@ -0,0 +1,50 @@ +#ifndef _KEYAPISTADEFS_H_ +#define _KEYAPISTADEFS_H_ + +#include + + +typedef struct { + UINT8 key[16]; // +0 + UINT8 txMicKey[8]; // +16 + UINT8 rxMicKey[8]; // +24 +} key_Type_TKIP_t; + +typedef struct { + UINT8 keyIndex; // +0 + UINT8 isDefaultTx; // +1 + UINT8 key[13]; // +2 +} key_Type_WEP_t; + +typedef struct { + UINT8 key[16]; // +0 +} key_Type_AES_t; + +typedef struct { + UINT8 keyIndex; // +0 + UINT8 isDefKey; // +1 + UINT8 key[16]; // +2 + UINT8 mickey[16]; // +18 + UINT8 rxPN[16]; // +34 +} key_Type_WAPI_t; + +typedef struct { + UINT8 ipn[6]; // +0 + UINT8 reserved[2]; // +6 + UINT8 key[16]; // +8 +} key_Type_AES_CMAC_t; + +typedef struct { + UINT16 keyType; // +0 + UINT16 keyInfo; // +2 + UINT16 keyLen; // +4 + union { + key_Type_TKIP_t TKIP; + key_Type_AES_t AES1; + key_Type_WEP_t WEP; + key_Type_WAPI_t WAPI; + key_Type_AES_CMAC_t iGTK; + } keyEncypt; // +6 +} key_MgtMaterial_t; + +#endif // __KEYAPISTADEFS_H__ diff --git a/src/include/bl602_wifi/modules/supplicant/bufferMgmtLib.h b/src/include/bl602_wifi/modules/supplicant/bufferMgmtLib.h new file mode 100644 index 0000000..0d9235e --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/bufferMgmtLib.h @@ -0,0 +1,20 @@ +#ifndef _BUFFERMGMTLIB_H_ +#define _BUFFERMGMTLIB_H_ + +#include + + +typedef void (*BufferReturnNotify_t)(void); + +struct BufferDesc { + union { + uint32 Interface; + struct cm_ConnectionInfo *connPtr; + } intf; // +0 + uint16 DataLen; // +4 + void *Buffer; // +8 +}; + +typedef struct BufferDesc BufferDesc_t; + +#endif // _BUFFERMGMTLIB_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/customApp_mib.h b/src/include/bl602_wifi/modules/supplicant/customApp_mib.h new file mode 100644 index 0000000..89a1f1e --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/customApp_mib.h @@ -0,0 +1,24 @@ +#ifndef _CUSTOMAPP_MIB_H_ +#define _CUSTOMAPP_MIB_H_ + +#include +#include +#include + + +typedef struct { + UINT8 RSNEnabled:1; // +0 + UINT8 pmkidValid:1; // +0 + UINT8 rsnCapValid:1; // +0 + UINT8 grpMgmtCipherValid:1; // +0 + UINT8 rsvd:4; // +0 + SecurityMode_t wpaType; // +1 + Cipher_t mcstCipher; // +3 + Cipher_t ucstCipher; // +4 + AkmSuite_t AKM; // +5 + UINT8 PMKID[16]; // +9 + IEEEtypes_RSNCapability_t rsnCap; // +25 + Cipher_t grpMgmtCipher; // +27 +} RSNConfig_t; + +#endif // _CUSTOMAPP_MIB_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes.h b/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes.h new file mode 100644 index 0000000..2314295 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes.h @@ -0,0 +1,12 @@ +#ifndef _KEYAPISTATYPES_H_ +#define _KEYAPISTATYPES_H_ + +#include + + +struct cipher_key_buf { + cipher_key_t cipher_key; // +0 +}; +typedef struct cipher_key_buf cipher_key_buf_t; + +#endif // _KEYAPISTATYPES_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes_rom.h b/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes_rom.h new file mode 100644 index 0000000..0519c19 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyApiStaTypes_rom.h @@ -0,0 +1,23 @@ +#ifndef _KEYAPISTATYPES_ROM_H_ +#define _KEYAPISTATYPES_ROM_H_ + +#include +#include + + +typedef struct { + UINT8 ANonce[32]; // +0 + KeyData_t pwsKeyData; // +32 +} eapolHskData_t; + +union ckd { + eapolHskData_t hskData; +}; + +struct cipher_key_t { + union ckd ckd; // +0 +}; + +typedef struct cipher_key_t cipher_key_t; + +#endif // _KEYAPISTATYPES_ROM_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyApiSta_rom.h b/src/include/bl602_wifi/modules/supplicant/keyApiSta_rom.h new file mode 100644 index 0000000..f8df686 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyApiSta_rom.h @@ -0,0 +1,4 @@ +#ifndef _KEYAPISTA_ROM_H_ +#define _KEYAPISTA_ROM_H_ + +#endif // _KEYAPISTA_ROM_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes.h new file mode 100644 index 0000000..6890142 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes.h @@ -0,0 +1,21 @@ +#ifndef _KEYMGMTAPTYPES_H_ +#define _KEYMGMTAPTYPES_H_ + +#include +#include +#include + + +typedef struct { + apKeyMgmtInfoStaRom_t rom; // +0 + UINT8 numHskTries; // +8 + UINT32 counterLo; // +12 + UINT32 counterHi; // +16 + struct mm_timer_tag HskTimer; // +20 + UINT8 EAPOL_MIC_Key[16]; // +36 + UINT8 EAPOL_Encr_Key[16]; // +52 + UINT8 EAPOLProtoVersion; // +68 + UINT8 rsvd[3]; // +69 +} apKeyMgmtInfoSta_t; + +#endif // _KEYMGMTAPTYPES_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes_rom.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes_rom.h new file mode 100644 index 0000000..b37df6c --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtApTypes_rom.h @@ -0,0 +1,30 @@ +#ifndef _KEYMGMTAPTYPES_ROM_H_ +#define _KEYMGMTAPTYPES_ROM_H_ + +#include +#include + + +typedef enum { + HSK_NOT_STARTED = 0, + MSG1_PENDING = 1, + WAITING_4_MSG2 = 2, + MSG3_PENDING = 3, + WAITING_4_MSG4 = 4, + GRPMSG1_PENDING = 5, + WAITING_4_GRPMSG2 = 6, + GRP_REKEY_MSG1_PENDING = 7, + WAITING_4_GRP_REKEY_MSG2 = 8, + HSK_DUMMY_STATE = 9, + HSK_END = 10, +} keyMgmtState_e; + +typedef struct { + UINT16 staRsnCap; // +0 + SecurityMode_t staSecType; // +2 + Cipher_t staUcstCipher; // +4 + UINT8 staAkmType; // +5 + keyMgmtState_e keyMgmtState; // +6 +} apKeyMgmtInfoStaRom_t; + +#endif // _KEYMGMTAPTYPES_ROM_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtCommon.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtCommon.h new file mode 100644 index 0000000..267ad7c --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtCommon.h @@ -0,0 +1,72 @@ +#ifndef _KEYMGMTCOMMON_H_ +#define _KEYMGMTCOMMON_H_ + +#include +#include + + +typedef struct { + UINT8 protocol_ver; // +0 + IEEEtypes_8021x_PacketType_e pckt_type; // +1 + UINT16 pckt_body_len; // +2 +} Hdr_8021x_t; + +typedef struct { + UINT16 KeyMIC:1; // +0 + UINT16 Secure:1; // +0 + UINT16 Error:1; // +0 + UINT16 Request:1; // +0 + UINT16 EncryptedKeyData:1; // +0 + UINT16 Reserved:3; // +0 + UINT16 KeyDescriptorVersion:3; // +0 + UINT16 KeyType:1; // +0 + UINT16 KeyIndex:2; // +0 + UINT16 Install:1; // +0 + UINT16 KeyAck:1; // +0 +} key_info_t; + +typedef struct { + UINT8 KeyID:2; // +0 + UINT8 Tx:1; // +0 + UINT8 rsvd:5; // +0 + UINT8 rsvd1; // +1 + UINT8 GTK[1]; // +2 +} GTK_KDE_t; + +typedef struct { + UINT8 type; // +0 + UINT8 length; // +1 + UINT8 OUI[3]; // +2 + UINT8 dataType; // +5 + UINT8 data[1]; // +6 +} KDE_t; + +typedef struct { + Hdr_8021x_t hdr_8021x; // +0 + UINT8 desc_type; // +4 + key_info_t key_info; // +5 + UINT16 key_length; // +7 + UINT32 replay_cnt[2]; // +9 + UINT8 key_nonce[32]; // +17 + UINT8 EAPOL_key_IV[16]; // +49 + UINT8 key_RSC[8]; // +65 + UINT8 key_ID[8]; // +73 + UINT8 key_MIC[16]; // +81 + UINT16 key_material_len; // +97 + UINT8 key_data[1]; // +99 +} EAPOL_KeyMsg_t; + +typedef struct { + Hdr_8021x_t hdr_8021x; // +0 + IEEEtypes_8021x_CodeType_e code; // +4 + UINT8 identifier; // +5 + UINT16 length; // +6 + UINT8 data[1]; // +8 +} EAP_PacketMsg_t; + +typedef struct { + ether_hdr_t ethHdr; // +0 + EAPOL_KeyMsg_t keyMsg; // +14 +} EAPOL_KeyMsg_Tx_t; + +#endif // __KEYMGMTCOMMON_H__ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtSta.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtSta.h new file mode 100644 index 0000000..ef042f7 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtSta.h @@ -0,0 +1,37 @@ +#ifndef _KEYMGMTSTA_H_ +#define _KEYMGMTSTA_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + + +struct supplicantData { + BOOLEAN inUse; // +0 + IEEEtypes_SsIdElement_t hashSsId; // +4 + IEEEtypes_MacAddr_t localBssid; // +38 + IEEEtypes_MacAddr_t localStaAddr; // +44 + customMIB_RSNStats_t customMIB_RSNStats; // +50 + RSNConfig_t customMIB_RSNConfig; // +53 + keyMgmtInfoSta_t keyMgmtInfoSta; // +84 + SecurityParams_t currParams; // +408 +}; +typedef struct supplicantData supplicantData_t; + + +BOOLEAN supplicantAkmIsWpaWpa2(AkmSuite_t *pAkm); +BOOLEAN supplicantAkmIsWpaWpa2Psk(AkmSuite_t *pAkm); +BOOLEAN supplicantAkmUsesKdf(AkmSuite_t *pAkm); +void UpdateEAPOLWcbLenAndTransmit(BufferDesc_t *pBufDesc, UINT16 frameLen); +BufferDesc_t *GetTxEAPOLBuffer(cm_ConnectionInfo_t *connPtr, EAPOL_KeyMsg_Tx_t **ppTxEapol, BufferDesc_t *pBufDesc); +void allocSupplicantData(void *connectionPtr); +void supplicantEnable(void *connectionPtr, int security_mode, void *mcstCipher, void *ucstCipher, bool is_pmf_required); +void supplicantDisable(cm_ConnectionInfo_t *connPtr); +uint8_t add_key_to_mac(cm_ConnectionInfo_t *connPtr, UINT8 pairwise); + +#endif // _KEYMGMTSTA_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtStaHostTypes_rom.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtStaHostTypes_rom.h new file mode 100644 index 0000000..844773a --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtStaHostTypes_rom.h @@ -0,0 +1,16 @@ +#ifndef _KEYMGMTSTAHOSTTYPES_ROM_H_ +#define _KEYMGMTSTAHOSTTYPES_ROM_H_ + +#include + + +typedef struct { + UINT8 Key[16]; // +0 + UINT8 RxMICKey[8]; // +16 + UINT8 TxMICKey[8]; // +24 + UINT32 TxIV32; // +32 + UINT16 TxIV16; // +36 + UINT16 KeyIndex; // +38 +} KeyData_t; + +#endif // _KEYMGMTSTAHOSTTYPES_ROM_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtStaTypes.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtStaTypes.h new file mode 100644 index 0000000..50cf7a2 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtStaTypes.h @@ -0,0 +1,56 @@ +#ifndef _KEYMGMTSTATYPES_H_ +#define _KEYMGMTSTATYPES_H_ + +#include + + +typedef struct { + UINT8 wep40:1; // +0 + UINT8 wep104:1; // +0 + UINT8 tkip:1; // +0 + UINT8 ccmp:1; // +0 + UINT8 rsvd:4; // +0 +} Cipher_t; + +typedef struct { + UINT16 noRsn:1; // +0 + UINT16 wepStatic:1; // +0 + UINT16 wepDynamic:1; // +0 + UINT16 wpa:1; // +0 + UINT16 wpaNone:1; // +0 + UINT16 wpa2:1; // +0 + UINT16 cckm:1; // +0 + UINT16 wapi:1; // +0 + UINT16 wpa3:1; // +0 + UINT16 rsvd:7; // +0 +} SecurityMode_t; + +typedef enum { + AKM_NONE = 0, + AKM_1X = 1, + AKM_PSK = 2, + AKM_FT_1X = 3, + AKM_FT_PSK = 4, + AKM_SHA256_1X = 5, + AKM_SHA256_PSK = 6, + AKM_TDLS = 7, + AKM_CCKM = 99, + AKM_WPA_MAX = 2, + AKM_RSN_MAX = 6, + AKM_SUITE_MAX = 5, +} AkmType_e; + +typedef AkmType_e AkmTypePacked_e; + +typedef struct { + UINT8 akmOui[3]; // +0 + AkmTypePacked_e akmType; // +3 +} AkmSuite_t; + +typedef struct { + SecurityMode_t wpaType; // +0 + Cipher_t mcstCipher; // +2 + Cipher_t ucstCipher; // +3 +} SecurityParams_t; + +#endif // _KEYMGMTSTATYPES_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtSta_rom.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtSta_rom.h new file mode 100644 index 0000000..2597dba --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtSta_rom.h @@ -0,0 +1,117 @@ +#ifndef _KEYMGMTSTA_ROM_H_ +#define _KEYMGMTSTA_ROM_H_ + +#include +#include +#include +#include +#include +#include +#include + + +typedef enum { + NO_MIC_FAILURE = 0, + FIRST_MIC_FAIL_IN_60_SEC = 1, + SECOND_MIC_FAIL_IN_60_SEC = 2, +} MIC_Fail_State_e; + +typedef struct { + MIC_Fail_State_e status; // +0 + BOOLEAN MICCounterMeasureEnabled; // +4 + UINT32 disableStaAsso; // +8 +} MIC_Error_t; + +typedef struct { + UINT8 TKIPICVErrors; // +0 + UINT8 TKIPLocalMICFailures; // +1 + UINT8 TKIPCounterMeasuresInvoked; // +2 +} customMIB_RSNStats_t; + +typedef struct { + UINT8 ANonce[32]; // +0 + UINT8 SNonce[32]; // +32 + UINT8 EAPOL_MIC_Key[16]; // +64 + UINT8 EAPOL_Encr_Key[16]; // +80 + UINT32 apCounterLo; // +96 + UINT32 apCounterHi; // +100 + UINT32 apCounterZeroDone; // +104 + UINT32 staCounterLo; // +108 + UINT32 staCounterHi; // +112 + BOOLEAN RSNDataTrafficEnabled; // +116 + BOOLEAN RSNSecured; // +120 + BOOLEAN pwkHandshakeComplete; // +124 + cipher_key_t *pRxDecryptKey; // +128 + KeyData_t PWKey; // +132 + KeyData_t GRKey; // +172 + KeyData_t newPWKey; // +212 + MIC_Error_t sta_MIC_Error; // +252 + struct mm_timer_tag rsnTimer; // +264 + struct cm_ConnectionInfo *connPtr; // +280 + KeyData_t IGtk; // +284 +} keyMgmtInfoSta_t; + +typedef struct { + UINT8 kck[16]; // +0 + UINT8 kek[16]; // +16 + UINT8 tk[16]; // +32 + UINT8 rxMicKey[8]; // +48 + UINT8 txMicKey[8]; // +56 +} TkipPtk_t; + + +void updateApReplayCounter(keyMgmtInfoSta_t *pKeyMgmtStaInfo, UINT8 *pRxReplayCount); +void formEAPOLEthHdr(EAPOL_KeyMsg_Tx_t *pTxEapol, IEEEtypes_MacAddr_t *da, IEEEtypes_MacAddr_t *sa); + + +extern BOOLEAN (*ComputeEAPOL_MIC_hook)(EAPOL_KeyMsg_t*, UINT16, UINT8*, UINT8, UINT8); +extern BOOLEAN (*FillKeyMaterialStruct_internal_hook)(key_MgtMaterial_t*, UINT16, UINT8, KeyData_t*); +extern BOOLEAN (*supplicantSetAssocRsn_internal_hook)(RSNConfig_t*, SecurityParams_t*, SecurityMode_t, Cipher_t*, Cipher_t*, AkmSuite_t*, IEEEtypes_RSNCapability_t*, Cipher_t*); +extern BOOLEAN (*keyMgmtFormatWpaRsnIe_internal_hook)(RSNConfig_t*, UINT8*, IEEEtypes_MacAddr_t*, IEEEtypes_MacAddr_t*, UINT8*, BOOLEAN, UINT16*); +extern BOOLEAN (*install_wpa_none_keys_internal_hook)(key_MgtMaterial_t*, UINT8*, UINT8, UINT8); +extern BOOLEAN (*keyMgmtGetKeySize_internal_hook)(RSNConfig_t*, UINT8, UINT16*); + + +UINT16 keyMgmtGetKeySize_internal(RSNConfig_t *pRsnConfig, UINT8 isPairwise); + + +extern BOOLEAN (*parseKeyKDE_DataType_hook)(UINT8*, SINT32, IEEEtypes_KDEDataType_e, UINT32*); +extern BOOLEAN (*parseKeyDataGTK_hook)(UINT8*, UINT16, KeyData_t*, UINT32*); + + +BOOLEAN IsEAPOL_MICValid(EAPOL_KeyMsg_t *pKeyMsg, UINT8 *pMICKey); + + +extern BOOLEAN (*KeyMgmtSta_ApplyKEK_hook)(EAPOL_KeyMsg_t*, KeyData_t*, UINT8*); +extern BOOLEAN (*KeyMgmtSta_IsRxEAPOLValid_hook)(keyMgmtInfoSta_t*, EAPOL_KeyMsg_t*, BOOLEAN*); +extern BOOLEAN (*KeyMgmtSta_PrepareEAPOLFrame_hook)(EAPOL_KeyMsg_Tx_t*, EAPOL_KeyMsg_t*, IEEEtypes_MacAddr_t*, IEEEtypes_MacAddr_t*, UINT8*); + + +void KeyMgmtSta_PrepareEAPOLFrame(EAPOL_KeyMsg_Tx_t *pTxEapol, EAPOL_KeyMsg_t *pRxEapol, IEEEtypes_MacAddr_t *da, IEEEtypes_MacAddr_t *sa, UINT8 *pSNonce); + + +extern BOOLEAN (*KeyMgmtSta_PopulateEAPOLLengthMic_hook)(EAPOL_KeyMsg_Tx_t*, UINT8*, UINT8, UINT8, UINT16*); + + +UINT16 KeyMgmtSta_PopulateEAPOLLengthMic(EAPOL_KeyMsg_Tx_t *pTxEapol, UINT8 *pEAPOLMICKey, UINT8 eapolProtocolVersion, UINT8 forceKeyDescVersion); + + +extern BOOLEAN (*KeyMgmtSta_PrepareEAPOLMicErrFrame_hook)(EAPOL_KeyMsg_Tx_t*, BOOLEAN, IEEEtypes_MacAddr_t*, IEEEtypes_MacAddr_t*, keyMgmtInfoSta_t*); + + +void KeyMgmtSta_DeriveKeys(UINT8 *pPMK, IEEEtypes_MacAddr_t *da, IEEEtypes_MacAddr_t *sa, UINT8 *ANonce, UINT8 *SNonce, UINT8 *EAPOL_MIC_Key, UINT8 *EAPOL_Encr_Key, KeyData_t *newPWKey, BOOLEAN use_kdf); +void SetEAPOLKeyDescTypeVersion(EAPOL_KeyMsg_Tx_t *pTxEapol, BOOLEAN isWPA2, BOOLEAN isKDF, BOOLEAN nonTKIP); +void KeyMgmtResetCounter(keyMgmtInfoSta_t *pKeyMgmtInfo); +void keyMgmtSta_StartSession_internal(keyMgmtInfoSta_t *pKeyMgmtInfoSta, UINT32 expiry); + + +extern BOOLEAN (*ramHook_keyMgmtProcessMsgExt)(keyMgmtInfoSta_t*, EAPOL_KeyMsg_t*); +extern void (*ramHook_keyMgmtSendDeauth)(void*, UINT16); + + +EAPOL_KeyMsg_t *GetKeyMsgNonceFromEAPOL(BufferDesc_t *pEAPoLBufDesc, keyMgmtInfoSta_t *pKeyMgmtInfoSta); +EAPOL_KeyMsg_t *ProcessRxEAPOL_PwkMsg3(BufferDesc_t *pEAPoLBufDesc, keyMgmtInfoSta_t *pKeyMgmtInfoSta); +EAPOL_KeyMsg_t *ProcessRxEAPOL_GrpMsg1(BufferDesc_t *pEAPoLBufDesc, keyMgmtInfoSta_t *pKeyMgmtInfoSta); +void KeyMgmtSta_InitSession(keyMgmtInfoSta_t *pKeyMgmtInfoSta); + +#endif // _KEYMGMTSTA_ROM_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/keyMgmtStatTypes.h b/src/include/bl602_wifi/modules/supplicant/keyMgmtStatTypes.h new file mode 100644 index 0000000..43b270e --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/keyMgmtStatTypes.h @@ -0,0 +1,56 @@ +#ifndef _KEYMGMTSTATYPES_H_ +#define _KEYMGMTSTATYPES_H_ + +#include + + +typedef struct { + UINT8 wep40:1; // +0 + UINT8 wep104:1; // +0 + UINT8 tkip:1; // +0 + UINT8 ccmp:1; // +0 + UINT8 rsvd:4; // +0 +} Cipher_t; + +typedef struct { + UINT16 noRsn:1; // +0 + UINT16 wepStatic:1; // +0 + UINT16 wepDynamic:1; // +0 + UINT16 wpa:1; // +0 + UINT16 wpaNone:1; // +0 + UINT16 wpa2:1; // +0 + UINT16 cckm:1; // +0 + UINT16 wapi:1; // +0 + UINT16 wpa3:1; // +0 + UINT16 rsvd:7; // +0 +} SecurityMode_t; + +typedef enum { + AKM_NONE = 0, + AKM_1X = 1, + AKM_PSK = 2, + AKM_FT_1X = 3, + AKM_FT_PSK = 4, + AKM_SHA256_1X = 5, + AKM_SHA256_PSK = 6, + AKM_TDLS = 7, + AKM_CCKM = 99, + AKM_WPA_MAX = 2, + AKM_RSN_MAX = 6, + AKM_SUITE_MAX = 5, +} AkmType_e; + +typedef AkmType_e AkmTypePacked_e; + +typedef struct { + UINT8 akmOui[3]; // +0 + AkmTypePacked_e akmType; // +3 +} AkmSuite_t; + +typedef struct { + SecurityMode_t wpaType; // +0 + Cipher_t mcstCipher; // +2 + Cipher_t ucstCipher; // +3 +} SecurityParams_t; + +#endif diff --git a/src/include/bl602_wifi/modules/supplicant/macMgmtMain.h b/src/include/bl602_wifi/modules/supplicant/macMgmtMain.h new file mode 100644 index 0000000..004e5e3 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/macMgmtMain.h @@ -0,0 +1,86 @@ +#ifndef _MACMGMTMAIN_H_ +#define _MACMGMTMAIN_H_ + +#include +#include +#include +#include +#include +#include + + +typedef struct { + IEEEtypes_SsId_t SsId; // +0 + IEEEtypes_Len_t SsIdLen; // +32 + IEEEtypes_DtimPeriod_t DtimPeriod; // +33 + IEEEtypes_BcnInterval_t BcnPeriod; // +34 + IEEEtypes_MacAddr_t BssId; // +36 + UINT16 RtsThresh; // +42 + UINT16 FragThresh; // +44 + UINT8 ShortRetryLim; // +46 + UINT8 LongRetryLim; // +47 + UINT8 MbssBcnIntFac; // +48 + UINT8 MbssCurBcnIntCnt; // +49 + UINT16 Reserved; // +50 +} CommonMlmeData_t; + +struct _txQingInfo_t { + IEEEtypes_PwrMgmtMode_e mode; // +0 +}; + +typedef struct _txQingInfo_t txQingInfo_t; + +typedef struct { + UINT16 keyExchange:1; // +0 + UINT16 authenticate:1; // +0 + UINT16 reserved:14; // +0 +} Operation_t; + +typedef struct { + Cipher_t mcstCipher; // +0 + UINT8 mcstCipherCount; // +1 + Cipher_t wpaUcstCipher; // +2 + UINT8 wpaUcstCipherCount; // +3 + Cipher_t wpa2UcstCipher; // +4 + UINT8 wpa2UcstCipherCount; // +5 + UINT16 AuthKey; // +6 + UINT16 AuthKeyCount; // +8 + Operation_t Akmp; // +10 + UINT32 GrpReKeyTime; // +12 + UINT8 PSKPassPhrase[64]; // +16 + UINT8 PSKPassPhraseLen; // +80 + UINT8 PSKValue[32]; // +81 + UINT8 MaxPwsHskRetries; // +113 + UINT8 MaxGrpHskRetries; // +114 + UINT32 PwsHskTimeOut; // +116 + UINT32 GrpHskTimeOut; // +120 +} apRsnConfig_t; + +typedef struct { + UINT32 StaAgeOutTime; // +0 + UINT32 PsStaAgeOutTime; // +4 + apRsnConfig_t RsnConfig; // +8 + CommonMlmeData_t comData; // +132 +} BssConfig_t; + +typedef struct { + BOOLEAN updatePassPhrase; // +0 + struct mm_timer_tag apMicTimer; // +4 + KeyData_t grpKeyData; // +20 + UINT8 GNonce[32]; // +60 + UINT32 grpRekeyBcnCntConfigured; // +92 + UINT32 grpRekeyBcnCntRemaining; // +96 +} BssData_t; + +typedef struct { + txQingInfo_t pwrSaveInfo; // +0 + apKeyMgmtInfoSta_t keyMgmtInfo; // +4 +} staData_t; + +typedef struct { + BssConfig_t bssConfig; // +0 + BssData_t bssData; // +184 + UINT8 ApStop_Req_Pending; // +284 +} apInfo_t; + +#endif // _MACMGMTMAIN_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/nohostSecurityParams.h b/src/include/bl602_wifi/modules/supplicant/nohostSecurityParams.h new file mode 100644 index 0000000..c32adf5 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/nohostSecurityParams.h @@ -0,0 +1,18 @@ +#ifndef _NOHOSTSECURITYPARAMS_H_ +#define _NOHOSTSECURITYPARAMS_H_ + +#include + + +typedef struct { + UINT8 CipherType; // +0 + UINT8 MulticastCipher; // +1 + UINT8 UnicastCipher; // +2 + char PSKPassPhrase[64]; // +3 +} NoHostSecurityParams_t; + + +void set_psk(char *pSsid, UINT8 ssidLen, char *phrase); +void remove_psk(char *pSsid, UINT8 ssidLen); + +#endif // _NOHOSTSECURITYPARAMS_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/w81connmgr.h b/src/include/bl602_wifi/modules/supplicant/w81connmgr.h new file mode 100644 index 0000000..ea85e32 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/w81connmgr.h @@ -0,0 +1,46 @@ +#ifndef _W81CONNMGR_H_ +#define _W81CONNMGR_H_ + +#include +#include +#include +#include + + +typedef struct { + apInfo_t *apInfo; // +0 + BufferDesc_t *apInfoBuffDesc; // +4 + ChanBandInfo_t chanBandInfo; // +8 + staData_t staData; // +12 +} apSpecificData_t; + +typedef struct cm_ConnectionInfo { + UINT8 conType; // +0 + UINT8 staId; // +1 + UINT8 instNbr; // +2 + UINT8 gtkHwKeyId; // +3 + UINT8 ptkHwKeyId; // +4 + UINT8 mfpHwKeyId; // +5 + struct supplicantData *suppData; // +8 + CommonMlmeData_t comData; // +12 + IEEEtypes_MacAddr_t peerMacAddr; // +64 + IEEEtypes_MacAddr_t localMacAddr; // +70 + union { + apSpecificData_t apData; + } specDat; // +76 + cipher_key_buf_t TxRxCipherKeyBuf; // +164 +} cm_ConnectionInfo_t; + + +extern cm_ConnectionInfo_t sta_conn_info; +extern cm_ConnectionInfo_t *uap_conn_info; + + +cm_ConnectionInfo_t *cm_InitConnection(UINT8 conType, UINT8 bssType, UINT8 bssNum, IEEEtypes_MacAddr_t *bssId, IEEEtypes_MacAddr_t *peerMacAddr, UINT8 channel, mdev_t *hostMdev); +void cm_DeleteConnection(cm_ConnectionInfo_t *connPtr); +void cm_SetPeerAddr(cm_ConnectionInfo_t *connPtr, IEEEtypes_MacAddr_t *bssId, IEEEtypes_MacAddr_t *peerMacAddr); +void cm_SetComData(cm_ConnectionInfo_t *connPtr, char *ssid); +apInfo_t *cm_GetApInfo(cm_ConnectionInfo_t *connPtr); +apSpecificData_t *cm_GetApData(cm_ConnectionInfo_t *connPtr); + +#endif // _W81CONNMGR_H_ diff --git a/src/include/bl602_wifi/modules/supplicant/wltypes.h b/src/include/bl602_wifi/modules/supplicant/wltypes.h new file mode 100644 index 0000000..227e628 --- /dev/null +++ b/src/include/bl602_wifi/modules/supplicant/wltypes.h @@ -0,0 +1,43 @@ +#ifndef _WLTYPES_H_ +#define _WLTYPES_H_ + +#include + + +typedef long long unsigned int UINT64; +typedef long unsigned int UINT32; +typedef long int SINT32; +typedef short unsigned int UINT16; +typedef short int SINT16; +typedef unsigned char UINT8; +typedef signed char SINT8; +typedef long unsigned int uint32; +typedef int sint32; +typedef short unsigned int uint16; +typedef unsigned char uint8; +typedef int BOOLEAN; +typedef char CHAR; + +typedef enum { + FW_SUCCESS = 0, + FAIL = 1 +} Status_e; + +typedef void mdev_t; + +enum wlan_security_type { + WLAN_SECURITY_NONE = 0, + WLAN_SECURITY_WEP_OPEN = 1, + WLAN_SECURITY_WEP_SHARED = 2, + WLAN_SECURITY_WPA = 3, + WLAN_SECURITY_WPA2 = 4, + WLAN_SECURITY_WPA_WPA2_MIXED = 5, + WLAN_SECURITY_EAP_TLS = 6, + WLAN_SECURITY_WILDCARD = 7 +}; + + +uint16_t mm_get_rsn_wpa_ie(uint8_t sta_id, uint8_t *wpa_ie); +void sm_handle_supplicant_result(uint8_t sta_id, uint16_t reason_code); + +#endif // _WLTYPES_H_ diff --git a/src/include/bl602_wifi/phy_rf/bl602_rf_calib_data.h b/src/include/bl602_wifi/phy_rf/bl602_rf_calib_data.h new file mode 100644 index 0000000..72faa65 --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/bl602_rf_calib_data.h @@ -0,0 +1,58 @@ +#ifndef _BL602_RF_CALIB_DATA_H_ +#define _BL602_RF_CALIB_DATA_H_ +#include +typedef struct { + uint32_t gpadc_oscode:12; // +0 + uint32_t rx_offset_i:10; // +0 + uint32_t rx_offset_q:10; // +0 + uint32_t rbb_cap1_fc_i:6; // +4 + uint32_t rbb_cap1_fc_q:6; // +4 + uint32_t rbb_cap2_fc_i:6; // +4 + uint32_t rbb_cap2_fc_q:6; // +4 + uint32_t tx_dc_comp_i:12; // +8 + uint32_t tx_dc_comp_q:12; // +8 + uint32_t tmx_cs:3; // +8 + uint32_t txpwr_att_rec:3; // +8 + uint32_t pa_pwrmx_osdac:4; // +12 + uint32_t tmx_csh:3; // +12 + uint32_t tmx_csl:3; // +12 + uint32_t tsen_refcode_rfcal:12; // +12 + uint32_t tsen_refcode_corner:12; // +16 + uint32_t rc32k_code_fr_ext:10; // +16 + uint32_t rc32m_code_fr_ext:8; // +16 + uint32_t saradc_oscode:10; // +20 + uint16_t fcal_4osmx:4; // +20 +} rf_calib1_tag; // :37:3 + +typedef struct { + uint16_t fcal:8; // +0 + uint16_t acal:5; // +0 +} rf_calib2_tag; // :44:3 + +typedef struct { + uint32_t rosdac_i:6; // +0 + uint32_t rosdac_q:6; // +0 + uint32_t rx_iq_gain_comp:11; // +0 + uint32_t rx_iq_phase_comp:10; // +4 +} rf_calib3_tag; // :53:3 + +typedef struct { + uint32_t tosdac_i:6; // +0 + uint32_t tosdac_q:6; // +0 + uint32_t tx_iq_gain_comp:11; // +0 + uint32_t tx_iq_phase_comp:10; // +4 +} rf_calib4_tag; // :62:3 + +typedef volatile struct { + uint32_t inited; // +0 + rf_calib1_tag cal; // +4 + rf_calib2_tag lo[21]; // +28 + rf_calib3_tag rxcal[4]; // +72 + rf_calib4_tag txcal[8]; // +104 +} rf_calib_data_tag; // :72:3 + +extern rf_calib_data_tag *rf_calib_data; // :75:27 +// void rf_pri_init_calib_mem(void); +// unused + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/bl602_rf_private.h b/src/include/bl602_wifi/phy_rf/bl602_rf_private.h new file mode 100644 index 0000000..0ac7f1e --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/bl602_rf_private.h @@ -0,0 +1,156 @@ +#ifndef _BL602_RF_PRIVATE_H_ +#define _BL602_RF_PRIVATE_H_ +#include +#define RF_PRIVATE_PRESENT 1 +struct anon_struct1 { + uint32_t index; + int32_t dvga; +}; + +typedef struct anon_struct1 anon_struct1; + +struct anon_struct { + uint32_t vbcore; + uint32_t iet; + uint32_t vbcore_11n; + uint32_t iet_11n; + uint32_t vbcore_11g; + uint32_t iet_11g; + uint32_t vbcore_11b; + uint32_t iet_11b; + uint32_t lo_fbdv_halfstep_en; + uint32_t lo_fbdv_halfstep_en_tx; + uint32_t lo_fbdv_halfstep_en_rx; + uint32_t clkpll_reset_postdiv; + uint32_t clkpll_dither_sel; +}; + +struct notch_param { + uint32_t notch_en; + int32_t spur_freq; +}; + +typedef struct notch_param notch_param; + +struct regs_to_opti { + uint32_t vbcore; + uint32_t iet; + uint32_t vbcore_11n; + uint32_t iet_11n; + uint32_t vbcore_11g; + uint32_t iet_11g; + uint32_t vbcore_11b; + uint32_t iet_11b; + uint32_t lo_fbdv_halfstep_en; + uint32_t lo_fbdv_halfstep_en_tx; + uint32_t lo_fbdv_halfstep_en_rx; + uint32_t clkpll_reset_postdiv; + uint32_t clkpll_dither_sel; +}; + +typedef struct regs_to_opti regs_to_opti; + +struct tx_pwr_index { + uint32_t index; + int32_t dvga; +}; + +typedef struct tx_pwr_index tx_pwr_index; + +void rf_pri_config_bandwidth(uint32_t bw); +void rf_pri_fcal(void); +void rf_pri_full_cal(void); +void rf_pri_get_notch_param(uint32_t chanfreq_MHz, uint8_t * ncf_on, int32_t * ncf_freq_Hz); +uint32_t rf_pri_get_txgain_index(int32_t pwr, uint32_t mode); +int32_t rf_pri_get_txgain_max(void); +int32_t rf_pri_get_txgain_min(void); +uint32_t rf_pri_get_vco_freq_cw(uint32_t chanfreq_MHz); +uint32_t rf_pri_get_vco_idac_cw(uint32_t chanfreq_MHz); +void rf_pri_init(uint8_t reset, uint8_t chipv); +void rf_pri_init_fast(uint32_t flag); +void rf_pri_lo_acal(void); +void rf_pri_query_txgain_table(uint32_t index, uint32_t * rfg_index, uint32_t * dg); +void rf_pri_rccal(void); +void rf_pri_tx_gain_comp(int32_t Tsens); +void rf_pri_txcal(void); +void rf_pri_update_param(uint32_t chanfreq_MHz); +void rf_pri_update_power_offset(int32_t * power_offset); +void rf_pri_update_tx_power_offset(uint8_t channel, int8_t * power_offset); +void rf_pri_update_txgain_tempos(int16_t tempos); +void rf_pri_xtalfreq(uint32_t xtalfreq); + +enum { + E_RF_XTAL_24M = 0, + E_RF_XTAL_26M = 1, + E_RF_XTAL_32M = 2, + E_RF_XTAL_38M4 = 3, + E_RF_XTAL_40M = 4, + E_RF_XTAL_52M = 5, +}; + +enum +{ + E_RF_CHANNEL_2404M = 0, + E_RF_CHANNEL_2408M, + E_RF_CHANNEL_2412M, + E_RF_CHANNEL_2416M, + E_RF_CHANNEL_2420M, + E_RF_CHANNEL_2424M, + E_RF_CHANNEL_2428M, + E_RF_CHANNEL_2432M, + E_RF_CHANNEL_2436M, + E_RF_CHANNEL_2440M, + E_RF_CHANNEL_2444M, + E_RF_CHANNEL_2448M, + E_RF_CHANNEL_2452M, + E_RF_CHANNEL_2456M, + E_RF_CHANNEL_2460M, + E_RF_CHANNEL_2464M, + E_RF_CHANNEL_2468M, + E_RF_CHANNEL_2472M, + E_RF_CHANNEL_2476M, + E_RF_CHANNEL_2480M, + E_RF_CHANNEL_2484M, + E_RF_CHANNEL_NUM +}; + +enum { + E_RF_BRANCH_I = 0, + E_RF_BRANCH_Q = 1, + E_RF_GAIN = 2, + E_RF_PHASE = 3 +}; + +enum { + E_RF_MODE_11B = 0, + E_RF_MODE_11G = 1, + E_RF_MODE_11N = 2, +}; + +enum { + E_RF_GC_TBB_0DB = 0, + E_RF_GC_TBB_6DB = 1, + E_RF_GC_TBB_12DB = 2, + E_RF_GC_TBB_18DB = 3, + E_RF_GC_TBB_24DB = 4 +}; + +enum { + E_RF_MODE_IDLE = 0, + E_RF_MODE_TX, + E_RF_MODE_RX, + E_RF_MODE_ROSCAL, + E_RF_MODE_RCCAL, + E_RF_MODE_TXCAL, + E_RF_MODE_LO_ACAL, + E_RF_MODE_LO_FCAL +}; + +enum { + E_RF_RXCAL_GAIN_CNT = 4, + E_RF_TXCAL_GAIN_CNT = 8, + E_RF_TXPWR_TBL_CNT = 16, +}; + + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy.h b/src/include/bl602_wifi/phy_rf/phy.h new file mode 100644 index 0000000..2a646a4 --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy.h @@ -0,0 +1,74 @@ +#ifndef _PHY_H_ +#define _PHY_H_ +#include + + +/// Invalid value for some octet parameters reserved for the future +#define PHY_UNUSED 0xFF + +/// Maximum number of words in the configuration buffer +#define PHY_CFG_BUF_SIZE 16 + + +/* + * DEFINES + **************************************************************************************** + */ +/// Invalid value for some octet parameters reserved for the future +#define PHY_UNUSED 0xFF + +/// Maximum number of words in the configuration buffer +#define PHY_CFG_BUF_SIZE 16 + +enum +{ + /// 2.4GHz Band + PHY_BAND_2G4, + /// 5GHz band + PHY_BAND_5G, + /// Number of bands + PHY_BAND_MAX, +}; + +enum +{ + PHY_CHNL_BW_20, + PHY_CHNL_BW_40, + PHY_CHNL_BW_80, + PHY_CHNL_BW_160, + PHY_CHNL_BW_80P80, + PHY_CHNL_BW_OTHER, +}; + +enum +{ + /// Primary radar detection chain (i.e for the operating channel) + PHY_PRIM, + /// Secondary radar detection chain + PHY_SEC, +}; + +/// Structure containing the information about the PHY channel that was used for this RX +struct phy_channel_info +{ + /// PHY channel information 1 + uint32_t info1; + /// PHY channel information 2 + uint32_t info2; +}; + +struct phy_radar_pulse +{ + /// In our PHY a radar pulse is only one 32-bit word + uint32_t pulse; +}; + +/// Structure containing the parameters of the PHY configuration +struct phy_cfg_tag +{ + /// Buffer containing the parameters specific for the PHY used + uint32_t parameters[PHY_CFG_BUF_SIZE]; +}; + +typedef struct phy_cfg_tag phy_cfg_tag; +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_adapt.h b/src/include/bl602_wifi/phy_rf/phy_adapt.h new file mode 100644 index 0000000..72e6bfa --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_adapt.h @@ -0,0 +1,97 @@ +#ifndef _PHY_ADAPT_H_ +#define _PHY_ADAPT_H_ +#include +#include + +typedef struct { + int8_t rssi; // +0 + int8_t lna; // +1 + float ppm; // +4 + uint8_t new; // +8 +} input_t; // :53:3 + +typedef struct { + uint8_t used; // +0 + uint32_t vif_tag; // +4 + input_t input_buffer[8]; // +8 + int8_t input_buffer_ptr; // +104 + // input_buffer is something like a ring buffer + // input_buffer[input_buffer_ptr] is the in-coming data buffer + // and input_buffer[input_buffer_ptr -1, -2, -3, ..., -6] + // are available datas + // the most recent one is input_buffer[input_buffer_ptr -1] + // wrapped by math mod + uint32_t last_update; // +108 + int8_t rss; // +112 + int8_t rss_acq; // +113 + int8_t rss_trk; // +114 + int8_t rss_state; // +115 + uint8_t rss_hit_count; // +116 + uint32_t rss_count; // +120 + int8_t ris; // +124 + float ce; // +128 + int8_t ce_in; // +132 + int8_t ce_acq; // +133 + int8_t ce_trk; // +134 + int8_t ce_state; // +135 + int8_t ce_num_up_cmds; // +136 + int8_t ce_num_dn_cmds; // +137 +} pa_state_t; // :83:3 + +typedef struct { + uint32_t leg_length:12; // +0 + uint32_t leg_rate:4; // +0 + uint32_t ht_length:16; // +0 + + uint32_t _ht_length:4; // +4 + uint32_t short_gi:1; // +4 + uint32_t stbc:2; // +4 + uint32_t smoothing:1; // +4 + uint32_t mcs:7; // +4 + uint32_t pre_type:1; // +4 + uint32_t format_mod:3; // +4 + uint32_t ch_bw:2; // +4 + uint32_t n_sts:3; // +4 + uint32_t lsig_valid:1; // +4 + uint32_t sounding:1; // +4 + uint32_t num_extn_ss:2; // +4 + uint32_t aggregation:1; // +4 + uint32_t fec_coding:1; // +4 + uint32_t dyn_bw:1; // +4 + uint32_t doze_not_allowed:1; // +4 + + uint32_t antenna_set:8; // +8 + uint32_t partial_aid:9; // +8 + uint32_t group_id:6; // +8 + uint32_t reserved_1c:1; // +8 + int32_t rssi1:8; // +8 + int32_t rssi2:8; // +12 + int32_t agc_lna:4; // +12 + int32_t agc_rbb1:5; // +12 + int32_t agc_dg:7; // +12 + uint32_t reserved_1d:8; // +12 + uint32_t rcpi:8; // +16 + uint32_t evm1:8; // +16 + uint32_t evm2:8; // +16 + union { + uint32_t freqoff:16; + struct { + uint32_t freqoff_lo:8; // +16 + uint32_t freqoff_hi:8; // +20 + }; + }; + uint32_t reserved2b_1:8; // +20 + uint32_t reserved2b_2:8; // +20 + uint32_t reserved2b_3:8; // +20 +} rvec_t; // :134:3 + +void pa_adapt(uint8_t id); +void pa_init(void); +void pa_input(uint8_t id, struct rx_hd *rhd); +int8_t pa_alloc(uint32_t vif_addr); +void pa_reset(uint8_t id); +void pa_free(uint8_t id); + +float calc_ppm_dsss(uint8_t rxv_freqoff); +float calc_ppm_ofdm(uint16_t rxv_freqoff); +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_bl602.h b/src/include/bl602_wifi/phy_rf/phy_bl602.h new file mode 100644 index 0000000..aaf911b --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_bl602.h @@ -0,0 +1,113 @@ +#ifndef _PHY_BL602_H_ +#include +#include + +/// Maximum output power TODO +#define PHY_BL602_MAX_PWR_24G (20) +/// Minimum output power TODO +#define PHY_BL602_MIN_PWR_24G (-6) +/// MAC core clock frequency in MHz +#define PHY_BL602_MACCORE_FREQ_MHZ (40) +/// AGC memory address and size +#define PHY_BL602_AGC_MEM_ADDR (0x54c0a000) +#define PHY_BL602_AGC_MEM_SIZE (2048) + +enum +{ + PHY_FORMATMOD_11B, + PHY_FORMATMOD_11G, + PHY_FORMATMOD_11N, +}; + +struct phy_bl602_cfg_tag { + uint32_t reserved; +}; // :48:8 + +struct phy_env_tag { + struct phy_bl602_cfg_tag cfg; + uint16_t chnl_prim20_freq; + uint16_t chnl_center1_freq; + uint16_t chnl_center2_freq; + uint8_t band; + uint8_t chnl_type; +}; // :54:8 + +void phy_config_rxgain(int offset); +uint8_t phy_get_mac_freq(); +void phy_get_channel(struct phy_channel_info *info, uint8_t index); +uint8_t phy_get_nss(void); +void phy_get_version(uint32_t *version_1,uint32_t *version_2); +void agc_config(void); +void mdm_reset(); +void mpif_clk_init(void); +uint8_t phy_vht_supported(); +uint8_t phy_get_ntx(void); +uint8_t phy_get_nss(void); +void phy_stop(void); +void phy_reset(void); +void phy_rc_isr(void); +uint8_t phy_mu_mimo_tx_supported(void); +uint8_t phy_mu_mimo_rx_supported(void); +void phy_mdm_isr(void); +uint8_t phy_ldpc_tx_supported(void); +uint8_t phy_ldpc_rx_supported(void); +void phy_init(const phy_cfg_tag *config); +void phy_set_channel(uint8_t band,uint8_t type,uint16_t prim20_freq,uint16_t center1_freq, + uint16_t center2_freq,uint8_t index); +void phy_hw_set_channel(uint8_t band, uint16_t freq, uint16_t freq1, uint8_t chantype); + +void phy_powroffset_set(int8_t *power_offset); +void phy_get_trpc_idx(uint8_t formatmod,uint8_t mcs,int8_t power,uint8_t *idx); +void phy_get_rf_gain_idx_vs_mode(uint8_t mode,int8_t *power,uint8_t *idx); +void phy_get_rf_gain_idx(int8_t *power,uint8_t *idx); +void phy_get_rf_gain_capab(int8_t *max,int8_t *min); +uint8_t phy_bfmer_supported(void); +uint8_t phy_bfmee_supported(); +void bz_phy_reset(void); + +// not sure if there functions are belong to phy_bl602 +// but they seem to be inlined in many funcs + +int static phy_freq_to_channel(uint8_t band, uint16_t freq) { + int base = 0; + if (band == 0) { + // 2.4GHz + if (freq == 2484) + return 14; + if (freq - 2407 > 65) + return 0; + base = -2407; + } else { + if (band == 1) { + // 5GHz + if (freq > 5825) + return 0; + base = -5000; + } else return 0; + } + return (((int)freq) + base) / 5; +} + + +uint16_t static phy_channel_to_freq(uint8_t band, int channel) { + int freq = 0; + if (band == 0) { + // 2.4GHz + if (channel > 14) { + return 0xffff; + } + if (channel == 14) { + return 2484; + } + freq = 2407; + } else { + // 5GHz + if (channel > 165) { + return 0xffff; + } + freq = 5000; + } + return channel * 5 + freq; +} + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_hal.h b/src/include/bl602_wifi/phy_rf/phy_hal.h new file mode 100644 index 0000000..eee906c --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_hal.h @@ -0,0 +1,16 @@ +#ifndef _PHY_HAL_H_ +#define _PHY_HAL_H_ +#include + +struct phy_hal_tag { + int16_t temperature; // +0 + uint8_t capcode; // +2 +}; // :6:8 + +uint8_t hal_get_capcode(void); // :43:9 +void hal_set_capcode(uint32_t capcode); // :48:6 +void hal_set_capcode_asymm(uint32_t capcode_in, uint32_t capcode_out); // :55:6 +void hal_get_capcode_asymm(uint8_t *capcode_in, uint8_t *capcode_out); // :64:6 +bool hal_get_temperature(int16_t *temperature); // :75:5 +void hal_set_temperature(int16_t temperature); // :83:6 +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_helper.h b/src/include/bl602_wifi/phy_rf/phy_helper.h new file mode 100644 index 0000000..81c9cb2 --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_helper.h @@ -0,0 +1,39 @@ +#ifndef _PHY_HELPER_H_ +#define _PHY_HELPER_H_ +#include + +typedef long long (*timer_func_ptr)(void*); // :237:21 + +struct HWStateMachineReg { + uint32_t rxControl:6; // +0 + uint32_t reserved_7_6:2; // +0 + uint32_t txControl:9; // +0 + uint32_t reserved_23_17:7; // +0 + uint32_t macControl:8; // +0 +}; // :59:8 + +struct dump_data_t { + uint32_t time; // +0 + const char *func_name; // +4 + uint32_t rc_state; // +8 + uint32_t rf_state; // +12 + uint32_t mac_debugRegHWSM1; // +16 + uint32_t mac_debugRegHWSM2; // +20 + uint16_t mac_debugPortCoex; // +24 + uint16_t mac_debugPortBackoff; // +26 + uint16_t mac_debugPortMacPhyIf; // +28 + uint16_t mac_debugPortMacPhyIf2; // +30 + uint16_t phy_debugPortMainFSM; // +32 + uint16_t phy_debugPortTDTX; // +34 + uint16_t phy_debugPortDSSSCCK1; // +36 + uint16_t phy_debugPortDSSSCCKTx; // +38 +}; // :68:8 + +int bl60x_check_mac_status(int * is_ok); +void helper_channel_monitor(uint32_t chanfreq, timer_func_ptr * timer_func, int nrepeats, int mon_time_ms); +void helper_record_all_states(char * func_name); +void helper_record_dump(void); +void helper_record_rc_rf_states(uint32_t * rc_state, uint32_t * rf_state); +void helper_record_reset(void); + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_tcal.h b/src/include/bl602_wifi/phy_rf/phy_tcal.h new file mode 100644 index 0000000..db84c03 --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_tcal.h @@ -0,0 +1,21 @@ +#ifndef _PHY_TCAL_H_ +#define _PHY_TCAL_H_ + +#include + +void phy_tcal_reset(void); +void phy_tcal_start(void); + +struct tcal_tag { + int16_t prev_temperature; // +0 + uint32_t last_action_time[4]; // +4 + uint32_t last_action_temperature[4]; // +20 + int32_t last_action_out[4]; // +36 + bool enabled; // +52 +}; // :29:8 + +void phy_tcal_stop(void); // :69:6 +void phy_tcal_handle(void); // :74:6 +void phy_tcal_callback(int16_t temperature); // :104:6 +void phy_tcal_txpwr(int16_t curr_temperature); // :141:6 +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/phy_trpc.h b/src/include/bl602_wifi/phy_rf/phy_trpc.h new file mode 100644 index 0000000..670a568 --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/phy_trpc.h @@ -0,0 +1,31 @@ +#ifndef _PHY_TRPC_H_ +#define _PHY_TRPC_H_ +#include + +struct trpc_env_tag { + int8_t power_dbm_max_rf; // +0 + int8_t power_dbm_min_rf; // +1 + int8_t power_dbm_lim_reg; // +2 + int16_t channel_freq; // +4 + int8_t temperature; // +6 + int8_t temperature_compensate; // +7 +}; + +void trpc_init(void); +int8_t trpc_get_rf_max_power(void); +int8_t trpc_get_rf_min_power(void); +uint8_t trpc_get_power_idx(uint8_t formatmod, uint8_t mcs, int8_t pwr_dbm); +void trpc_update_vs_channel(int8_t channel_MHz); // :171:6 + +uint8_t trpc_get_default_power_idx(uint8_t formatmod,uint8_t mcs); +void trpc_power_get(int8_t * power_rate_table); +void trpc_update_power(int8_t (*power_rate_table) [8]); +void trpc_update_power_11b(int8_t * power_rate_table); +void trpc_update_power_11g(int8_t * power_rate_table); +void trpc_update_power_11n(int8_t * power_rate_table); +void trpc_update_vs_channel(int8_t channel_MHz); +void trpc_update_vs_temperature(int8_t temperature); + +extern int8_t txpwr_vs_rate_table[3][8]; + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/rf.h b/src/include/bl602_wifi/phy_rf/rf.h new file mode 100644 index 0000000..28a73df --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/rf.h @@ -0,0 +1,9 @@ +#ifndef _RF_H_ +#define _RF_H_ +#include + +void rf_set_channel(uint8_t bandwidth, uint16_t channel_freq); +void rf_clkpll_isr(void); +void rf_init(void); +void rf_lo_isr(void); +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phy_rf/rfc_bl602.h b/src/include/bl602_wifi/phy_rf/rfc_bl602.h new file mode 100644 index 0000000..2fa9add --- /dev/null +++ b/src/include/bl602_wifi/phy_rf/rfc_bl602.h @@ -0,0 +1,199 @@ +#ifndef _RFC_BL602_H_ +#define _RFC_BL602_H_ +#include + + +enum +{ + RFC_OFF = 0, + RFC_ON = 1 +}; + +enum +{ + RFC_PM_MUX_TO_ADC = 0, + RFC_PM_MUX_TO_IQCOMP = 1, + RFC_PM_MUX_TO_BLE = 2 +}; + +enum +{ + RFC_TXDFE_IN_MUX_TO_BB = 0, + RFC_TXDFE_IN_MUX_TO_SRAM = 1, + RFC_TXDFE_IN_MUX_TO_SINGEN = 2, + RFC_TXDFE_IN_MUX_TO_PAD = 3 +}; + +enum +{ + RFC_FSM_PD = 0, + RFC_FSM_SB = 1, + RFC_FSM_LO = 2, + RFC_FSM_RX = 3, + RFC_FSM_TX = 4, + RFC_FSM_FORCE_OFF = 15 +}; + +enum +{ + RFC_BBMODE_WLAN = 0, + RFC_BBMODE_BLE = 1 +}; + +enum +{ + RFC_SG_SINGLE_TONE = 0, + RFC_SG_TWO_TONE, + RFC_SG_RAMP +}; + +enum { + RFC_PC_AUTO = 0, + RFC_PC_WLAN_11B, + RFC_PC_WLAN_11G, + RFC_PC_WLAN_11N, + RFC_PC_BT_BLE +}; + +enum { + RFC_FORMATMOD_11B = 0, + RFC_FORMATMOD_11G = 1, + RFC_FORMATMOD_11N = 2 +}; + +enum { + RFC_BW_20M = 0, + RFC_BW_10M = 1 +}; + +void rfc_init(uint32_t xtalfreq); +void rfc_reset(); +void rfc_ver_set(uint8_t ver); // :1047:6 +void rfc_config_channel(uint32_t channel_freq); +void rfc_config_channel_sw(uint32_t channel_freq); +// void rfc_write_reg(uint32_t a, uint32_t d); +// uint32_t rfc_read_reg(uint32_t a); + +uint32_t rfc_get_power_level(uint32_t mode, int32_t power); +void rfc_wlan_mode_force(uint32_t force_mode); // :1500:6 +/* + * TXDFE DECLARATIONS + **************************************************************************************** + */ +void rfc_txdfe_start(); +void rfc_txdfe_stop(); +void rfc_txdfe_mux(int8_t signal_source); +void rfc_txdfe_set_dvga(int8_t dvga_qdb); +void rfc_txdfe_set_iqgaincomp(uint8_t en,uint16_t coeff); +void rfc_txdfe_set_iqphasecomp(uint8_t en,int16_t coeff); +void rfc_txdfe_set_dccomp(int16_t dcc_i,int16_t dcc_q); +void rfc_txdfe_set_iqswap(uint8_t swap_on); + +/* + * RXDFE DECLARATIONS + **************************************************************************************** + */ +void rfc_rxdfe_start(); +void rfc_rxdfe_stop(); +void rfc_rxdfe_set_iqgaincomp(uint8_t en,uint16_t coeff); +void rfc_rxdfe_set_iqphasecomp(uint8_t en,int16_t coeff); +void rfc_rxdfe_set_dccomp(int16_t dcc_i,int16_t dcc_q); +void rfc_rxdfe_set_iqswap(uint8_t swap_on); +void rfc_rxdfe_set_notch0(uint8_t en,uint8_t alpha,int8_t nrmfc); +void rfc_rxdfe_set_notch1(uint8_t en,uint8_t alpha,int8_t nrmfc); + +/* + * SG DECLARATIONS + **************************************************************************************** + */ +void rfc_sg_start(uint32_t inc_step,uint32_t gain_i,uint32_t gain_q,uint32_t addr_i,uint32_t addr_q); +void rfc_sg_stop(); + +/* + * PM DECLARATIONS + **************************************************************************************** + */ + +uint32_t rfc_pm_start(uint32_t insel,int32_t freq_cw,uint32_t acclen,uint32_t rshiftlen, + int32_t *raw_acc_i,int32_t *raw_acc_q); +void rfc_pm_stop(); + +/* + * HWCTRL DECLARATIONS + **************************************************************************************** + */ +void rfc_hwctrl_txrfgain(uint8_t hwctrl_on); +void rfc_hwctrl_rxgain(uint8_t hwctrl_on); +void rfc_hwctrl_txdvga(uint8_t hwctrl_on); +void rfc_hwctrl_calparam(uint8_t hwctrl_on); + +/* + * FSM DECLARATIONS + **************************************************************************************** + */ + +void rfc_fsm_force(uint8_t state); +void rfc_rc_fsm_force(uint8_t state); // :1313:6 +/* + * COEX DECLARATIONS + **************************************************************************************** + */ +void rfc_coex_force_to(uint32_t force_enable, uint32_t bbmode); + +void rfc_dump(); + +void rfc_apply_tx_power_offset(uint8_t channel, int8_t *power_offset); // :1643:6 +void rfc_config_channel(uint32_t channel_freq); +void rfc_apply_tx_dvga(int8_t *dvga_qdb); +void rfc_apply_tx_dvga_offset(int8_t offset_qdb); // :1519:6 + +void rfc_config_power(uint32_t mode, uint32_t tbb_boost, uint32_t tbb, uint32_t tmx); +_Bool rfc_config_power_ble(int32_t pwr_dbm); +void rfc_config_bandwidth(uint32_t mode); + +struct rfc_status_tag { + uint32_t pkdet_out_raw:1; // +0 + uint32_t dig_xtal_clk_dbg:1; // +0 + uint32_t clk_ble_16m_dbg:1; // +0 + uint32_t clk_rc_dbg0:1; // +0 + uint32_t clk_adcpow_dbg:1; // +0 + uint32_t clk_fetx_dbg:1; // +0 + uint32_t clk_ferx_dbg:1; // +0 + uint32_t clkpll_postdiv_outclk_dbg:1; // +0 + uint32_t clk_soc_480m_dbg:1; // +0 + uint32_t clk_soc_240m_dbg:1; // +0 + uint32_t clk_soc_192m_dbg:1; // +0 + uint32_t clk_soc_160m_dbg:1; // +0 + uint32_t clk_soc_120m_dbg:1; // +0 + uint32_t clk_soc_96m_dbg:1; // +0 + uint32_t clk_soc_80m_dbg:1; // +0 + uint32_t clk_soc_48m_dbg:1; // +0 + uint32_t clk_soc_32m_dbg:1; // +0 + uint32_t pad_pkdet_out:1; // +0 + uint32_t pad_agc_ctrl:10; // +0 + uint32_t rf_pkdet_rst_hw:1; // +0 + uint32_t rf_cbw_wifi:2; // +0 + uint32_t lo_unlocked:1; // +0 + uint32_t fsm_pu_txbuf:1; // +4 + uint32_t fsm_pu_rxbuf:1; // +4 + uint32_t fsm_pu_tosdac:1; // +4 + uint32_t fsm_pu_dac:1; // +4 + uint32_t fsm_trsw_en:1; // +4 + uint32_t fsm_pu_adc:1; // +4 + uint32_t fsm_pu_pkdet:1; // +4 + uint32_t fsm_pu_rbb:1; // +4 + uint32_t fsm_pu_rmx:1; // +4 + uint32_t fsm_pu_rmxgm:1; // +4 + uint32_t fsm_pu_lna:1; // +4 + uint32_t clk_rc_dbg2:1; // +4 + uint32_t rf_lna_ind_hw:4; // +4 + uint32_t rf_rbb_ind_hw:4; // +4 + uint32_t rf_tx_pow_lvl_hw:4; // +4 + uint32_t rf_rc_lo_rdy:1; // +4 + uint32_t rf_fsm_state:3; // +4 + uint32_t rf_rc_state:3; // +4 + uint32_t clk_rc_dbg:1; // +4 +}; // :84:8 + + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/phyif/phyif_utils.h b/src/include/bl602_wifi/phyif/phyif_utils.h new file mode 100644 index 0000000..25f31ee --- /dev/null +++ b/src/include/bl602_wifi/phyif/phyif_utils.h @@ -0,0 +1,16 @@ +#ifndef _PHYIF_H_ +#define _PHYIF_H_ + +#include + +typedef struct { + uint32_t recvtable1; // +0 + uint32_t recvtable2; // +4 + uint32_t recvtable3; // +8 + uint32_t recvtable4; // +12 + uint32_t recvtable5; // +16 + uint32_t recvtable6; // +20 +} phyif_utils_recvtable_t; // :11:3 +int phyif_utils_decode(phyif_utils_recvtable_t *vec,int8_t *ppm); + +#endif \ No newline at end of file diff --git a/src/include/bl602_wifi/sysctrl/sysctrl.h b/src/include/bl602_wifi/sysctrl/sysctrl.h new file mode 100644 index 0000000..0bcb1d6 --- /dev/null +++ b/src/include/bl602_wifi/sysctrl/sysctrl.h @@ -0,0 +1,4 @@ +#ifndef _SYSCTRL_H_ +#define _SYSCTRL_H_ +void sysctrl_init(); +#endif diff --git a/src/include/bl602_wifi/umac/apm/apm.h b/src/include/bl602_wifi/umac/apm/apm.h new file mode 100644 index 0000000..7ac3e6b --- /dev/null +++ b/src/include/bl602_wifi/umac/apm/apm.h @@ -0,0 +1,53 @@ +#ifndef _APM_H_ +#define _APM_H_ + +#include +#include + +#include +#include +#include +#include + + +struct apm { + const struct apm_start_req *param; // +0 + struct co_list bss_config; // +4 + uint8_t aging_sta_idx; // +12 + uint8_t *bcn_buf; // +16 + bool apm_emb_enabled; // +20 + uint8_t hidden_ssid; // +21 + uint8_t assoc_sta_count; // +22 + uint8_t max_sta_supported; // +23 + struct { + uint8_t mac[6]; // +0 + uint8_t used; // +6 + } aid_list[10]; // +24 +}; + +void apm_init(void); +void apm_start_cfm(uint8_t status); +void apm_set_bss_param(void); +void apm_send_next_bss_param(void); +void apm_bcn_set(void); +void apm_stop(struct vif_info_tag *vif); +bool apm_tx_int_ps_check(struct txdesc *txdesc); +void apm_tx_int_ps_postpone(struct txdesc *txdesc, struct sta_info_tag *sta); +struct txdesc *apm_tx_int_ps_get_postpone(struct vif_info_tag *vif, struct sta_info_tag *sta, int *stop); +void apm_tx_int_ps_clear(struct vif_info_tag *vif, uint8_t sta_idx); + +extern struct apm apm_env; + +void apm_send_mlme(struct vif_info_tag *vif, uint16_t fctl, const struct mac_addr *ra, cfm_func_ptr cfm_func, void *env, uint16_t status_code); +bool apm_embedded_enabled(struct vif_info_tag *vif); +void apm_sta_fw_delete(uint8_t sta_idx); +void apm_sta_add(uint8_t sta_idx); +void apm_probe_req_handler(const struct rxu_mgt_ind *param); +void apm_auth_handler(const struct rxu_mgt_ind *param); +void apm_assoc_req_handler(const struct rxu_mgt_ind *param, bool is_reassoc); +void apm_deauth_handler(const struct rxu_mgt_ind *param); +void apm_disassoc_handler(const struct rxu_mgt_ind *param); +void apm_beacon_handler(const struct rxu_mgt_ind *param); +void apm_sta_remove(uint8_t vif_idx, uint8_t sta_idx); + +#endif // _APM_H_ diff --git a/src/include/bl602_wifi/umac/apm/apm_task.h b/src/include/bl602_wifi/umac/apm/apm_task.h new file mode 100644 index 0000000..34326d2 --- /dev/null +++ b/src/include/bl602_wifi/umac/apm/apm_task.h @@ -0,0 +1,123 @@ +#ifndef _APM_TASK_H_ +#define _APM_TASK_H_ + +#include +#include + +#include +#include + +#define APM_IDX_MAX 1 + +enum apm_state_tag { + APM_IDLE = 0, + APM_BSS_PARAM_SETTING = 1, + APM_BCN_SETTING = 2, + APM_STATE_MAX = 3, +}; + +enum apm_msg_tag { + APM_START_REQ = 7168, + APM_START_CFM = 7169, + APM_STOP_REQ = 7170, + APM_STOP_CFM = 7171, + APM_START_CAC_REQ = 7172, + APM_START_CAC_CFM = 7173, + APM_STOP_CAC_REQ = 7174, + APM_STOP_CAC_CFM = 7175, + APM_STA_ADD_IND = 7176, + APM_STA_DEL_IND = 7177, + APM_STA_CONNECT_TIMEOUT_IND = 7178, + APM_STA_DEL_REQ = 7179, + APM_STA_DEL_CFM = 7180, + APM_CONF_MAX_STA_REQ = 7181, + APM_CONF_MAX_STA_CFM = 7182, +}; + +struct apm_start_req { + struct mac_rateset basic_rates; // +0 + struct scan_chan_tag chan; // +14 + uint32_t center_freq1; // +20 + uint32_t center_freq2; // +24 + uint8_t ch_width; // +28 + uint8_t hidden_ssid; // +29 + uint32_t bcn_addr; // +32 + uint16_t bcn_len; // +36 + uint16_t tim_oft; // +38 + uint16_t bcn_int; // +40 + uint32_t flags; // +44 + uint16_t ctrl_port_ethertype; // +48 + uint8_t tim_len; // +50 + uint8_t vif_idx; // +51 + bool apm_emb_enabled; // +52 + struct mac_rateset rate_set; // +53 + uint8_t beacon_period; // +66 + uint8_t qos_supported; // +67 + struct mac_ssid ssid; // +68 + uint8_t ap_sec_type; // +102 + uint8_t phrase[64]; // +103 + uint8_t bcn_buf[]; // +167 +}; + +struct apm_start_cfm { + uint8_t status; // +0 + uint8_t vif_idx; // +1 + uint8_t ch_idx; // +2 + uint8_t bcmc_idx; // +3 +}; + +struct apm_stop_req { + uint8_t vif_idx; // +0 +}; + +struct apm_conf_max_sta_req { + uint8_t max_sta_supported; // +0 +}; + +struct apm_start_cac_req { + struct scan_chan_tag chan; // +0 + uint32_t center_freq1; // +8 + uint32_t center_freq2; // +12 + uint8_t ch_width; // +16 + uint8_t vif_idx; // +17 +}; + +struct apm_start_cac_cfm { + uint8_t status; // +0 + uint8_t ch_idx; // +1 +}; + +struct apm_stop_cac_req { + uint8_t vif_idx; // +0 +}; + +struct apm_sta_del_req { + uint8_t vif_idx; // +0 + uint8_t sta_idx; // +1 +}; + +struct apm_sta_del_cfm { + uint8_t status; // +0 + uint8_t vif_idx; // +1 + uint8_t sta_idx; // +2 +}; + +struct apm_sta_add_ind { + uint32_t flags; // +0 + struct mac_addr sta_addr; // +4 + uint8_t vif_idx; // +10 + uint8_t sta_idx; // +11 + int8_t rssi; // +12 + uint32_t tsflo; // +16 + uint32_t tsfhi; // +20 + uint8_t data_rate; // +24 +}; + +struct apm_sta_del_ind { + uint8_t sta_idx; // +0 +}; + +extern const struct ke_state_handler apm_default_handler; +extern ke_state_t apm_state[1]; + +#endif // _APM_TASK_H_ diff --git a/src/include/bl602_wifi/umac/bam/bam_task.h b/src/include/bl602_wifi/umac/bam/bam_task.h new file mode 100644 index 0000000..3636162 --- /dev/null +++ b/src/include/bl602_wifi/umac/bam/bam_task.h @@ -0,0 +1,20 @@ +#ifndef _BAM_TASK_H_ +#define _BAM_TASK_H_ + +#include + +#define BAM_IDX_MAX 1 + +enum bam_state_tag { + BAM_IDLE = 0, + BAM_ACTIVE = 1, + BAM_WAIT_RSP = 2, + BAM_CHECK_ADMISSION = 3, + BAM_RESET = 4, + BAM_STATE_MAX = 5, +}; + +extern const struct ke_state_handler bam_default_handler; +extern ke_state_t bam_state[BAM_IDX_MAX]; + +#endif // _BAM_TASK_H_ diff --git a/src/include/bl602_wifi/umac/hostapd/hostapd_task.h b/src/include/bl602_wifi/umac/hostapd/hostapd_task.h new file mode 100644 index 0000000..3176d09 --- /dev/null +++ b/src/include/bl602_wifi/umac/hostapd/hostapd_task.h @@ -0,0 +1,17 @@ +#ifndef _HOSTAPD_TASK_H_ +#define _HOSTAPD_TASK_H_ + +#include + +#define HOSTAPD_IDX_MAX 1 + +enum hostapd_state_tag { + HOSTAPD_STATE_IDLE = 0, + HOSTAPD_STATE_MAX = 1, +}; + + +extern const struct ke_state_handler hostapd_default_handler; +extern ke_state_t hostapd_u_state[HOSTAPD_IDX_MAX]; + +#endif // _HOSTAPD_TASK_H_ diff --git a/src/include/bl602_wifi/umac/me/me.h b/src/include/bl602_wifi/umac/me/me.h new file mode 100644 index 0000000..0d573dc --- /dev/null +++ b/src/include/bl602_wifi/umac/me/me.h @@ -0,0 +1,77 @@ +#ifndef __ME_H__ +#define __ME_H__ + +#include +#include + +#include +#include +#include +#include +#include + + +struct me_env_tag { + uint32_t active_vifs; // +0 + uint32_t ps_disable_vifs; // +4 + ke_task_id_t requester_id; // +8 + struct mac_htcapability ht_cap; // +12 + uint16_t tx_lft; // +44 + bool ht_supported; // +46 + struct me_chan_config_req chan; // +48 + uint8_t stbc_nss; // +302 + uint8_t phy_bw_max; // +303 + bool ps_on; // +304 +}; + +struct mobility_domain { + uint16_t mdid; // +0 + uint8_t ft_capability_policy; // +2 +}; + +struct mac_bss_info { + struct mac_htcapability ht_cap; // +0 + struct mac_addr bssid; // +32 + struct mac_ssid ssid; // +38 + uint16_t bsstype; // +72 + struct scan_chan_tag *chan; // +76 + uint16_t center_freq1; // +80 + uint16_t center_freq2; // +82 + uint16_t beacon_period; // +84 + uint16_t cap_info; // +86 + struct mac_rateset rate_set; // +88 + struct mac_edca_param_set edca_param; // +104 + int8_t rssi; // +124 + int8_t ppm_rel; // +125 + int8_t ppm_abs; // +126 + uint8_t high_11b_rate; // +127 + uint16_t prot_status; // +128 + uint8_t bw; // +130 + uint8_t phy_bw; // +131 + uint8_t power_constraint; // +132 + uint32_t valid_flags; // +136 + struct mobility_domain mde; // +140 + bool is_supplicant_enabled; // +144 + SecurityMode_t wpa_wpa2_wep; // +145 + Cipher_t wpa_mcstCipher; // +147 + Cipher_t wpa_ucstCipher; // +148 + Cipher_t rsn_mcstCipher; // +149 + Cipher_t rsn_ucstCipher; // +150 + bool is_pmf_required; // +151 + bool is_wpa2_prefered; // +152 + uint8_t rsn_wpa_ie[32]; // +153 + uint8_t rsn_wpa_ie_len; // +185 + uint16_t beacon_interval; // +186 + uint16_t aid_bitmap; // +188 + uint16_t max_listen_interval; // +190 + uint8_t sec_type; // +192 +}; + +extern struct me_env_tag me_env; + +void me_init(void); +struct scan_chan_tag *me_freq_to_chan_ptr(uint8_t band, uint16_t freq); +unsigned char process_rsn_ie(uint8_t *rsn_ie, Cipher_t *mcstCipher, Cipher_t *ucstCipher, bool *is_pmf_required, SecurityMode_t *security_mode, bool wpa2_prefered); +unsigned char process_wpa_ie(uint8_t *wpa_ie, Cipher_t *mcstCipher, Cipher_t *ucstCipher); + +#endif // __ME_H__ diff --git a/src/include/bl602_wifi/umac/me/me_mic.h b/src/include/bl602_wifi/umac/me/me_mic.h new file mode 100644 index 0000000..ff551d4 --- /dev/null +++ b/src/include/bl602_wifi/umac/me/me_mic.h @@ -0,0 +1,20 @@ +#ifndef _ME_MIC_H_ +#define _ME_MIC_H_ + +#include + +#include + +struct mic_calc { + uint32_t mic_key_least; // +0 + uint32_t mic_key_most; // +4 + uint32_t last_m_i; // +8 + uint8_t last_m_i_len; // +12 +}; + + +void me_mic_init(struct mic_calc *mic_calc_ptr, uint32_t *mic_key_ptr, struct mac_addr *da, struct mac_addr *sa, uint8_t tid); +void me_mic_calc(struct mic_calc *mic_calc_ptr, uint32_t start_ptr, uint32_t data_len); +void me_mic_end(struct mic_calc *mic_calc_ptr); + +#endif // _ME_MIC_H_ diff --git a/src/include/bl602_wifi/umac/me/me_task.h b/src/include/bl602_wifi/umac/me/me_task.h new file mode 100644 index 0000000..cae3f8e --- /dev/null +++ b/src/include/bl602_wifi/umac/me/me_task.h @@ -0,0 +1,111 @@ +#ifndef _ME_TASK_H_ +#define _ME_TASK_H_ + +#include +#include + +#include +#include +#include + +/// Task max index number. +#define ME_IDX_MAX 1 + +/// Possible states of the task. +enum { + /// Idle State. + ME_IDLE, + /// Busy State. + ME_BUSY, + /// Max number of states + ME_STATE_MAX +}; + +struct me_config_req { + struct mac_htcapability ht_cap; // +0 + struct mac_vhtcapability vht_cap; // +32 + uint16_t tx_lft; // +44 + bool ht_supp; // +46 + bool vht_supp; // +47 + bool ps_on; // +48 +}; +struct me_chan_config_req { + struct scan_chan_tag chan2G4[14]; // +0 + struct scan_chan_tag chan5G[28]; // +84 + uint8_t chan2G4_cnt; // +252 + uint8_t chan5G_cnt; // +253 +}; +struct me_set_control_port_req { + uint8_t sta_idx; // +0 + bool control_port_open; // +1 +}; +struct me_tkip_mic_failure_ind { + struct mac_addr addr; // +0 + uint64_t tsc; // +8 + bool ga; // +16 + uint8_t keyid; // +17 + uint8_t vif_idx; // +18 +}; +struct me_sta_add_req { + struct mac_addr mac_addr; // +0 + struct mac_rateset rate_set; // +6 + struct mac_htcapability ht_cap; // +20 + struct mac_vhtcapability vht_cap; // +52 + uint32_t flags; // +64 + uint16_t aid; // +68 + uint8_t uapsd_queues; // +70 + uint8_t max_sp_len; // +71 + uint8_t opmode; // +72 + uint8_t vif_idx; // +73 + bool tdls_sta; // +74 + uint32_t tsflo; // +76 + uint32_t tsfhi; // +80 + int8_t rssi; // +84 + uint8_t data_rate; // +85 +}; +struct me_sta_add_cfm { + uint8_t sta_idx; // +0 + uint8_t status; // +1 + uint8_t pm_state; // +2 +}; +struct me_sta_del_req { + uint8_t sta_idx; // +0 + bool tdls_sta; // +1 +}; +struct me_set_active_req { + bool active; // +0 + uint8_t vif_idx; // +1 +}; +struct me_set_ps_disable_req { + bool ps_disable; // +0 + uint8_t vif_idx; // +1 +}; +struct me_traffic_ind_req { + uint8_t sta_idx; // +0 + uint8_t tx_avail; // +1 + bool uapsd; // +2 +}; +struct me_rc_stats_req { + uint8_t sta_idx; // +0 +}; +struct me_rc_stats_cfm { + uint8_t sta_idx; // +0 + uint16_t no_samples; // +2 + uint16_t ampdu_len; // +4 + uint16_t ampdu_packets; // +6 + uint32_t avg_ampdu_len; // +8 + uint8_t sw_retry_step; // +12 + uint8_t sample_wait; // +13 + struct step retry[4]; // +16 + struct rc_rate_stats rate_stats[10]; // +48 + uint32_t tp[10]; // +168 +}; +struct me_rc_set_rate_req { + uint8_t sta_idx; // +0 + uint16_t fixed_rate_cfg; // +2 +}; + +extern const struct ke_state_handler me_default_handler; +extern ke_state_t me_state[ME_IDX_MAX]; + +#endif diff --git a/src/include/bl602_wifi/umac/me/me_utils.h b/src/include/bl602_wifi/umac/me/me_utils.h new file mode 100644 index 0000000..9a6e174 --- /dev/null +++ b/src/include/bl602_wifi/umac/me/me_utils.h @@ -0,0 +1,32 @@ +#ifndef _ME_UTILS_H_ +#define _ME_UTILS_H_ + +#include +#include + +#include +#include +#include + + +uint8_t me_phy2mac_bw(uint8_t phy_bw); +uint8_t me_get_sta_bw(uint8_t sta_phy_bw, uint8_t bss_phy_bw); +bool me_set_sta_ht_vht_param(struct sta_info_tag *sta, struct mac_bss_info *bss); +void me_get_basic_rates(const struct mac_rateset *rateset, struct mac_rateset *basic_ratest); +uint16_t me_legacy_rate_bitfield_build(const struct mac_rateset *rateset, bool basic_only); +uint16_t me_build_capability(uint8_t vif_idx); +void me_init_rate(struct sta_info_tag *sta_entry); +void me_init_bcmc_rate(struct sta_info_tag *sta_entry); +void me_check_rc(uint8_t sta_idx, bool *tx_ampdu); +void me_tx_cfm_singleton(struct txdesc *txdesc); +struct txl_buffer_control *me_update_buffer_control(struct sta_info_tag *sta_info); +void me_bw_check(uint32_t ht_op_addr, uint32_t vht_op_addr, struct mac_bss_info *bss); +void me_beacon_check(uint8_t vif_idx, uint16_t length, uint32_t bcn_addr); +void me_sta_bw_nss_max_upd(uint8_t sta_idx, uint8_t bw, uint8_t nss); +uint8_t me_11n_nss_max(uint8_t *mcs_set); +uint8_t me_legacy_ridx_min(uint16_t rate_map); +uint8_t me_legacy_ridx_max(uint16_t rate_map); +uint8_t me_add_chan_ctx(uint8_t *p_chan_idx, struct scan_chan_tag *p_chan, uint32_t center_freq1, uint32_t center_freq2, uint8_t ch_width); +uint8_t me_rate_translate(uint8_t rate); + +#endif // _ME_UTILS_H_ diff --git a/src/include/bl602_wifi/umac/rc/rc.h b/src/include/bl602_wifi/umac/rc/rc.h new file mode 100644 index 0000000..f0363f8 --- /dev/null +++ b/src/include/bl602_wifi/umac/rc/rc.h @@ -0,0 +1,67 @@ +#ifndef _RC_H_ +#define _RC_H_ + +#include +#include + +#include + + +struct rc_rate_stats { + uint16_t attempts; // +0 + uint16_t success; // +2 + uint16_t probability; // +4 + uint16_t rate_config; // +6 + uint8_t sample_skipped; // +8 + bool old_prob_available; // +9 + uint8_t n_retry; // +10 + bool rate_allowed; // +11 +}; + +struct step { + uint32_t tp; // +0 + uint16_t idx; // +4 +}; + +struct rc_sta_stats { + uint32_t last_rc_time; // +0 + struct rc_rate_stats rate_stats[10]; // +4 + struct step retry[4]; // +124 + struct step max_tp_2_trial; // +156 + uint16_t ampdu_len; // +164 + uint16_t ampdu_packets; // +166 + uint32_t avg_ampdu_len; // +168 + uint8_t sample_wait; // +172 + uint8_t sample_slow; // +173 + uint8_t trial_status; // +174 + uint8_t info; // +175 + uint8_t sw_retry_step; // +176 + uint8_t format_mod; // +177 + union { + uint8_t ht[4]; + } rate_map; // +178 + uint16_t rate_map_l; // +182 + uint8_t mcs_max; // +184 + uint8_t r_idx_min; // +185 + uint8_t r_idx_max; // +186 + uint8_t bw_max; // +187 + uint8_t no_ss; // +188 + uint8_t short_gi; // +189 + uint8_t p_type; // +190 + uint16_t no_samples; // +192 + uint16_t max_amsdu_len; // +194 + uint16_t curr_amsdu_len; // +196 + uint16_t fixed_rate_cfg; // +198 +}; + + +uint16_t rc_get_max_amsdu_len(struct sta_info_tag *sta_entry); +void rc_init(struct sta_info_tag *sta_entry); +void rc_update_counters(uint8_t sta_idx, uint32_t attempts, uint32_t failures, bool tx_ampdu, bool retry_required); +void rc_check(uint8_t sta_idx, bool *tx_ampdu); +void rc_update_bw_nss_max(uint8_t sta_idx, uint8_t bw_max, uint8_t nss_max); +void rc_init_bcmc_rate(struct sta_info_tag *sta_entry, uint8_t basic_rate_idx); +uint32_t rc_calc_tp(struct rc_sta_stats *rc_ss, uint8_t sample_idx); +bool rc_check_fixed_rate_config(struct rc_sta_stats *rc_ss, uint16_t fixed_rate_config); + +#endif diff --git a/src/include/bl602_wifi/umac/rxu/rxu_cntrl.h b/src/include/bl602_wifi/umac/rxu/rxu_cntrl.h new file mode 100644 index 0000000..d4b624c --- /dev/null +++ b/src/include/bl602_wifi/umac/rxu/rxu_cntrl.h @@ -0,0 +1,93 @@ +#ifndef _RXU_CNTRL_H_ +#define _RXU_CNTRL_H_ + +#include +#include + +#include +#include + + +enum rx_status_bits { + RX_STAT_FORWARD = 1, + RX_STAT_ALLOC = 2, + RX_STAT_DELETE = 4, + RX_STAT_LEN_UPDATE = 8, + RX_STAT_ETH_LEN_UPDATE = 16, + RX_STAT_COPY = 32, +}; + +enum rxu_cntrl_frame_info_pos { + RXU_CNTRL_MIC_CHECK_NEEDED = 1, + RXU_CNTRL_PN_CHECK_NEEDED = 2, + RXU_CNTRL_NEW_MESH_PEER = 4, +}; + +struct rxu_mic_calc { + struct mic_calc mic_calc; // +0 + uint32_t last_bytes[2]; // +16 +}; + +struct rx_cntrl_rx_status { + uint16_t frame_cntl; // +0 + uint16_t seq_cntl; // +2 + uint16_t sn; // +4 + uint8_t fn; // +6 + uint8_t tid; // +7 + uint8_t machdr_len; // +8 + uint8_t sta_idx; // +9 + uint8_t vif_idx; // +10 + uint8_t dst_idx; // +11 + uint64_t pn; // +16 + uint32_t statinfo; // +24 + uint32_t host_buf_addr; // +28 + struct key_info_tag *key; // +32 + struct mac_addr da; // +36 + struct mac_addr sa; // +42 + uint8_t frame_info; // +48 + bool eth_len_present; // +49 + uint8_t payl_offset; // +50 +}; + +struct rx_cntrl_ipcdesc { + uint32_t host_id; // +0 +}; + +struct rx_cntrl_dupli { + struct mac_addr last_src_addr; // +0 + uint16_t last_seq_cntl; // +6 +}; + +struct rx_cntrl_pm_mon { + struct mac_addr addr; // +0 + uint8_t pm_state; // +6 + bool mon; // +7 +}; + +struct rxu_cntrl_env_tag { + struct rx_cntrl_rx_status rx_status; // +0 + struct co_list rxdesc_pending; // +56 + struct co_list rxdesc_ready; // +64 + struct rx_cntrl_ipcdesc rx_ipcdesc_stat; // +72 + struct co_list rxu_defrag_free; // +76 + struct co_list rxu_defrag_used; // +84 + struct rx_cntrl_dupli rxu_dupli; // +92 + struct mac_addr *mac_addr_ptr; // +100 + struct rx_cntrl_pm_mon pm_mon; // +104 + uint32_t ttr; // +112 +}; + + +extern struct rxu_cntrl_env_tag rxu_cntrl_env; +extern uint32_t mac_payload_offset; + + +bool rxu_cntrl_frame_handle(struct rx_swdesc *swdesc); +void rxu_cntrl_init(void); +void rxu_cntrl_monitor_pm(struct mac_addr *addr); +uint8_t rxu_cntrl_get_pm(void); + +void rxu_cntrl_evt(int dummy); +void rxu_swdesc_upload_evt(int arg); + +#endif // _RXU_CNTRL_H_ diff --git a/src/include/bl602_wifi/umac/rxu/rxu_task.h b/src/include/bl602_wifi/umac/rxu/rxu_task.h new file mode 100644 index 0000000..cf17920 --- /dev/null +++ b/src/include/bl602_wifi/umac/rxu/rxu_task.h @@ -0,0 +1,29 @@ +#ifndef _RXU_TASK_H_ +#define _RXU_TASK_H_ + +#include + + +enum rxu_msg_tag { + RXU_MGT_IND = 11264, + RXU_NULL_DATA = 11265, +}; + +struct rxu_mgt_ind { + uint16_t length; // +0 + uint16_t framectrl; // +2 + uint16_t center_freq; // +4 + uint8_t band; // +6 + uint8_t sta_idx; // +7 + uint8_t inst_nbr; // +8 + uint8_t sa[6]; // +9 + uint32_t tsflo; // +16 + uint32_t tsfhi; // +20 + int8_t rssi; // +24 + int8_t ppm_abs; // +25 + int8_t ppm_rel; // +26 + uint8_t data_rate; // +27 + uint32_t payload[0]; // +28 +}; + +#endif // _RXU_TASK_H_ diff --git a/src/include/bl602_wifi/umac/scanu/scanu_task.h b/src/include/bl602_wifi/umac/scanu/scanu_task.h new file mode 100644 index 0000000..dafa314 --- /dev/null +++ b/src/include/bl602_wifi/umac/scanu/scanu_task.h @@ -0,0 +1,53 @@ +#ifndef _SCANU_TASK_H_ +#define _SCANU_TASK_H_ + +#include +#include + +#include +#include +#include + +#define SCANU_IDX_MAX 1 + +enum +{ + /// Idle State. + SCANU_IDLE, + /// SCANNING State. + SCANU_SCANNING, + /// Max number of states + SCANU_STATE_MAX +}; + +struct scanu_start_req { + struct scan_chan_tag chan[42]; // +0 + struct mac_ssid ssid[2]; // +252 + struct mac_addr bssid; // +320 + uint32_t add_ies; // +328 + uint16_t add_ie_len; // +332 + uint8_t vif_idx; // +334 + uint8_t chan_cnt; // +335 + uint8_t ssid_cnt; // +336 + bool no_cck; // +337 +}; + +struct scanu_raw_send_req { + void *pkt; // +0 + uint32_t len; // +4 +}; + +struct scanu_raw_send_cfm { + uint32_t status; // +0 +}; + +struct scanu_start_cfm { + uint8_t status; // +0 +}; + + +extern const struct ke_state_handler scanu_state_handler[SCANU_STATE_MAX]; +extern const struct ke_state_handler scanu_default_handler; +extern ke_state_t scanu_state[1]; + +#endif // _SCANU_TASK_H_ diff --git a/src/include/bl602_wifi/umac/sm/sm.h b/src/include/bl602_wifi/umac/sm/sm.h new file mode 100644 index 0000000..ab5b174 --- /dev/null +++ b/src/include/bl602_wifi/umac/sm/sm.h @@ -0,0 +1,43 @@ +#ifndef _SM_H_ +#define _SM_H_ + +#include +#include + +#include +#include +#include +#include + + +struct sm_env_tag { + struct sm_connect_req *connect_param; // +0 + struct sm_connect_ind *connect_ind; // +4 + struct co_list bss_config; // +8 + bool join_passive; // +16 + bool ft_over_ds; // +17 + int exist_ssid_idx; // +20 + struct mac_addr ft_old_bssid; // +24 +}; + + +void sm_init(void); +void sm_get_bss_params(const struct mac_addr **bssid, const struct scan_chan_tag **chan); +void sm_join_bss(const struct mac_addr *bssid, const struct scan_chan_tag *chan, bool passive); +void sm_scan_bss(const struct mac_addr *bssid, const struct scan_chan_tag *chan); +void sm_connect_ind(uint16_t status); +void sm_auth_handler(const struct rxu_mgt_ind *param); +void sm_assoc_rsp_handler(const struct rxu_mgt_ind *param); +int sm_deauth_handler(const struct rxu_mgt_ind *param); +uint8_t sm_add_chan_ctx(uint8_t *p_chan_idx); +void sm_set_bss_param(void); +void sm_send_next_bss_param(void); +void sm_disconnect(uint8_t vif_index, uint16_t reason_code); +void sm_disconnect_process(struct vif_info_tag *vif, uint16_t reason); +void sm_assoc_req_send(void); +void sm_auth_send(uint16_t auth_seq, uint32_t *challenge); + + +extern struct sm_env_tag sm_env; + +#endif // _SM_H_ diff --git a/src/include/bl602_wifi/umac/sm/sm_task.h b/src/include/bl602_wifi/umac/sm/sm_task.h new file mode 100644 index 0000000..72c5bbd --- /dev/null +++ b/src/include/bl602_wifi/umac/sm/sm_task.h @@ -0,0 +1,94 @@ +#ifndef _SM_TASK_H_ +#define _SM_TASK_H_ + +#include +#include + +#include +#include +#include + +#define SM_IDX_MAX 1 + +enum sm_state_tag { + SM_IDLE = 0, + SM_SCANNING = 1, + SM_JOINING = 2, + SM_STA_ADDING = 3, + SM_BSS_PARAM_SETTING = 4, + SM_AUTHENTICATING = 5, + SM_ASSOCIATING = 6, + SM_ACTIVATING = 7, + SM_DISCONNECTING = 8, + SM_STATE_MAX = 9, +}; + +enum sm_msg_tag { + SM_CONNECT_REQ = 6144, + SM_CONNECT_CFM = 6145, + SM_CONNECT_IND = 6146, + SM_DISCONNECT_REQ = 6147, + SM_DISCONNECT_CFM = 6148, + SM_DISCONNECT_IND = 6149, + SM_RSP_TIMEOUT_IND = 6150, +}; + +struct sm_connect_req { + struct mac_ssid ssid; // +0 + struct mac_addr bssid; // +34 + struct scan_chan_tag chan; // +40 + uint32_t flags; // +48 + uint16_t ctrl_port_ethertype; // +52 + uint16_t ie_len; // +54 + uint16_t listen_interval; // +56 + bool dont_wait_bcmc; // +58 + uint8_t auth_type; // +59 + uint8_t uapsd_queues; // +60 + uint8_t vif_idx; // +61 + uint32_t ie_buf[64]; // +64 + bool is_supplicant_enabled; // +320 + uint8_t phrase[64]; // +321 + uint8_t phrase_pmk[64]; // +385 +}; + +struct sm_connect_cfm { + uint8_t status; // +0 +}; + +struct sm_connect_ind { + uint16_t status_code; // +0 + struct mac_addr bssid; // +2 + bool roamed; // +8 + uint8_t vif_idx; // +9 + uint8_t ap_idx; // +10 + uint8_t ch_idx; // +11 + bool qos; // +12 + uint8_t acm; // +13 + uint16_t assoc_req_ie_len; // +14 + uint16_t assoc_rsp_ie_len; // +16 + uint32_t assoc_ie_buf[200]; // +20 + uint16_t aid; // +820 + uint8_t band; // +822 + uint16_t center_freq; // +824 + uint8_t width; // +826 + uint32_t center_freq1; // +828 + uint32_t center_freq2; // +832 + uint32_t ac_param[4]; // +836 +}; + +struct sm_disconnect_req { + uint16_t reason_code; // +0 + uint8_t vif_idx; // +2 +}; + +struct sm_disconnect_ind { + uint16_t reason_code; // +0 + uint8_t vif_idx; // +2 + bool ft_over_ds; // +3 +}; + + +extern const struct ke_state_handler sm_default_handler; +extern ke_state_t sm_state[SM_IDX_MAX]; + +#endif // _SM_TASK_H_ diff --git a/src/include/bl602_wifi/umac/txu/txu_cntrl.h b/src/include/bl602_wifi/umac/txu/txu_cntrl.h new file mode 100644 index 0000000..87cd395 --- /dev/null +++ b/src/include/bl602_wifi/umac/txu/txu_cntrl.h @@ -0,0 +1,68 @@ +#ifndef __TXU_CNTRL_H__ +#define __TXU_CNTRL_H__ + +#include +#include + +#include + +/* + * DEFINES + **************************************************************************************** + */ + +/// status bit verified at umac +#define TX_STATUS_RETRY_REACHED 0x0800 + +/// Frame transmission done +#define TX_STATUS_DONE CO_BIT(0) +/// Frame retry required +#define TX_STATUS_RETRY_REQUIRED CO_BIT(1) +/// Frame sw retry required +#define TX_STATUS_SW_RETRY_REQUIRED CO_BIT(2) + +#define TXU_CNTRL_RETRY CO_BIT(0) +#define TXU_CNTRL_UNDER_BA CO_BIT(1) +#define TXU_CNTRL_MORE_DATA CO_BIT(2) +/** + * TX Frame is a management frame: + * - WLAN header is already provided, no need to transform an ethernet header + * - Frame shall be sent as a singleton + */ +#define TXU_CNTRL_MGMT CO_BIT(3) +/** + * No CCK rate can be used (valid only if TXU_CNTRL_MGMT is set) + */ +#define TXU_CNTRL_MGMT_NO_CCK CO_BIT(4) +/** + * Internal flags indicating that the PM monitoring has been started for this frame + */ +#define TXU_CNTRL_MGMT_PM_MON CO_BIT(5) +#define TXU_CNTRL_AMSDU CO_BIT(6) +#define TXU_CNTRL_MGMT_ROBUST CO_BIT(7) +#define TXU_CNTRL_USE_4ADDR CO_BIT(8) +#define TXU_CNTRL_EOSP CO_BIT(9) +#define TXU_CNTRL_MESH_FWD CO_BIT(10) +#define TXU_CNTRL_TDLS CO_BIT(11) + +/* + * ENUMERATION + **************************************************************************************** + */ + +// Information Field Bit Field +enum txu_cntrl_info_bit +{ + TXU_CNTRL_IV_PRESENT = 0, + TXU_CNTRL_EIV_PRESENT, + TXU_CNTRL_LLCSNAP_ADD, +}; + + +bool txu_cntrl_push(struct txdesc *txdesc, uint8_t access_category); +void txu_cntrl_frame_build(struct txdesc *txdesc, uint32_t buf); +void txu_cntrl_tkip_mic_append(struct txdesc *txdesc, uint8_t ac); +void txu_cntrl_cfm(struct txdesc *txdesc); +void txu_cntrl_protect_mgmt_frame(struct txdesc *txdesc, uint32_t frame, uint16_t hdr_len); + +#endif // __TXU_CNTRL_H__ diff --git a/src/include/blconfig.h b/src/include/blconfig.h new file mode 100644 index 0000000..0d6b767 --- /dev/null +++ b/src/include/blconfig.h @@ -0,0 +1,153 @@ +#ifndef _BLCONFIG_H_ +#define _BLCONFIG_H_ + +// from hal_machw_init nxmac_max_rx_length_set(0x1000) +#define CFG_AMSDU_4K + +#ifndef CFG_TXDESC +#define CFG_TXDESC 4 +#endif +#define NX_TXDESC_CNT0 CFG_TXDESC +#define NX_CHAN_CTXT_CNT 3 + +#define CFG_STA_MAX 10 +// #define NX_REMOTE_STA_MAX CFG_STA_MAX +// this is 10 given by the sizeof txl_buffer_control_desc +// no I think the value should be 3.. +#define NX_REMOTE_STA_MAX 3 + +// == txl_buffer_control_desc_bcmc +#define NX_VIRT_DEV_MAX 2 + +#define NX_BEACONING 1 + +#define NX_TD 1 +#define NX_POWERSAVE 1 +#define NX_MM_TIMER 1 +#define NX_HW_SCAN 1 +#define NX_CHNL_CTXT 1 +#define NX_GP_DMA 1 +#define NX_MULTI_ROLE 1 +#define NX_CONNECTION_MONITOR 1 +#define NX_BCN_AUTONOMOUS_TX 1 +#define NX_MFP 0 +#define NX_KEY_RAM_CONFIG 1 +#define NX_UAPSD 1 +#define NX_DPSM 1 +#define NX_AMPDU_TX 0 +#define NX_AMSDU_TX 0 +#define NX_P2P 0 +#define NX_P2P_GO 0 +#define NX_REORD 0 +#define TDLS_ENABLE 0 +#define RW_BFMEE_EN 0 +#define RW_BFMER_EN 0 +#define RW_MUMIMO_RX_EN 0 +#define RW_MUMIMO_TX_EN 0 +#define RW_WAPI_EN 0 +#define NX_VHT 0 +#define NX_RX_FRAME_HANDLING 1 + +#define NX_TXQ_CNT (AC_MAX + NX_BEACONING) + +/// == 13 not 17, because of the loop in rxl_hwdesc_init +/// Number of RX descriptors (SW and Header descriptors) +#define NX_RXDESC_CNT 13 + +/// Maximum size of A-MSDU supported in reception +#if defined CFG_AMSDU_4K +#define RWNX_MAX_AMSDU_RX 4096 +#elif defined CFG_AMSDU_8K +#define RWNX_MAX_AMSDU_RX 8192 +#elif defined CFG_AMSDU_12K +#define RWNX_MAX_AMSDU_RX 12288 +#endif + +/// Beamformer support +#if defined CFG_BFMER + #define RW_BFMER_EN 1 + #define RW_BFR_TXFRAME_CNT CFG_MU_CNT +#else //defined CFG_BFMER + #define RW_BFMER_EN 0 + #define RW_BFR_TXFRAME_CNT 0 + // Disable MU-MIMO TX if Beamformer is not supported + #undef CFG_MU_CNT + #define CFG_MU_CNT 1 +#endif //defined CFG_BFMER + +/// Number of users supported +#define RW_USER_MAX CFG_MU_CNT + +#if (NX_BEACONING) +/// Number of TX descriptors available in the system (BCN) +#define CFG_TXDESC4 4 +#define NX_TXDESC_CNT4 CFG_TXDESC4 +#if (NX_TXDESC_CNT4 & (NX_TXDESC_CNT4 - 1)) +#error "Not a power of 2" +#endif +#endif + +#define NX_BCNFRAME_LEN 512 + +// == 4 for some reason? +#define NX_TXFRAME_CNT NX_VIRT_DEV_MAX + RW_BFR_TXFRAME_CNT + 2 + +#if (NX_P2P) + #define NX_TXFRAME_LEN 384 +#else + #define NX_TXFRAME_LEN 256 +#endif //(NX_P2P) + +/// Wireless Mesh Networking support +#if defined CFG_MESH + #define RW_MESH_EN (1) + #define RW_UMESH_EN (1) + #define RW_MESH_VIF_NB (CFG_MESH_VIF) + #define RW_MESH_LINK_NB (CFG_MESH_LINK) + #define RW_MESH_PATH_NB (CFG_MESH_PATH) + #define RW_MESH_PROXY_NB (CFG_MESH_PROXY) + + // If Mesh is supported, enable MFP feature + #undef CFG_MFP + #define CFG_MFP (1) +#else + #define RW_MESH_EN (0) + #define RW_UMESH_EN (0) + #define RW_MESH_VIF_NB (0) + #define RW_MESH_LINK_NB (0) + #define RW_MESH_PATH_NB (0) + #define RW_MESH_PROXY_NB (0) +#endif //defined CFG_MESH + +/// RX Payload buffer size +#define NX_RX_PAYLOAD_LEN 848 + +/// Number of RX payload descriptors - defined to be twice the maximum A-MSDU size +/// plus one extra one used for HW flow control +// NX_RX_PAYLOAD_DESC_CNT == 13 based on sizeof rx_payload_desc +// RWNX_MAX_AMSDU_RX / NX_RX_PAYLOAD_LEN == 6 +// * 2 only gets 9, I guess it's *3 +#define NX_RX_PAYLOAD_DESC_CNT ((RWNX_MAX_AMSDU_RX / NX_RX_PAYLOAD_LEN) * 3 + 1) + +#define CFG_MODE_SWITCH 0 +#undef CONFIG_AOS_MESH + +#define NX_VERSION_MAJ 5 +/// Minor version number +#define NX_VERSION_MIN 0 +/// Release number +#define NX_VERSION_REL 4 +/// Patch number +#define NX_VERSION_PAT 0 + +/// Version word +#define NX_VERSION ((NX_VERSION_MAJ << 24) | (NX_VERSION_MIN << 16) | \ + (NX_VERSION_REL << 8) | NX_VERSION_PAT) + + + + +#define PACKED __attribute__((packed, aligned(1))) + + +#endif \ No newline at end of file diff --git a/src/include/macro.h b/src/include/macro.h new file mode 100644 index 0000000..33fc569 --- /dev/null +++ b/src/include/macro.h @@ -0,0 +1,56 @@ +#ifndef _MACRO_H_ +#define _MACRO_H_ + +#define EXPAND(...) __VA_ARGS__ + +#define EVAL5(...) EXPAND(EXPAND(__VA_ARGS__)) +#define EVAL4(...) EVAL5(EVAL5(__VA_ARGS__)) +#define EVAL3(...) EVAL4(EVAL4(__VA_ARGS__)) +#define EVAL2(...) EVAL3(EVAL3(__VA_ARGS__)) +#define EVAL1(...) EVAL2(EVAL2(__VA_ARGS__)) +#define EVAL(...) EVAL1(EVAL1(__VA_ARGS__)) + +#define FIRST(a, ...) a +#define SECOND(a, b, ...) b + +#define IS_PROBE(...) SECOND(__VA_ARGS__, 0) +#define PROBE() 0,1 +#define NOT_0 PROBE() +#define NOT(x) IS_PROBE(CAT(NOT_, x)) +#define BOOL(x) NOT(NOT(x)) + + +#define EAT(...) +#define DEFER(x) x EMPTY() +#define DEFER2(x) x EMPTY EMPTY()() +#define EMPTY() + +#define CAT(a,b) a ## b + +#define IF(c) _IF(BOOL(c)) +#define _IF(c) CAT(_IF_,c) +#define _IF_0(...) +#define _IF_1(...) __VA_ARGS__ + +#define HAS_ARGS(...) BOOL(FIRST(_END_OF_ARGUMENTS_ __VA_ARGS__)(0)) +#define _END_OF_ARGUMENTS_(...) BOOL(FIRST(__VA_ARGS__)) + +#define APPLY_NEXT(func, a, ...) \ + func(a) \ + IF(HAS_ARGS(__VA_ARGS__)) (DEFER2(_APPLY_NEXT)()(func, __VA_ARGS__)) +#define APPLY(func, ...) \ + IF(HAS_ARGS(__VA_ARGS__)) (EVAL(APPLY_NEXT(func, ##__VA_ARGS__))) +#define _APPLY_NEXT() APPLY_NEXT + +#define APPLYarg_NEXT(func, arg, a, ...) \ + func(arg, a) \ + IF(HAS_ARGS(__VA_ARGS__)) (DEFER2(_APPLYarg_NEXT)()(func, arg, __VA_ARGS__)) +#define APPLYarg(func, arg, ...) \ + IF(HAS_ARGS(__VA_ARGS__)) (EVAL(APPLYarg_NEXT(func, arg, ##__VA_ARGS__))) +#define _APPLYarg_NEXT() APPLYarg_NEXT + +#define PACK(var, name) for (int tip = 1; tip;) for (__typeof__ (var) name = var; tip; tip = 0, var = name) +#define PACK0(var, name) for (int tip = 1; tip;) for (__typeof__ (var) name = {0}; tip; tip = 0, var = name) +#define EXTRACT(var, name) for (int tip = 1; tip;) for (__typeof__ (var) name = var; tip; tip = 0) +#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1] +#endif \ No newline at end of file diff --git a/src/include/phy/agc.h b/src/include/phy/agc.h index a58e169..8943ab2 100644 --- a/src/include/phy/agc.h +++ b/src/include/phy/agc.h @@ -1,3 +1,4 @@ +#ifndef AGC_BASE typedef union { uint32_t regs[0x800]; uint8_t pad[0x2000]; @@ -239,7 +240,7 @@ typedef union { } r0xc044; // @ 0x1044 uint8_t pad12[0x38]; uint8_t rxgain_offset_vs_temperature[0x9]; // @ 0x1080 - uint8_t pad13[0xfc]; + uint8_t pad13[0xf7]; union { uint32_t value; struct { @@ -428,4 +429,5 @@ typedef union { }; } agc_regs; #define AGC_BASE 0x44c0b000 -#define AGC ((agc_regs* volatile)(AGC_BASE)) \ No newline at end of file +#define AGC ((volatile agc_regs*)(AGC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/agcram.h b/src/include/phy/agcram.h index e32c3c9..a44b74b 100644 --- a/src/include/phy/agcram.h +++ b/src/include/phy/agcram.h @@ -1,3 +1,4 @@ +#ifndef AGCRAM_BASE typedef union { uint32_t regs[0x200]; uint8_t pad[0x800]; @@ -6,4 +7,5 @@ typedef union { }; } agcram_regs; #define AGCRAM_BASE 0x54c0a000 -#define AGCRAM ((agcram_regs* volatile)(AGCRAM_BASE)) \ No newline at end of file +#define AGCRAM ((volatile agcram_regs*)(AGCRAM_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/bz_phy.h b/src/include/phy/bz_phy.h index 4e30a52..277612e 100644 --- a/src/include/phy/bz_phy.h +++ b/src/include/phy/bz_phy.h @@ -1,3 +1,4 @@ +#ifndef BZ_PHY_BASE typedef union { uint32_t regs[0xc0]; uint8_t pad[0x300]; @@ -883,4 +884,5 @@ typedef union { }; } bz_phy_regs; #define BZ_PHY_BASE 0x40002800 -#define BZ_PHY ((bz_phy_regs* volatile)(BZ_PHY_BASE)) \ No newline at end of file +#define BZ_PHY ((volatile bz_phy_regs*)(BZ_PHY_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/bz_phy_agc.h b/src/include/phy/bz_phy_agc.h index ee4702f..fe71eb0 100644 --- a/src/include/phy/bz_phy_agc.h +++ b/src/include/phy/bz_phy_agc.h @@ -1,3 +1,4 @@ +#ifndef BZ_PHY_AGC_BASE typedef union { uint32_t regs[0x40]; uint8_t pad[0x100]; @@ -583,4 +584,5 @@ typedef union { }; } bz_phy_agc_regs; #define BZ_PHY_AGC_BASE 0x40002c00 -#define BZ_PHY_AGC ((bz_phy_agc_regs* volatile)(BZ_PHY_AGC_BASE)) \ No newline at end of file +#define BZ_PHY_AGC ((volatile bz_phy_agc_regs*)(BZ_PHY_AGC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/dma.h b/src/include/phy/dma.h index 9c4e2fd..52519c5 100644 --- a/src/include/phy/dma.h +++ b/src/include/phy/dma.h @@ -1,3 +1,4 @@ +#ifndef DMA_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; @@ -88,4 +89,5 @@ typedef union { }; } dma_regs; #define DMA_BASE 0x44a00000 -#define DMA ((dma_regs* volatile)(DMA_BASE)) \ No newline at end of file +#define DMA ((volatile dma_regs*)(DMA_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/intc.h b/src/include/phy/intc.h new file mode 100644 index 0000000..3a103bc --- /dev/null +++ b/src/include/phy/intc.h @@ -0,0 +1,17 @@ +#ifndef INTC_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint32_t irq_status[0x2]; // @ 0x0 + uint32_t irq_raw_status[0x2]; // @ 0x8 + uint32_t irq_unmask_set[0x2]; // @ 0x10 + uint32_t irq_unmask_clear[0x2]; // @ 0x18 + uint32_t irq_polarity[0x2]; // @ 0x20 + uint8_t pad0[0x18]; + uint32_t irq_index; // @ 0x40 + }; +} intc_regs; +#define INTC_BASE 0x44910000 +#define INTC ((volatile intc_regs*)(INTC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/ipc.h b/src/include/phy/ipc.h index c20a865..309064b 100644 --- a/src/include/phy/ipc.h +++ b/src/include/phy/ipc.h @@ -1,52 +1,71 @@ +#ifndef IPC_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; struct { + uint32_t app2emb_trigger; // @ 0x0 + uint32_t emb2app_rawstatus; // @ 0x4 + uint32_t emb2app_ack; // @ 0x8 + uint32_t emb2app_unmask_set; // @ 0xc + uint32_t emb2app_unmask_clear; // @ 0x10 union { uint32_t value; struct { - uint32_t APP2EMB_TRIGGER : 32; // @ 31 -- 0 # 0x0 + uint32_t emb2app0_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t emb2app1_sel : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t emb2app2_sel : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t emb2app3_sel : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t emb2app4_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t emb2app5_sel : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t emb2app6_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t emb2app7_sel : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t emb2app8_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t emb2app9_sel : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t emb2app10_sel : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t emb2app11_sel : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t emb2app12_sel : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t emb2app13_sel : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t emb2app14_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t emb2app15_sel : 2; // @ 31 -- 30 # 0x3fffffff }; - } APP2EMB_TRIGGER; // @ 0x0 + } emb2app_line_sel_low; // @ 0x14 + uint32_t emb2app_line_sel_high; // @ 0x18 + uint32_t emb2app_status; // @ 0x1c + uint8_t pad0[0x20]; + uint32_t app_signature; // @ 0x40 + uint8_t pad1[0xbc]; + uint32_t emb2app_trigger; // @ 0x100 + uint32_t app2emb_rawstatus; // @ 0x104 + uint32_t app2emb_ack; // @ 0x108 + uint32_t app2emb_unmask_set; // @ 0x10c + uint32_t app2emb_unmask_clear; // @ 0x110 union { uint32_t value; struct { - uint32_t EMB2APP_RAWSTATUS : 32; // @ 31 -- 0 # 0x0 + uint32_t app2emb0_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t app2emb1_sel : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t app2emb2_sel : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t app2emb3_sel : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t app2emb4_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t app2emb5_sel : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t app2emb6_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t app2emb7_sel : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t app2emb8_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t app2emb9_sel : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t app2emb10_sel : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t app2emb11_sel : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t app2emb12_sel : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t app2emb13_sel : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t app2emb14_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t app2emb15_sel : 2; // @ 31 -- 30 # 0x3fffffff }; - } EMB2APP_RAWSTATUS; // @ 0x4 - union { - uint32_t value; - struct { - uint32_t EMB2APP_ACK : 32; // @ 31 -- 0 # 0x0 - }; - } EMB2APP_ACK; // @ 0x8 - union { - uint32_t value; - struct { - uint32_t EMB2APP_UNMASK : 32; // @ 31 -- 0 # 0x0 - }; - } EMB2APP_UNMASK_SET; // @ 0xc - union { - uint32_t value; - struct { - uint32_t EMB2APP_UNMASK : 32; // @ 31 -- 0 # 0x0 - }; - } EMB2APP_UNMASK_CLEAR; // @ 0x10 - uint8_t pad0[0x8]; - union { - uint32_t value; - struct { - uint32_t EMB2APP_STATUS : 32; // @ 31 -- 0 # 0x0 - }; - } EMB2APP_STATUS; // @ 0x1c - uint8_t pad1[0x20]; - union { - uint32_t value; - struct { - uint32_t APP_SIGNATURE : 32; // @ 31 -- 0 # 0x0 - }; - } APP_SIGNATURE; // @ 0x40 + } app2emb_line_sel_low; // @ 0x114 + uint32_t app2emb_line_sel_high; // @ 0x118 + uint32_t app2emb_status; // @ 0x11c + uint8_t pad2[0x20]; + uint32_t emb_signature; // @ 0x140 }; } ipc_regs; #define IPC_BASE 0x44800000 -#define IPC ((ipc_regs* volatile)(IPC_BASE)) \ No newline at end of file +#define IPC ((volatile ipc_regs*)(IPC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/mac_core.h b/src/include/phy/mac_core.h index f869d75..8a5f7db 100644 --- a/src/include/phy/mac_core.h +++ b/src/include/phy/mac_core.h @@ -1,3 +1,4 @@ +#ifndef MAC_CORE_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; @@ -362,7 +363,15 @@ typedef union { uint32_t encrIntKeyRAMWord3 : 32; // @ 31 -- 0 # 0x0 }; } ENCR_WPI_INT_KEY_3; // @ 0xd4 - uint8_t pad6[0x4]; + union { + uint32_t value; + struct { + uint32_t start : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t end : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t nVAP : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t max : 8; // @ 31 -- 24 # 0xffffff + }; + } encr_ram_config; // @ 0xd8 union { uint32_t value; struct { @@ -454,7 +463,7 @@ typedef union { uint32_t pad0 : 2; }; } TIMINGS_9; // @ 0x104 - uint8_t pad7[0x4]; + uint8_t pad6[0x4]; union { uint32_t value; struct { @@ -509,13 +518,7 @@ typedef union { uint32_t pad0 : 16; }; } MONOTONIC_COUNTER_2_HI; // @ 0x124 - union { - uint32_t value; - struct { - uint32_t absTimerValue : 32; // @ 31 -- 0 # 0x0 - }; - } ABS_TIMER; // @ 0x128 - uint8_t pad8[0x24]; + uint32_t ABS_TIMER[0xa]; // @ 0x128 union { uint32_t value; struct { @@ -523,7 +526,7 @@ typedef union { uint32_t pad0 : 12; }; } MAX_RX_LENGTH; // @ 0x150 - uint8_t pad9[0xac]; + uint8_t pad7[0xac]; union { uint32_t value; struct { @@ -564,7 +567,7 @@ typedef union { uint32_t pad0 : 4; }; } EDCA_AC_3; // @ 0x20c - uint8_t pad10[0x10]; + uint8_t pad8[0x10]; union { uint32_t value; struct { @@ -582,7 +585,7 @@ typedef union { uint32_t pad1 : 26; }; } EDCA_CNTRL; // @ 0x224 - uint8_t pad11[0x58]; + uint8_t pad9[0x58]; union { uint32_t value; struct { @@ -631,7 +634,7 @@ typedef union { uint32_t ccaBusyDurSec80 : 32; // @ 31 -- 0 # 0x0 }; } ADD_CCA_BUSY_SEC_80; // @ 0x298 - uint8_t pad12[0x64]; + uint8_t pad10[0x64]; union { uint32_t value; struct { @@ -700,7 +703,7 @@ typedef union { uint32_t pad0 : 10; }; } HTMCS; // @ 0x314 - uint8_t pad13[0x4]; + uint8_t pad11[0x4]; union { uint32_t value; struct { @@ -715,16 +718,22 @@ typedef union { uint32_t pad0 : 31; }; } LSTP; // @ 0x320 - uint8_t pad14[0xdc]; + uint8_t pad12[0xdc]; union { uint32_t value; struct { uint32_t coexEnable : 1; // @ 0 -- 0 # 0xfffffffe - uint32_t pad0 : 11; + uint32_t pad0 : 3; + uint32_t coexForceEnable : 1; // @ 4 -- 4 # 0xffffffef + uint32_t coexAutoPTIAdjEnable : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 6; uint32_t coexWlanChanOffset : 1; // @ 12 -- 12 # 0xffffefff - uint32_t pad1 : 3; + uint32_t pad2 : 3; uint32_t coexWlanChanFreq : 7; // @ 22 -- 16 # 0xff80ffff - uint32_t pad2 : 9; + uint32_t pad3 : 3; + uint32_t coexForceWlanChanBw : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t coexForceWlanPtiToggle : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t coexForceWlanPti : 4; // @ 31 -- 28 # 0xfffffff }; } COEX_CONTROL; // @ 0x400 union { @@ -740,7 +749,8 @@ typedef union { uint32_t coexPTIBcnData : 4; // @ 31 -- 28 # 0xfffffff }; } COEX_PTI; // @ 0x404 - uint8_t pad15[0xf8]; + uint32_t coex_stat; // @ 0x408 + uint8_t pad13[0xf4]; union { uint32_t value; struct { @@ -761,7 +771,7 @@ typedef union { uint32_t macControlCs : 8; // @ 31 -- 24 # 0xffffff }; } DEBUG_HWSM_2; // @ 0x504 - uint8_t pad16[0x4]; + uint8_t pad14[0x4]; union { uint32_t value; struct { @@ -814,7 +824,7 @@ typedef union { uint32_t ac3QLRC : 8; // @ 31 -- 24 # 0xffffff }; } DEBUG_QLRC; // @ 0x520 - uint8_t pad17[0x38]; + uint8_t pad15[0x38]; union { uint32_t value; struct { @@ -825,4 +835,5 @@ typedef union { }; } mac_core_regs; #define MAC_CORE_BASE 0x44b00000 -#define MAC_CORE ((mac_core_regs* volatile)(MAC_CORE_BASE)) \ No newline at end of file +#define MAC_CORE ((volatile mac_core_regs*)(MAC_CORE_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/mac_pl.h b/src/include/phy/mac_pl.h index 918266a..4a4758b 100644 --- a/src/include/phy/mac_pl.h +++ b/src/include/phy/mac_pl.h @@ -1,3 +1,4 @@ +#ifndef MAC_PL_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; @@ -867,4 +868,5 @@ typedef union { }; } mac_pl_regs; #define MAC_PL_BASE 0x44b08000 -#define MAC_PL ((mac_pl_regs* volatile)(MAC_PL_BASE)) \ No newline at end of file +#define MAC_PL ((volatile mac_pl_regs*)(MAC_PL_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/mdm.h b/src/include/phy/mdm.h index 1ab9362..bc88107 100644 --- a/src/include/phy/mdm.h +++ b/src/include/phy/mdm.h @@ -1,3 +1,4 @@ +#ifndef MDM_BASE typedef union { uint32_t regs[0x1000]; uint8_t pad[0x4000]; @@ -162,4 +163,5 @@ typedef union { }; } mdm_regs; #define MDM_BASE 0x44c00000 -#define MDM ((mdm_regs* volatile)(MDM_BASE)) \ No newline at end of file +#define MDM ((volatile mdm_regs*)(MDM_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/sysctrl.h b/src/include/phy/sysctrl.h index 8f186ab..b36b6f2 100644 --- a/src/include/phy/sysctrl.h +++ b/src/include/phy/sysctrl.h @@ -1,3 +1,4 @@ +#ifndef SYSCTRL_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; @@ -10,7 +11,8 @@ typedef union { uint32_t pad0 : 16; }; } diag_conf; // @ 0x68 - uint8_t pad1[0x8]; + uint8_t pad1[0x4]; + uint32_t diag_trigger; // @ 0x70 uint32_t r074; // @ 0x74 uint8_t pad2[0xc]; union { @@ -32,4 +34,5 @@ typedef union { }; } sysctrl_regs; #define SYSCTRL_BASE 0x44900000 -#define SYSCTRL ((sysctrl_regs* volatile)(SYSCTRL_BASE)) \ No newline at end of file +#define SYSCTRL ((volatile sysctrl_regs*)(SYSCTRL_BASE)) +#endif \ No newline at end of file diff --git a/src/include/phy/sysctrl92.h b/src/include/phy/sysctrl92.h index a137b6b..0ff7574 100644 --- a/src/include/phy/sysctrl92.h +++ b/src/include/phy/sysctrl92.h @@ -1,3 +1,4 @@ +#ifndef SYSCTRL92_BASE typedef union { uint32_t regs[0x400]; uint8_t pad[0x1000]; @@ -7,4 +8,5 @@ typedef union { }; } sysctrl92_regs; #define SYSCTRL92_BASE 0x44920000 -#define SYSCTRL92 ((sysctrl92_regs* volatile)(SYSCTRL92_BASE)) \ No newline at end of file +#define SYSCTRL92 ((volatile sysctrl92_regs*)(SYSCTRL92_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/AON.h b/src/include/soc/AON.h new file mode 100644 index 0000000..713e7a2 --- /dev/null +++ b/src/include/soc/AON.h @@ -0,0 +1,399 @@ +#ifndef AON_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint8_t pad0[0x800]; + union { + uint32_t value; + struct { + uint32_t aon_resv : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 4; + uint32_t pu_aon_dc_tbuf : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad1 : 7; + uint32_t ldo11_rt_pulldown : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ldo11_rt_pulldown_sel : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t sw_pu_ldo11_rt : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad2 : 9; + }; + } aon; // @ 0x800 + union { + uint32_t value; + struct { + uint32_t tmux_aon : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t ten_aon : 1; // @ 4 -- 4 # 0xffffffef + uint32_t dten_xtal32k : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t ten_xtal32k : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad1 : 1; + uint32_t ten_vddcore_aon : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t ten_ldo11soc_aon : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t ten_dcdc18_0_aon : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t ten_dcdc18_1_aon : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t ten_bg_sys_aon : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad2 : 3; + uint32_t ten_ldo15rf_aon : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ten_xtal_aon : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t dten_xtal_aon : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ten_mbg_aon : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ten_cip_misc_aon : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad3 : 11; + }; + } aon_common; // @ 0x804 + union { + uint32_t value; + struct { + uint32_t sw_soc_en_aon : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sw_wb_en_aon : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } aon_misc; // @ 0x808 + uint8_t pad1[0x4]; + union { + uint32_t value; + struct { + uint32_t pmip_resv : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pu_bg_sys_aon : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad0 : 3; + uint32_t bg_sys_start_ctrl_aon : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad1 : 19; + }; + } bg_sys_top; // @ 0x810 + union { + uint32_t value; + struct { + uint32_t pad0 : 1; + uint32_t dcdc18_vout_sel_aon : 5; // @ 5 -- 1 # 0xffffffc1 + uint32_t pad1 : 2; + uint32_t dcdc18_vpfm_aon : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t dcdc18_osc_2m_mode_aon : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad2 : 3; + uint32_t dcdc18_osc_freq_trim_aon : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t dcdc18_slope_curr_sel_aon : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t dcdc18_stop_osc_aon : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t dcdc18_slow_osc_aon : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t dcdc18_osc_inhibit_t2_aon : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t dcdc18_sstart_time_aon : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t pad3 : 1; + uint32_t dcdc18_rdy_aon : 1; // @ 31 -- 31 # 0x7fffffff + }; + } dcdc18_top_0; // @ 0x814 + union { + uint32_t value; + struct { + uint32_t dcdc18_force_cs_zvs_aon : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t dcdc18_cs_delay_aon : 3; // @ 3 -- 1 # 0xfffffff1 + uint32_t dcdc18_zvs_td_opt_aon : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad0 : 1; + uint32_t dcdc18_nonoverlap_td_aon : 5; // @ 12 -- 8 # 0xffffe0ff + uint32_t pad1 : 3; + uint32_t dcdc18_rc_sel_aon : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t dcdc18_chf_sel_aon : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t dcdc18_cfb_sel_aon : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t dcdc18_en_antiring_aon : 1; // @ 28 -- 28 # 0xefffffff + uint32_t dcdc18_pulldown_aon : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad2 : 2; + }; + } dcdc18_top_1; // @ 0x818 + union { + uint32_t value; + struct { + uint32_t pu_ldo11soc_aon : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t ldo11soc_sstart_sel_aon : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t ldo11soc_sstart_delay_aon : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t ldo11soc_pulldown_aon : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t ldo11soc_pulldown_sel_aon : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t ldo11soc_vth_sel_aon : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pad2 : 10; + uint32_t ldo11soc_cc_aon : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad3 : 2; + uint32_t ldo11soc_rdy_aon : 1; // @ 28 -- 28 # 0xefffffff + uint32_t ldo11soc_power_good_aon : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pu_vddcore_misc_aon : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t pmip_dc_tp_out_en_aon : 1; // @ 31 -- 31 # 0x7fffffff + }; + } ldo11soc_and_dctest; // @ 0x81c + union { + uint32_t value; + struct { + uint32_t pu_ir_psw_aon : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } psw_irrcv; // @ 0x820 + uint8_t pad2[0x5c]; + union { + uint32_t value; + struct { + uint32_t pu_mbg_aon : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pu_ldo15rf_aon : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pu_sfreg_aon : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t pu_xtal_buf_aon : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pu_xtal_aon : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 2; + uint32_t ldo15rf_sstart_sel_aon : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t ldo15rf_sstart_delay_aon : 2; // @ 10 -- 9 # 0xfffff9ff + uint32_t pad2 : 1; + uint32_t ldo15rf_pulldown_aon : 1; // @ 12 -- 12 # 0xffffefff + uint32_t ldo15rf_pulldown_sel_aon : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad3 : 2; + uint32_t ldo15rf_vout_sel_aon : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad4 : 5; + uint32_t ldo15rf_cc_aon : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad5 : 2; + uint32_t ldo15rf_bypass_aon : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad6 : 3; + }; + } rf_top_aon; // @ 0x880 + union { + uint32_t value; + struct { + uint32_t xtal_bk_aon : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t xtal_capcode_extra_aon : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t xtal_ext_sel_aon : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t xtal_buf_en_aon : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t xtal_buf_hp_aon : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t xtal_fast_startup_aon : 1; // @ 12 -- 12 # 0xffffefff + uint32_t xtal_sleep_aon : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t xtal_amp_ctrl_aon : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t xtal_capcode_out_aon : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t xtal_capcode_in_aon : 6; // @ 27 -- 22 # 0xf03fffff + uint32_t xtal_gm_boost_aon : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t xtal_rdy_sel_aon : 2; // @ 31 -- 30 # 0x3fffffff + }; + } xtal_cfg; // @ 0x884 + union { + uint32_t value; + struct { + uint32_t tsen_refcode_corner : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 4; + uint32_t tsen_refcode_rfcal : 12; // @ 27 -- 16 # 0xf000ffff + uint32_t xtal_rdy : 1; // @ 28 -- 28 # 0xefffffff + uint32_t xtal_inn_cfg_en_aon : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t xtal_rdy_int_sel_aon : 2; // @ 31 -- 30 # 0x3fffffff + }; + } tsen; // @ 0x888 + uint8_t pad3[0x74]; + union { + uint32_t value; + struct { + uint32_t acomp0_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t acomp0_hyst_seln : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t acomp0_hyst_selp : 3; // @ 9 -- 7 # 0xfffffc7f + uint32_t acomp0_bias_prog : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t acomp0_level_sel : 6; // @ 17 -- 12 # 0xfffc0fff + uint32_t acomp0_neg_sel : 4; // @ 21 -- 18 # 0xffc3ffff + uint32_t acomp0_pos_sel : 4; // @ 25 -- 22 # 0xfc3fffff + uint32_t acomp0_muxen : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad1 : 5; + }; + } acomp0_ctrl; // @ 0x900 + union { + uint32_t value; + struct { + uint32_t acomp1_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t acomp1_hyst_seln : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t acomp1_hyst_selp : 3; // @ 9 -- 7 # 0xfffffc7f + uint32_t acomp1_bias_prog : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t acomp1_level_sel : 6; // @ 17 -- 12 # 0xfffc0fff + uint32_t acomp1_neg_sel : 4; // @ 21 -- 18 # 0xffc3ffff + uint32_t acomp1_pos_sel : 4; // @ 25 -- 22 # 0xfc3fffff + uint32_t acomp1_muxen : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad1 : 5; + }; + } acomp1_ctrl; // @ 0x904 + union { + uint32_t value; + struct { + uint32_t acomp1_rstn_ana : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t acomp0_rstn_ana : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 6; + uint32_t acomp1_test_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t acomp0_test_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t acomp1_test_sel : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t acomp0_test_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pad1 : 3; + uint32_t acomp1_out_raw : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pad2 : 1; + uint32_t acomp0_out_raw : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pad3 : 4; + uint32_t acomp_reserved : 8; // @ 31 -- 24 # 0xffffff + }; + } acomp_ctrl; // @ 0x908 + union { + uint32_t value; + struct { + uint32_t gpadc_global_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpadc_conv_start : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t gpadc_soft_rst : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t gpadc_neg_sel : 5; // @ 7 -- 3 # 0xffffff07 + uint32_t gpadc_pos_sel : 5; // @ 12 -- 8 # 0xffffe0ff + uint32_t gpadc_neg_gnd : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t gpadc_micbias_en : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t gpadc_micpga_en : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t gpadc_byp_micboost : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 1; + uint32_t gpadc_dwa_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t gpadc_mic2_diff : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t gpadc_mic1_diff : 1; // @ 20 -- 20 # 0xffefffff + uint32_t gpadc_mic_pga2_gain : 2; // @ 22 -- 21 # 0xff9fffff + uint32_t gpadc_micboost_32db_en : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pad1 : 3; + uint32_t gpadc_chip_sen_pu : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t gpadc_sen_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t gpadc_sen_test_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t pad2 : 1; + }; + } gpadc_reg_cmd; // @ 0x90c + union { + uint32_t value; + struct { + uint32_t gpadc_cal_os_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpadc_cont_conv_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t gpadc_res_sel : 3; // @ 4 -- 2 # 0xffffffe3 + uint32_t pad0 : 12; + uint32_t gpadc_clk_ana_inv : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t gpadc_clk_div_ratio : 3; // @ 20 -- 18 # 0xffe3ffff + uint32_t gpadc_scan_length : 4; // @ 24 -- 21 # 0xfe1fffff + uint32_t gpadc_scan_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t gpadc_dither_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t gpadc_v11_sel : 2; // @ 28 -- 27 # 0xe7ffffff + uint32_t gpadc_v18_sel : 2; // @ 30 -- 29 # 0x9fffffff + uint32_t pad1 : 1; + }; + } gpadc_reg_config1; // @ 0x910 + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t gpadc_diff_mode : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t gpadc_vref_sel : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t gpadc_vbat_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t gpadc_tsext_sel : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t gpadc_ts_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t gpadc_pga_vcm : 2; // @ 8 -- 7 # 0xfffffe7f + uint32_t gpadc_pga_os_cal : 4; // @ 12 -- 9 # 0xffffe1ff + uint32_t gpadc_pga_en : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t gpadc_pga_vcmi_en : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t gpadc_chop_mode : 2; // @ 16 -- 15 # 0xfffe7fff + uint32_t gpadc_bias_sel : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t gpadc_test_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t gpadc_test_sel : 3; // @ 21 -- 19 # 0xffc7ffff + uint32_t gpadc_pga2_gain : 3; // @ 24 -- 22 # 0xfe3fffff + uint32_t gpadc_pga1_gain : 3; // @ 27 -- 25 # 0xf1ffffff + uint32_t gpadc_dly_sel : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t gpadc_tsvbe_low : 1; // @ 31 -- 31 # 0x7fffffff + }; + } gpadc_reg_config2; // @ 0x914 + union { + uint32_t value; + struct { + uint32_t gpadc_scan_pos_0 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t gpadc_scan_pos_1 : 5; // @ 9 -- 5 # 0xfffffc1f + uint32_t gpadc_scan_pos_2 : 5; // @ 14 -- 10 # 0xffff83ff + uint32_t gpadc_scan_pos_3 : 5; // @ 19 -- 15 # 0xfff07fff + uint32_t gpadc_scan_pos_4 : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t gpadc_scan_pos_5 : 5; // @ 29 -- 25 # 0xc1ffffff + uint32_t pad0 : 2; + }; + } gpadc_reg_scn_pos1; // @ 0x918 + union { + uint32_t value; + struct { + uint32_t gpadc_scan_pos_6 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t gpadc_scan_pos_7 : 5; // @ 9 -- 5 # 0xfffffc1f + uint32_t gpadc_scan_pos_8 : 5; // @ 14 -- 10 # 0xffff83ff + uint32_t gpadc_scan_pos_9 : 5; // @ 19 -- 15 # 0xfff07fff + uint32_t gpadc_scan_pos_10 : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t gpadc_scan_pos_11 : 5; // @ 29 -- 25 # 0xc1ffffff + uint32_t pad0 : 2; + }; + } gpadc_reg_scn_pos2; // @ 0x91c + union { + uint32_t value; + struct { + uint32_t gpadc_scan_neg_0 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t gpadc_scan_neg_1 : 5; // @ 9 -- 5 # 0xfffffc1f + uint32_t gpadc_scan_neg_2 : 5; // @ 14 -- 10 # 0xffff83ff + uint32_t gpadc_scan_neg_3 : 5; // @ 19 -- 15 # 0xfff07fff + uint32_t gpadc_scan_neg_4 : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t gpadc_scan_neg_5 : 5; // @ 29 -- 25 # 0xc1ffffff + uint32_t pad0 : 2; + }; + } gpadc_reg_scn_neg1; // @ 0x920 + union { + uint32_t value; + struct { + uint32_t gpadc_scan_neg_6 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t gpadc_scan_neg_7 : 5; // @ 9 -- 5 # 0xfffffc1f + uint32_t gpadc_scan_neg_8 : 5; // @ 14 -- 10 # 0xffff83ff + uint32_t gpadc_scan_neg_9 : 5; // @ 19 -- 15 # 0xfff07fff + uint32_t gpadc_scan_neg_10 : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t gpadc_scan_neg_11 : 5; // @ 29 -- 25 # 0xc1ffffff + uint32_t pad0 : 2; + }; + } gpadc_reg_scn_neg2; // @ 0x924 + union { + uint32_t value; + struct { + uint32_t gpadc_data_rdy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 15; + uint32_t gpadc_reserved : 16; // @ 31 -- 16 # 0xffff + }; + } gpadc_reg_status; // @ 0x928 + union { + uint32_t value; + struct { + uint32_t gpadc_neg_satur : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpadc_pos_satur : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 2; + uint32_t gpadc_neg_satur_clr : 1; // @ 4 -- 4 # 0xffffffef + uint32_t gpadc_pos_satur_clr : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 2; + uint32_t gpadc_neg_satur_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t gpadc_pos_satur_mask : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad2 : 22; + }; + } gpadc_reg_isr; // @ 0x92c + union { + uint32_t value; + struct { + uint32_t gpadc_data_out : 26; // @ 25 -- 0 # 0xfc000000 + uint32_t pad0 : 6; + }; + } gpadc_reg_result; // @ 0x930 + union { + uint32_t value; + struct { + uint32_t gpadc_raw_data : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 20; + }; + } gpadc_reg_raw_result; // @ 0x934 + union { + uint32_t value; + struct { + uint32_t gpadc_os_cal_data : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } gpadc_reg_define; // @ 0x938 + union { + uint32_t value; + struct { + uint32_t hbncore_resv0_data : 32; // @ 31 -- 0 # 0x0 + }; + } hbncore_resv0; // @ 0x93c + union { + uint32_t value; + struct { + uint32_t hbncore_resv1_data : 32; // @ 31 -- 0 # 0x0 + }; + } hbncore_resv1; // @ 0x940 + }; +} AON_regs; +#define AON_BASE 0x4000f000 +#define AON ((volatile AON_regs*)(AON_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/HBN.h b/src/include/soc/HBN.h new file mode 100644 index 0000000..cce4af6 --- /dev/null +++ b/src/include/soc/HBN.h @@ -0,0 +1,211 @@ +#ifndef HBN_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t rtc_ctl : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t hbn_mode : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t trap_mode : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pwrdn_hbn_core : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad0 : 1; + uint32_t pwrdn_hbn_rtc : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t sw_rst : 1; // @ 12 -- 12 # 0xffffefff + uint32_t hbn_dis_pwr_off_ldo11 : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t hbn_dis_pwr_off_ldo11_rt : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t hbn_ldo11_rt_vout_sel : 4; // @ 18 -- 15 # 0xfff87fff + uint32_t hbn_ldo11_aon_vout_sel : 4; // @ 22 -- 19 # 0xff87ffff + uint32_t pu_dcdc18_aon : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t rtc_dly_option : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pwr_on_option : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t sram_slp_option : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t sram_slp : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t hbn_state : 4; // @ 31 -- 28 # 0xfffffff + }; + } HBN_CTL; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t hbn_time_l : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_TIME_L; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t hbn_time_h : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } HBN_TIME_H; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t rtc_time_latch_l : 32; // @ 31 -- 0 # 0x0 + }; + } RTC_TIME_L; // @ 0xc + union { + uint32_t value; + struct { + uint32_t rtc_time_latch_h : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 23; + uint32_t rtc_time_latch : 1; // @ 31 -- 31 # 0x7fffffff + }; + } RTC_TIME_H; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t hbn_pin_wakeup_mode : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t hbn_pin_wakeup_mask : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t pad0 : 3; + uint32_t reg_aon_pad_ie_smt : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 7; + uint32_t reg_en_hw_pu_pd : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 1; + uint32_t irq_bor_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad3 : 1; + uint32_t irq_acomp0_en : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t irq_acomp1_en : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t pin_wakeup_sel : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pin_wakeup_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t pad4 : 4; + }; + } HBN_IRQ_MODE; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t irq_stat : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_IRQ_STAT; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t irq_clr : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_IRQ_CLR; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t pir_hpf_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pir_lpf_sel : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t pir_dis : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 1; + uint32_t pir_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t gpadc_cgen : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t gpadc_nosync : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad2 : 22; + }; + } HBN_PIR_CFG; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t pir_vth : 14; // @ 13 -- 0 # 0xffffc000 + uint32_t pad0 : 18; + }; + } HBN_PIR_VTH; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t pir_interval : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 20; + }; + } HBN_PIR_INTERVAL; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t bor_sel : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t bor_vth : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pu_bor : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t r_bor_out : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 28; + }; + } HBN_BOR_CFG; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t hbn_root_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t hbn_uart_clk_sel : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t hbn_f32k_sel : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t hbn_pu_rc32k : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 10; + uint32_t sw_ldo11soc_vout_sel_aon : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t pad1 : 4; + uint32_t sw_ldo11_rt_vout_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t sw_ldo11_aon_vout_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } HBN_GLB; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t pad0 : 6; + uint32_t retram_ret : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t retram_slp : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad1 : 24; + }; + } HBN_SRAM; // @ 0x34 + uint8_t pad0[0xc8]; + union { + uint32_t value; + struct { + uint32_t HBN_RSV0 : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_RSV0; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t HBN_RSV1 : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_RSV1; // @ 0x104 + union { + uint32_t value; + struct { + uint32_t HBN_RSV2 : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_RSV2; // @ 0x108 + union { + uint32_t value; + struct { + uint32_t HBN_RSV3 : 32; // @ 31 -- 0 # 0x0 + }; + } HBN_RSV3; // @ 0x10c + uint8_t pad1[0xf0]; + union { + uint32_t value; + struct { + uint32_t rc32k_cal_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rc32k_rdy : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rc32k_cal_inprogress : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rc32k_cal_div : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t rc32k_cal_precharge : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rc32k_dig_code_fr_cal : 10; // @ 15 -- 6 # 0xffff003f + uint32_t rc32k_vref_dly : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t rc32k_allow_cal : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t rc32k_ext_code_en : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t rc32k_cal_en : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad0 : 1; + uint32_t rc32k_code_fr_ext : 10; // @ 31 -- 22 # 0x3fffff + }; + } rc32k_ctrl0; // @ 0x200 + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t xtal32k_ext_sel : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t xtal32k_amp_ctrl : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t xtal32k_reg : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t xtal32k_outbuf_stre : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t xtal32k_otf_short : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t xtal32k_inv_stre : 2; // @ 10 -- 9 # 0xfffff9ff + uint32_t xtal32k_capbank : 6; // @ 16 -- 11 # 0xfffe07ff + uint32_t xtal32k_ac_cap_short : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pu_xtal32k_buf : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pu_xtal32k : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pad1 : 12; + }; + } xtal32k; // @ 0x204 + }; +} HBN_regs; +#define HBN_BASE 0x4000f000 +#define HBN ((volatile HBN_regs*)(HBN_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/cci.h b/src/include/soc/cci.h new file mode 100644 index 0000000..dfd5b4b --- /dev/null +++ b/src/include/soc/cci.h @@ -0,0 +1,52 @@ +#ifndef CCI_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cci_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cci_slv_sel_cci2 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cci_mas_sel_cci2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cci_mas_hw_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t reg_m_cci_sclk_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_div_m_cci_sclk : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t cfg_cci1_pre_read : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t reg_scci_clk_inv : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t reg_mcci_clk_inv : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad0 : 22; + }; + } cci_cfg; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t apb_cci_addr : 32; // @ 31 -- 0 # 0x0 + }; + } cci_addr; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t apb_cci_wdata : 32; // @ 31 -- 0 # 0x0 + }; + } cci_wdata; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t apb_cci_rdata : 32; // @ 31 -- 0 # 0x0 + }; + } cci_rdata; // @ 0xc + union { + uint32_t value; + struct { + uint32_t cci_write_flag : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cci_read_flag : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t ahb_state : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t pad0 : 28; + }; + } cci_ctl; // @ 0x10 + }; +} cci_regs; +#define CCI_BASE 0x40008000 +#define CCI ((volatile cci_regs*)(CCI_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/cks.h b/src/include/soc/cks.h new file mode 100644 index 0000000..1283d9e --- /dev/null +++ b/src/include/soc/cks.h @@ -0,0 +1,32 @@ +#ifndef CKS_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cr_cks_clr : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_cks_byte_swap : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } cks_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t data_in : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } data_in; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t cks_out : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } cks_out; // @ 0x8 + }; +} cks_regs; +#define CKS_BASE 0x4000a000 +#define CKS ((volatile cks_regs*)(CKS_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/dma.h b/src/include/soc/dma.h new file mode 100644 index 0000000..9463951 --- /dev/null +++ b/src/include/soc/dma.h @@ -0,0 +1,306 @@ +#ifndef DMA_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t IntStatus : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_IntStatus; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t IntTCStatus : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_IntTCStatus; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t IntTCClear : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_IntTCClear; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t IntErrorStatus : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_IntErrorStatus; // @ 0xc + union { + uint32_t value; + struct { + uint32_t IntErrClr : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_IntErrClr; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t RawIntTCStatus : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_RawIntTCStatus; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t RawIntErrorStatus : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_RawIntErrorStatus; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t EnabledChannels : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } DMA_EnbldChns; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t SoftBReq : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_SoftBReq; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t SoftSReq : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_SoftSReq; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t SoftLBReq : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_SoftLBReq; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t SoftLSReq : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_SoftLSReq; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t E : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t M : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } DMA_Top_Config; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t DMA_Sync : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_Sync; // @ 0x34 + uint8_t pad0[0xc8]; + union { + uint32_t value; + struct { + uint32_t SrcAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C0SrcAddr; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t DstAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C0DstAddr; // @ 0x104 + union { + uint32_t value; + struct { + uint32_t LLI : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C0LLI; // @ 0x108 + union { + uint32_t value; + struct { + uint32_t TransferSize : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t SBSize : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t DBSize : 3; // @ 17 -- 15 # 0xfffc7fff + uint32_t SWidth : 3; // @ 20 -- 18 # 0xffe3ffff + uint32_t DWidth : 3; // @ 23 -- 21 # 0xff1fffff + uint32_t SLargerD : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad0 : 1; + uint32_t SI : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t DI : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t Prot : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t I : 1; // @ 31 -- 31 # 0x7fffffff + }; + } DMA_C0Control; // @ 0x10c + union { + uint32_t value; + struct { + uint32_t E : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t SrcPeripheral : 5; // @ 5 -- 1 # 0xffffffc1 + uint32_t DstPeripheral : 5; // @ 10 -- 6 # 0xfffff83f + uint32_t FlowCntrl : 3; // @ 13 -- 11 # 0xffffc7ff + uint32_t IE : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ITC : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t L : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t A : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t H : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad0 : 1; + uint32_t LLICounter : 10; // @ 29 -- 20 # 0xc00fffff + uint32_t pad1 : 2; + }; + } DMA_C0Config; // @ 0x110 + uint8_t pad1[0xec]; + union { + uint32_t value; + struct { + uint32_t SrcAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C1SrcAddr; // @ 0x200 + union { + uint32_t value; + struct { + uint32_t DstAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C1DstAddr; // @ 0x204 + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t LLI : 30; // @ 31 -- 2 # 0x3 + }; + } DMA_C1LLI; // @ 0x208 + union { + uint32_t value; + struct { + uint32_t TransferSize : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t SBSize : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t DBSize : 3; // @ 17 -- 15 # 0xfffc7fff + uint32_t SWidth : 3; // @ 20 -- 18 # 0xffe3ffff + uint32_t DWidth : 3; // @ 23 -- 21 # 0xff1fffff + uint32_t pad0 : 2; + uint32_t SI : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t DI : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t Prot : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t I : 1; // @ 31 -- 31 # 0x7fffffff + }; + } DMA_C1Control; // @ 0x20c + union { + uint32_t value; + struct { + uint32_t E : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t SrcPeripheral : 5; // @ 5 -- 1 # 0xffffffc1 + uint32_t DstPeripheral : 5; // @ 10 -- 6 # 0xfffff83f + uint32_t FlowCntrl : 3; // @ 13 -- 11 # 0xffffc7ff + uint32_t IE : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ITC : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t L : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t A : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t H : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad0 : 13; + }; + } DMA_C1Config; // @ 0x210 + uint8_t pad2[0xec]; + union { + uint32_t value; + struct { + uint32_t SrcAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C2SrcAddr; // @ 0x300 + union { + uint32_t value; + struct { + uint32_t DstAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C2DstAddr; // @ 0x304 + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t LLI : 30; // @ 31 -- 2 # 0x3 + }; + } DMA_C2LLI; // @ 0x308 + union { + uint32_t value; + struct { + uint32_t TransferSize : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t SBSize : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t DBSize : 3; // @ 17 -- 15 # 0xfffc7fff + uint32_t SWidth : 3; // @ 20 -- 18 # 0xffe3ffff + uint32_t DWidth : 3; // @ 23 -- 21 # 0xff1fffff + uint32_t pad0 : 2; + uint32_t SI : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t DI : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t Prot : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t I : 1; // @ 31 -- 31 # 0x7fffffff + }; + } DMA_C2Control; // @ 0x30c + union { + uint32_t value; + struct { + uint32_t E : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t SrcPeripheral : 5; // @ 5 -- 1 # 0xffffffc1 + uint32_t DstPeripheral : 5; // @ 10 -- 6 # 0xfffff83f + uint32_t FlowCntrl : 3; // @ 13 -- 11 # 0xffffc7ff + uint32_t IE : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ITC : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t L : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t A : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t H : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad0 : 13; + }; + } DMA_C2Config; // @ 0x310 + uint8_t pad3[0xec]; + union { + uint32_t value; + struct { + uint32_t SrcAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C3SrcAddr; // @ 0x400 + union { + uint32_t value; + struct { + uint32_t DstAddr : 32; // @ 31 -- 0 # 0x0 + }; + } DMA_C3DstAddr; // @ 0x404 + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t LLI : 30; // @ 31 -- 2 # 0x3 + }; + } DMA_C3LLI; // @ 0x408 + union { + uint32_t value; + struct { + uint32_t TransferSize : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t SBSize : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t DBSize : 3; // @ 17 -- 15 # 0xfffc7fff + uint32_t SWidth : 3; // @ 20 -- 18 # 0xffe3ffff + uint32_t DWidth : 3; // @ 23 -- 21 # 0xff1fffff + uint32_t pad0 : 2; + uint32_t SI : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t DI : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t Prot : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t I : 1; // @ 31 -- 31 # 0x7fffffff + }; + } DMA_C3Control; // @ 0x40c + union { + uint32_t value; + struct { + uint32_t E : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t SrcPeripheral : 5; // @ 5 -- 1 # 0xffffffc1 + uint32_t DstPeripheral : 5; // @ 10 -- 6 # 0xfffff83f + uint32_t FlowCntrl : 3; // @ 13 -- 11 # 0xffffc7ff + uint32_t IE : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ITC : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t L : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t A : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t H : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad0 : 13; + }; + } DMA_C3Config; // @ 0x410 + }; +} dma_regs; +#define DMA_BASE 0x4000c000 +#define DMA ((volatile dma_regs*)(DMA_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/ef_ctrl.h b/src/include/soc/ef_ctrl.h new file mode 100644 index 0000000..c3649dc --- /dev/null +++ b/src/include/soc/ef_ctrl.h @@ -0,0 +1,192 @@ +#ifndef EF_CTRL_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint8_t pad0[0x800]; + union { + uint32_t value; + struct { + uint32_t ef_if_0_autoload_p1_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t ef_if_0_autoload_done : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t ef_if_0_busy : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t ef_if_0_rw : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t ef_if_0_trig : 1; // @ 4 -- 4 # 0xffffffef + uint32_t ef_if_0_manual_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t ef_if_0_cyc_modify : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t ef_clk_sahb_data_sel : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t ef_if_prot_code_ctrl : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t ef_if_por_dig : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ef_clk_sahb_data_gate : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t ef_if_auto_rd_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ef_if_cyc_modify_lock : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ef_if_0_int : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ef_if_0_int_clr : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ef_if_0_int_set : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad0 : 1; + uint32_t ef_if_prot_code_cyc : 8; // @ 31 -- 24 # 0xffffff + }; + } ef_if_ctrl_0; // @ 0x800 + union { + uint32_t value; + struct { + uint32_t ef_if_cyc_rd_dmy : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t ef_if_cyc_rd_dat : 6; // @ 11 -- 6 # 0xfffff03f + uint32_t ef_if_cyc_rd_adr : 6; // @ 17 -- 12 # 0xfffc0fff + uint32_t ef_if_cyc_cs : 6; // @ 23 -- 18 # 0xff03ffff + uint32_t ef_if_cyc_pd_cs_s : 8; // @ 31 -- 24 # 0xffffff + }; + } ef_if_cyc_0; // @ 0x804 + union { + uint32_t value; + struct { + uint32_t ef_if_cyc_pi : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t ef_if_cyc_pp : 8; // @ 13 -- 6 # 0xffffc03f + uint32_t ef_if_cyc_wr_adr : 6; // @ 19 -- 14 # 0xfff03fff + uint32_t ef_if_cyc_ps_cs : 6; // @ 25 -- 20 # 0xfc0fffff + uint32_t ef_if_cyc_pd_cs_h : 6; // @ 31 -- 26 # 0x3ffffff + }; + } ef_if_cyc_1; // @ 0x808 + union { + uint32_t value; + struct { + uint32_t ef_if_a : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t ef_if_pd : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t ef_if_ps : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t ef_if_strobe : 1; // @ 12 -- 12 # 0xffffefff + uint32_t ef_if_pgenb : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t ef_if_load : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ef_if_csb : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t ef_if_0_q : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t ef_if_prot_code_manual : 8; // @ 31 -- 24 # 0xffffff + }; + } ef_if_0_manual; // @ 0x80c + union { + uint32_t value; + struct { + uint32_t ef_if_0_status : 32; // @ 31 -- 0 # 0x0 + }; + } ef_if_0_status; // @ 0x810 + union { + uint32_t value; + struct { + uint32_t ef_if_sf_aes_mode : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t ef_if_sboot_sign_mode : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t ef_if_sboot_en : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t ef_if_cpu1_enc_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t ef_if_cpu0_enc_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t ef_if_boot_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t ef_if_sw_usage_1 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t ef_if_sdu_dis : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ef_if_ble_dis : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t ef_if_wifi_dis : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ef_if_0_key_enc_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t ef_if_cam_dis : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ef_if_sf_dis : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ef_if_cpu1_dis : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ef_if_cpu_rst_dbg_dis : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ef_if_se_dbg_dis : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t ef_if_efuse_dbg_dis : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t ef_if_dbg_jtag_1_dis : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t ef_if_dbg_jtag_0_dis : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t ef_if_dbg_mode : 4; // @ 31 -- 28 # 0xfffffff + }; + } ef_if_cfg_0; // @ 0x814 + union { + uint32_t value; + struct { + uint32_t ef_sw_sf_aes_mode : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t ef_sw_sboot_sign_mode : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t ef_sw_sboot_en : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t ef_sw_cpu1_enc_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t ef_sw_cpu0_enc_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 4; + uint32_t ef_sw_sw_usage_1 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t ef_sw_sdu_dis : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ef_sw_ble_dis : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t ef_sw_wifi_dis : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ef_sw_0_key_enc_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t ef_sw_cam_dis : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ef_sw_sf_dis : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ef_sw_cpu1_dis : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ef_sw_cpu_rst_dbg_dis : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ef_sw_se_dbg_dis : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t ef_sw_efuse_dbg_dis : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t ef_sw_dbg_jtag_1_dis : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t ef_sw_dbg_jtag_0_dis : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t ef_sw_dbg_mode : 4; // @ 31 -- 28 # 0xfffffff + }; + } ef_sw_cfg_0; // @ 0x818 + union { + uint32_t value; + struct { + uint32_t ef_reserved : 32; // @ 31 -- 0 # 0x0 + }; + } ef_reserved; // @ 0x81c + union { + uint32_t value; + struct { + uint32_t ef_if_ana_trim_0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_if_ana_trim_0; // @ 0x820 + union { + uint32_t value; + struct { + uint32_t ef_if_sw_usage_0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_if_sw_usage_0; // @ 0x824 + uint8_t pad1[0x1d8]; + union { + uint32_t value; + struct { + uint32_t ef_crc_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t ef_crc_trig : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t ef_crc_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t ef_crc_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t ef_crc_error : 1; // @ 4 -- 4 # 0xffffffef + uint32_t ef_crc_dout_inv_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t ef_crc_dout_endian : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t ef_crc_din_endian : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t ef_crc_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t ef_crc_int_clr : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t ef_crc_int_set : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t ef_crc_lock : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad0 : 4; + uint32_t ef_crc_slp_n : 16; // @ 31 -- 16 # 0xffff + }; + } ef_crc_ctrl_0; // @ 0xa00 + union { + uint32_t value; + struct { + uint32_t ef_crc_data_0_en : 32; // @ 31 -- 0 # 0x0 + }; + } ef_crc_ctrl_1; // @ 0xa04 + union { + uint32_t value; + struct { + uint32_t ef_crc_data_1_en : 32; // @ 31 -- 0 # 0x0 + }; + } ef_crc_ctrl_2; // @ 0xa08 + union { + uint32_t value; + struct { + uint32_t ef_crc_iv : 32; // @ 31 -- 0 # 0x0 + }; + } ef_crc_ctrl_3; // @ 0xa0c + union { + uint32_t value; + struct { + uint32_t ef_crc_golden : 32; // @ 31 -- 0 # 0x0 + }; + } ef_crc_ctrl_4; // @ 0xa10 + union { + uint32_t value; + struct { + uint32_t ef_crc_dout : 32; // @ 31 -- 0 # 0x0 + }; + } ef_crc_ctrl_5; // @ 0xa14 + }; +} ef_ctrl_regs; +#define EF_CTRL_BASE 0x40007000 +#define EF_CTRL ((volatile ef_ctrl_regs*)(EF_CTRL_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/ef_data_0.h b/src/include/soc/ef_data_0.h new file mode 100644 index 0000000..7925bc7 --- /dev/null +++ b/src/include/soc/ef_data_0.h @@ -0,0 +1,240 @@ +#ifndef EF_DATA_0_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t ef_sf_aes_mode : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t ef_sboot_sign_mode : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t ef_sboot_en : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t ef_cpu1_enc_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t ef_cpu0_enc_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t ef_boot_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t ef_sw_usage_1 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t ef_sdu_dis : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ef_ble_dis : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t ef_wifi_dis : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ef_0_key_enc_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t ef_cam_dis : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ef_sf_dis : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ef_cpu1_dis : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ef_cpu_rst_dbg_dis : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ef_se_dbg_dis : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t ef_efuse_dbg_dis : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t ef_dbg_jtag_1_dis : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t ef_dbg_jtag_0_dis : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t ef_dbg_mode : 4; // @ 31 -- 28 # 0xfffffff + }; + } ef_cfg_0; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t ef_dbg_pwd_low : 32; // @ 31 -- 0 # 0x0 + }; + } ef_dbg_pwd_low; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t ef_dbg_pwd_high : 32; // @ 31 -- 0 # 0x0 + }; + } ef_dbg_pwd_high; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t ef_ana_trim_0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_ana_trim_0; // @ 0xc + union { + uint32_t value; + struct { + uint32_t ef_sw_usage_0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_sw_usage_0; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t ef_wifi_mac_low : 32; // @ 31 -- 0 # 0x0 + }; + } ef_wifi_mac_low; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t ef_wifi_mac_high : 32; // @ 31 -- 0 # 0x0 + }; + } ef_wifi_mac_high; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_0_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_0_w0; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_0_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_0_w1; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_0_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_0_w2; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_0_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_0_w3; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_1_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_1_w0; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_1_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_1_w1; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_1_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_1_w2; // @ 0x34 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_1_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_1_w3; // @ 0x38 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_2_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_2_w0; // @ 0x3c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_2_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_2_w1; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_2_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_2_w2; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_2_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_2_w3; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_3_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_3_w0; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_3_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_3_w1; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_3_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_3_w2; // @ 0x54 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_3_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_3_w3; // @ 0x58 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_4_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_4_w0; // @ 0x5c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_4_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_4_w1; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_4_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_4_w2; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_4_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_4_w3; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_5_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_5_w0; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t ef_key_slot_5_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_5_w1; // @ 0x70 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_5_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_5_w2; // @ 0x74 + union { + uint32_t value; + struct { + uint32_t ef_key_slot_5_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } ef_key_slot_5_w3; // @ 0x78 + union { + uint32_t value; + struct { + uint32_t ef_ana_trim_1 : 13; // @ 12 -- 0 # 0xffffe000 + uint32_t wr_lock_key_slot_4_l : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t wr_lock_key_slot_5_l : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t wr_lock_boot_mode : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t wr_lock_dbg_pwd : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t wr_lock_sw_usage_0 : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t wr_lock_wifi_mac : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t wr_lock_key_slot_0 : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t wr_lock_key_slot_1 : 1; // @ 20 -- 20 # 0xffefffff + uint32_t wr_lock_key_slot_2 : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t wr_lock_key_slot_3 : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t wr_lock_key_slot_4_h : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t wr_lock_key_slot_5_h : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t rd_lock_dbg_pwd : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t rd_lock_key_slot_0 : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t rd_lock_key_slot_1 : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t rd_lock_key_slot_2 : 1; // @ 28 -- 28 # 0xefffffff + uint32_t rd_lock_key_slot_3 : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t rd_lock_key_slot_4 : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t rd_lock_key_slot_5 : 1; // @ 31 -- 31 # 0x7fffffff + }; + } ef_data_0_lock; // @ 0x7c + }; +} ef_data_0_regs; +#define EF_DATA_0_BASE 0x40007000 +#define EF_DATA_0 ((volatile ef_data_0_regs*)(EF_DATA_0_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/ef_data_1.h b/src/include/soc/ef_data_1.h new file mode 100644 index 0000000..b612006 --- /dev/null +++ b/src/include/soc/ef_data_1.h @@ -0,0 +1,132 @@ +#ifndef EF_DATA_1_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint8_t pad0[0x80]; + union { + uint32_t value; + struct { + uint32_t reg_key_slot_6_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_6_w0; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_6_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_6_w1; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_6_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_6_w2; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_6_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_6_w3; // @ 0x8c + union { + uint32_t value; + struct { + uint32_t reg_key_slot_7_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_7_w0; // @ 0x90 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_7_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_7_w1; // @ 0x94 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_7_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_7_w2; // @ 0x98 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_7_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_7_w3; // @ 0x9c + union { + uint32_t value; + struct { + uint32_t reg_key_slot_8_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_8_w0; // @ 0xa0 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_8_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_8_w1; // @ 0xa4 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_8_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_8_w2; // @ 0xa8 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_8_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_8_w3; // @ 0xac + union { + uint32_t value; + struct { + uint32_t reg_key_slot_9_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_9_w0; // @ 0xb0 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_9_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_9_w1; // @ 0xb4 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_9_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_9_w2; // @ 0xb8 + union { + uint32_t value; + struct { + uint32_t reg_key_slot_9_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } reg_key_slot_9_w3; // @ 0xbc + uint32_t reg_key_slot_10_w0; // @ 0xc0 + uint32_t reg_key_slot_10_w1; // @ 0xc4 + uint32_t reg_key_slot_10_w2; // @ 0xc8 + uint32_t reg_key_slot_10_w3; // @ 0xcc + uint32_t reg_key_slot_11_w0; // @ 0xd0 + uint32_t reg_key_slot_11_w1; // @ 0xd4 + uint32_t reg_key_slot_11_w2; // @ 0xd8 + uint32_t reg_key_slot_11_w3; // @ 0xdc + union { + uint32_t value; + struct { + uint32_t RESERVED_9_0 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t wr_lock_key_slot_6 : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t wr_lock_key_slot_7 : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t wr_lock_key_slot_8 : 1; // @ 12 -- 12 # 0xffffefff + uint32_t wr_lock_key_slot_9 : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad0 : 2; + uint32_t RESERVED_25_16 : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t rd_lock_key_slot_6 : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t rd_lock_key_slot_7 : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t rd_lock_key_slot_8 : 1; // @ 28 -- 28 # 0xefffffff + uint32_t rd_lock_key_slot_9 : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad1 : 2; + }; + } reg_data_1_lock; // @ 0xe0 + }; +} ef_data_1_regs; +#define EF_DATA_1_BASE 0x40007000 +#define EF_DATA_1 ((volatile ef_data_1_regs*)(EF_DATA_1_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/glb.h b/src/include/soc/glb.h new file mode 100644 index 0000000..7ab25ac --- /dev/null +++ b/src/include/soc/glb.h @@ -0,0 +1,970 @@ +#ifndef GLB_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t reg_pll_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_fclk_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_hclk_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t reg_bclk_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t reg_pll_sel : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t hbn_root_clk_sel : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t reg_hclk_div : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t reg_bclk_div : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t fclk_sw_state : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t chip_rdy : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t glb_id : 4; // @ 31 -- 28 # 0xfffffff + }; + } clk_cfg0; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t wifi_mac_core_div : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t wifi_mac_wt_div : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t pad0 : 8; + uint32_t ble_clk_sel : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad1 : 2; + uint32_t ble_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad2 : 7; + }; + } clk_cfg1; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t uart_clk_div : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t uart_clk_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 2; + uint32_t hbn_uart_clk_sel : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t sf_clk_div : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t sf_clk_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t sf_clk_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t sf_clk_sel2 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t ir_clk_div : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 1; + uint32_t ir_clk_en : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t dma_clk_en : 8; // @ 31 -- 24 # 0xffffff + }; + } clk_cfg2; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t spi_clk_div : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t spi_clk_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 7; + uint32_t i2c_clk_div : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t i2c_clk_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad2 : 7; + }; + } clk_cfg3; // @ 0xc + union { + uint32_t value; + struct { + uint32_t swrst_s00 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t swrst_s01 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 2; + uint32_t swrst_s20 : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t swrst_s30 : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 23; + }; + } swrst_cfg0; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t swrst_s10 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t swrst_s11 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t swrst_s12 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t swrst_s13 : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t swrst_s14 : 1; // @ 4 -- 4 # 0xffffffef + uint32_t swrst_s15 : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t swrst_s16 : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t swrst_s17 : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t swrst_s18 : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t swrst_s19 : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t swrst_s1a : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t swrst_s1b : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t swrst_s1c : 1; // @ 12 -- 12 # 0xffffefff + uint32_t swrst_s1d : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t swrst_s1e : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t swrst_s1f : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t swrst_s1a0 : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t swrst_s1a1 : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t swrst_s1a2 : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t swrst_s1a3 : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t swrst_s1a4 : 1; // @ 20 -- 20 # 0xffefffff + uint32_t swrst_s1a5 : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t swrst_s1a6 : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t swrst_s1a7 : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pad0 : 8; + }; + } swrst_cfg1; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t reg_ctrl_pwron_rst : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_ctrl_cpu_reset : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_ctrl_sys_reset : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t reg_ctrl_reset_dummy : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t pad1 : 16; + uint32_t pka_clk_sel : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad2 : 7; + }; + } swrst_cfg2; // @ 0x18 + uint32_t swrst_cfg3; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t cgen_m : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } cgen_cfg0; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t cgen_s1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t cgen_s1a : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t pad0 : 8; + }; + } cgen_cfg1; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t cgen_s2 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t cgen_s3 : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 27; + }; + } cgen_cfg2; // @ 0x28 + uint32_t cgen_cfg3; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t irom_mbist_mode : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t hsram_mbist_mode : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tag_mbist_mode : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t ocram_mbist_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t wifi_mbist_mode : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 26; + uint32_t reg_mbist_rst_n : 1; // @ 31 -- 31 # 0x7fffffff + }; + } MBIST_CTL; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t irom_mbist_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t hsram_mbist_done : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tag_mbist_done : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t ocram_mbist_done : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t wifi_mbist_done : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 11; + uint32_t irom_mbist_fail : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t hsram_mbist_fail : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t tag_mbist_fail : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ocram_mbist_fail : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t wifi_mbist_fail : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad1 : 11; + }; + } MBIST_STAT; // @ 0x34 + uint8_t pad0[0x18]; + union { + uint32_t value; + struct { + uint32_t bmx_timeout_en : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t bmx_arb_mode : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad0 : 2; + uint32_t bmx_err_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t bmx_busy_option_dis : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t bmx_gating_dis : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad1 : 1; + uint32_t hsel_option : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t pds_apb_cfg : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t hbn_apb_cfg : 8; // @ 31 -- 24 # 0xffffff + }; + } bmx_cfg1; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t bmx_err_addr_dis : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t bmx_err_dec : 1; // @ 4 -- 4 # 0xffffffef + uint32_t bmx_err_tz : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 22; + uint32_t bmx_dbg_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } bmx_cfg2; // @ 0x54 + union { + uint32_t value; + struct { + uint32_t bmx_err_addr : 32; // @ 31 -- 0 # 0x0 + }; + } bmx_err_addr; // @ 0x58 + union { + uint32_t value; + struct { + uint32_t bmx_dbg_out : 32; // @ 31 -- 0 # 0x0 + }; + } bmx_dbg_out; // @ 0x5c + union { + uint32_t value; + struct { + uint32_t rsvd_31_0 : 32; // @ 31 -- 0 # 0x0 + }; + } rsv0; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t rsvd_31_0 : 32; // @ 31 -- 0 # 0x0 + }; + } rsv1; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t rsvd_31_0 : 32; // @ 31 -- 0 # 0x0 + }; + } rsv2; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t rsvd_31_0 : 32; // @ 31 -- 0 # 0x0 + }; + } rsv3; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t reg_sram_ret : 32; // @ 31 -- 0 # 0x0 + }; + } sram_ret; // @ 0x70 + union { + uint32_t value; + struct { + uint32_t reg_sram_slp : 32; // @ 31 -- 0 # 0x0 + }; + } sram_slp; // @ 0x74 + union { + uint32_t value; + struct { + uint32_t reg_sram_parm : 32; // @ 31 -- 0 # 0x0 + }; + } sram_parm; // @ 0x78 + union { + uint32_t value; + struct { + uint32_t em_sel : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t pad0 : 28; + }; + } seam_misc; // @ 0x7c + union { + uint32_t value; + struct { + uint32_t reg_bd_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_ext_rst_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t jtag_swap_set : 6; // @ 7 -- 2 # 0xffffff03 + uint32_t swap_sflash_io_3_io_0 : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t sel_embedded_sflash : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad0 : 2; + uint32_t reg_spi_0_master_mode : 1; // @ 12 -- 12 # 0xffffefff + uint32_t reg_spi_0_swap : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad1 : 1; + uint32_t reg_cci_use_jtag_pin : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t reg_cci_use_sdio_pin : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t p1_adc_test_with_cci : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t p2_dac_test_with_cci : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t p3_cci_use_io_2_5 : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t p4_adc_test_with_jtag : 1; // @ 20 -- 20 # 0xffefffff + uint32_t p5_dac_test_with_jtag : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t p6_sdio_use_io_0_5 : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t p7_jtag_use_io_2_5 : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t uart_swap_set : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad2 : 5; + }; + } glb_parm; // @ 0x80 + uint8_t pad1[0xc]; + union { + uint32_t value; + struct { + uint32_t cpu_rtc_div : 17; // @ 16 -- 0 # 0xfffe0000 + uint32_t pad0 : 1; + uint32_t cpu_rtc_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t cpu_rtc_sel : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t debug_ndreset_gate : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad1 : 11; + }; + } CPU_CLK_CFG; // @ 0x90 + uint8_t pad2[0x10]; + union { + uint32_t value; + struct { + uint32_t gpadc_32m_clk_div : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 1; + uint32_t gpadc_32m_clk_sel : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t gpadc_32m_div_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 23; + }; + } GPADC_32M_SRC_CTRL; // @ 0xa4 + union { + uint32_t value; + struct { + uint32_t dig_32k_div : 11; // @ 10 -- 0 # 0xfffff800 + uint32_t pad0 : 1; + uint32_t dig_32k_en : 1; // @ 12 -- 12 # 0xffffefff + uint32_t dig_32k_comp : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad1 : 2; + uint32_t dig_512k_div : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 1; + uint32_t dig_512k_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t dig_512k_comp : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t pad3 : 2; + uint32_t dig_clk_src_sel : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad4 : 2; + uint32_t reg_en_platform_wakeup : 1; // @ 31 -- 31 # 0x7fffffff + }; + } DIG32K_WAKEUP_CTRL; // @ 0xa8 + union { + uint32_t value; + struct { + uint32_t coex_bt_channel : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t coex_bt_pti : 4; // @ 10 -- 7 # 0xfffff87f + uint32_t coex_bt_bw : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t en_gpio_bt_coex : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad0 : 19; + }; + } WIFI_BT_COEX_CTRL; // @ 0xac + uint8_t pad3[0x10]; + union { + uint32_t value; + struct { + uint32_t uart_sig_0_sel : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t uart_sig_1_sel : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t uart_sig_2_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t uart_sig_3_sel : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t uart_sig_4_sel : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t uart_sig_5_sel : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t uart_sig_6_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t uart_sig_7_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } UART_SIG_SEL_0; // @ 0xc0 + uint8_t pad4[0xc]; + union { + uint32_t value; + struct { + uint32_t reg_dbg_ll_ctrl : 32; // @ 31 -- 0 # 0x0 + }; + } DBG_SEL_LL; // @ 0xd0 + union { + uint32_t value; + struct { + uint32_t reg_dbg_lh_ctrl : 32; // @ 31 -- 0 # 0x0 + }; + } DBG_SEL_LH; // @ 0xd4 + union { + uint32_t value; + struct { + uint32_t reg_dbg_hl_ctrl : 32; // @ 31 -- 0 # 0x0 + }; + } DBG_SEL_HL; // @ 0xd8 + union { + uint32_t value; + struct { + uint32_t reg_dbg_hh_ctrl : 32; // @ 31 -- 0 # 0x0 + }; + } DBG_SEL_HH; // @ 0xdc + union { + uint32_t value; + struct { + uint32_t debug_oe : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t debug_i : 31; // @ 31 -- 1 # 0x1 + }; + } debug; // @ 0xe0 + uint8_t pad5[0x1c]; + union { + uint32_t value; + struct { + uint32_t reg_gpio_0_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_0_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_0_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_0_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_0_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_0_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t real_gpio_0_func_sel : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t reg_gpio_1_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_1_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_1_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_1_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_1_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad1 : 2; + uint32_t reg_gpio_1_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t real_gpio_1_func_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } GPIO_CFGCTL0; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t reg_gpio_2_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_2_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_2_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_2_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_2_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_2_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t real_gpio_2_func_sel : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t reg_gpio_3_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_3_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_3_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_3_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_3_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad1 : 2; + uint32_t reg_gpio_3_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t real_gpio_3_func_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } GPIO_CFGCTL1; // @ 0x104 + union { + uint32_t value; + struct { + uint32_t reg_gpio_4_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_4_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_4_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_4_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_4_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_4_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t real_gpio_4_func_sel : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t reg_gpio_5_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_5_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_5_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_5_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_5_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad1 : 2; + uint32_t reg_gpio_5_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t real_gpio_5_func_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } GPIO_CFGCTL2; // @ 0x108 + union { + uint32_t value; + struct { + uint32_t reg_gpio_6_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_6_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_6_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_6_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_6_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_6_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_7_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_7_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_7_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_7_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_7_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_7_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL3; // @ 0x10c + union { + uint32_t value; + struct { + uint32_t reg_gpio_8_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_8_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_8_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_8_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_8_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_8_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_9_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_9_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_9_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_9_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_9_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_9_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL4; // @ 0x110 + union { + uint32_t value; + struct { + uint32_t reg_gpio_10_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_10_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_10_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_10_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_10_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_10_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_11_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_11_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_11_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_11_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_11_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_11_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL5; // @ 0x114 + union { + uint32_t value; + struct { + uint32_t reg_gpio_12_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_12_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_12_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_12_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_12_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_12_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_13_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_13_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_13_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_13_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_13_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_13_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL6; // @ 0x118 + union { + uint32_t value; + struct { + uint32_t reg_gpio_14_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_14_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_14_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_14_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_14_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_14_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_15_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_15_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_15_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_15_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_15_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_15_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL7; // @ 0x11c + union { + uint32_t value; + struct { + uint32_t reg_gpio_16_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_16_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_16_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_16_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_16_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_16_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_17_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_17_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_17_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_17_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_17_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_17_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL8; // @ 0x120 + union { + uint32_t value; + struct { + uint32_t reg_gpio_18_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_18_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_18_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_18_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_18_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_18_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_19_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_19_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_19_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_19_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_19_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_19_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL9; // @ 0x124 + union { + uint32_t value; + struct { + uint32_t reg_gpio_20_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_20_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_20_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_20_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_20_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_20_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_21_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_21_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_21_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_21_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_21_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t reg_gpio_21_func_sel : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t pad3 : 4; + }; + } GPIO_CFGCTL10; // @ 0x128 + union { + uint32_t value; + struct { + uint32_t reg_gpio_22_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_22_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_22_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_22_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_22_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t reg_gpio_22_func_sel : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t reg_gpio_23_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_23_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_23_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_23_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_23_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 10; + }; + } GPIO_CFGCTL11; // @ 0x12c + union { + uint32_t value; + struct { + uint32_t reg_gpio_24_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_24_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_24_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_24_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_24_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 10; + uint32_t reg_gpio_25_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_25_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_25_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_25_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_25_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad1 : 10; + }; + } GPIO_CFGCTL12; // @ 0x130 + union { + uint32_t value; + struct { + uint32_t reg_gpio_26_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_26_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_26_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_26_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_26_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 10; + uint32_t reg_gpio_27_ie : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_27_smt : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_27_drv : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t reg_gpio_27_pu : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_27_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad1 : 10; + }; + } GPIO_CFGCTL13; // @ 0x134 + union { + uint32_t value; + struct { + uint32_t reg_gpio_28_ie : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_28_smt : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_28_drv : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t reg_gpio_28_pu : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_28_pd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 26; + }; + } GPIO_CFGCTL14; // @ 0x138 + uint8_t pad6[0x44]; + union { + uint32_t value; + struct { + uint32_t reg_gpio_0_i : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_1_i : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_2_i : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t reg_gpio_3_i : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t reg_gpio_4_i : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_5_i : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t reg_gpio_6_i : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t reg_gpio_7_i : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t reg_gpio_8_i : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t reg_gpio_9_i : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t reg_gpio_10_i : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t reg_gpio_11_i : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t reg_gpio_12_i : 1; // @ 12 -- 12 # 0xffffefff + uint32_t reg_gpio_13_i : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t reg_gpio_14_i : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t reg_gpio_15_i : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t reg_gpio_16_i : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_17_i : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_18_i : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t reg_gpio_19_i : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t reg_gpio_20_i : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_21_i : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t reg_gpio_22_i : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad0 : 9; + }; + } GPIO_CFGCTL30; // @ 0x180 + uint32_t GPIO_CFGCTL31; // @ 0x184 + union { + uint32_t value; + struct { + uint32_t reg_gpio_0_o : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_1_o : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_2_o : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t reg_gpio_3_o : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t reg_gpio_4_o : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_5_o : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t reg_gpio_6_o : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t reg_gpio_7_o : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t reg_gpio_8_o : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t reg_gpio_9_o : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t reg_gpio_10_o : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t reg_gpio_11_o : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t reg_gpio_12_o : 1; // @ 12 -- 12 # 0xffffefff + uint32_t reg_gpio_13_o : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t reg_gpio_14_o : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t reg_gpio_15_o : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t reg_gpio_16_o : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_17_o : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_18_o : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t reg_gpio_19_o : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t reg_gpio_20_o : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_21_o : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t reg_gpio_22_o : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad0 : 9; + }; + } GPIO_CFGCTL32; // @ 0x188 + uint32_t GPIO_CFGCTL33; // @ 0x18c + union { + uint32_t value; + struct { + uint32_t reg_gpio_0_oe : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t reg_gpio_1_oe : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t reg_gpio_2_oe : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t reg_gpio_3_oe : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t reg_gpio_4_oe : 1; // @ 4 -- 4 # 0xffffffef + uint32_t reg_gpio_5_oe : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t reg_gpio_6_oe : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t reg_gpio_7_oe : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t reg_gpio_8_oe : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t reg_gpio_9_oe : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t reg_gpio_10_oe : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t reg_gpio_11_oe : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t reg_gpio_12_oe : 1; // @ 12 -- 12 # 0xffffefff + uint32_t reg_gpio_13_oe : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t reg_gpio_14_oe : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t reg_gpio_15_oe : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t reg_gpio_16_oe : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t reg_gpio_17_oe : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t reg_gpio_18_oe : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t reg_gpio_19_oe : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t reg_gpio_20_oe : 1; // @ 20 -- 20 # 0xffefffff + uint32_t reg_gpio_21_oe : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t reg_gpio_22_oe : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad0 : 9; + }; + } GPIO_CFGCTL34; // @ 0x190 + uint32_t GPIO_CFGCTL35; // @ 0x194 + uint8_t pad7[0x8]; + union { + uint32_t value; + struct { + uint32_t reg_gpio_int_mask1 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_MASK1; // @ 0x1a0 + uint8_t pad8[0x4]; + union { + uint32_t value; + struct { + uint32_t gpio_int_stat1 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_STAT1; // @ 0x1a8 + uint8_t pad9[0x4]; + union { + uint32_t value; + struct { + uint32_t reg_gpio_int_clr1 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_CLR1; // @ 0x1b0 + uint8_t pad10[0xc]; + union { + uint32_t value; + struct { + uint32_t reg_gpio_int_mode_set1 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_MODE_SET1; // @ 0x1c0 + union { + uint32_t value; + struct { + uint32_t reg_gpio_int_mode_set2 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_MODE_SET2; // @ 0x1c4 + union { + uint32_t value; + struct { + uint32_t reg_gpio_int_mode_set3 : 32; // @ 31 -- 0 # 0x0 + }; + } GPIO_INT_MODE_SET3; // @ 0x1c8 + uint8_t pad11[0x58]; + union { + uint32_t value; + struct { + uint32_t led_din_reg : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t led_din_sel : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t led_din_polarity_sel : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t leddrv_ibias : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t ir_rx_gpio_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 21; + uint32_t pu_leddrv : 1; // @ 31 -- 31 # 0x7fffffff + }; + } led_driver; // @ 0x224 + uint8_t pad12[0xe0]; + union { + uint32_t value; + struct { + uint32_t gpdaca_rstn_ana : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpdacb_rstn_ana : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 5; + uint32_t gpdac_test_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t gpdac_ref_sel : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t gpdac_test_sel : 3; // @ 11 -- 9 # 0xfffff1ff + uint32_t pad1 : 12; + uint32_t gpdac_reserved : 8; // @ 31 -- 24 # 0xffffff + }; + } gpdac_ctrl; // @ 0x308 + union { + uint32_t value; + struct { + uint32_t gpdac_a_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpdac_ioa_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 16; + uint32_t gpdac_a_rng : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t gpdac_a_outmux : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 9; + }; + } gpdac_actrl; // @ 0x30c + union { + uint32_t value; + struct { + uint32_t gpdac_b_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpdac_iob_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 16; + uint32_t gpdac_b_rng : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t gpdac_b_outmux : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 9; + }; + } gpdac_bctrl; // @ 0x310 + union { + uint32_t value; + struct { + uint32_t gpdac_b_data : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t gpdac_a_data : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 6; + }; + } gpdac_data; // @ 0x314 + uint8_t pad13[0xbe8]; + union { + uint32_t value; + struct { + uint32_t tzc_glb_swrst_s00_lock : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tzc_glb_swrst_s01_lock : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 6; + uint32_t tzc_glb_swrst_s30_lock : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 3; + uint32_t tzc_glb_ctrl_pwron_rst_lock : 1; // @ 12 -- 12 # 0xffffefff + uint32_t tzc_glb_ctrl_cpu_reset_lock : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t tzc_glb_ctrl_sys_reset_lock : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t tzc_glb_ctrl_ungated_ap_lock : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t pad2 : 9; + uint32_t tzc_glb_misc_lock : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t tzc_glb_sram_lock : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t tzc_glb_l2c_lock : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t tzc_glb_bmx_lock : 1; // @ 28 -- 28 # 0xefffffff + uint32_t tzc_glb_dbg_lock : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t tzc_glb_mbist_lock : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t tzc_glb_clk_lock : 1; // @ 31 -- 31 # 0x7fffffff + }; + } tzc_glb_ctrl_0; // @ 0xf00 + union { + uint32_t value; + struct { + uint32_t tzc_glb_swrst_s20_lock : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tzc_glb_swrst_s21_lock : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tzc_glb_swrst_s22_lock : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t tzc_glb_swrst_s23_lock : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t tzc_glb_swrst_s24_lock : 1; // @ 4 -- 4 # 0xffffffef + uint32_t tzc_glb_swrst_s25_lock : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t tzc_glb_swrst_s26_lock : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t tzc_glb_swrst_s27_lock : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t tzc_glb_swrst_s28_lock : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t tzc_glb_swrst_s29_lock : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t tzc_glb_swrst_s2a_lock : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t tzc_glb_swrst_s2b_lock : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t tzc_glb_swrst_s2c_lock : 1; // @ 12 -- 12 # 0xffffefff + uint32_t tzc_glb_swrst_s2d_lock : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t tzc_glb_swrst_s2e_lock : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t tzc_glb_swrst_s2f_lock : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t tzc_glb_swrst_s10_lock : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t tzc_glb_swrst_s11_lock : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t tzc_glb_swrst_s12_lock : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t tzc_glb_swrst_s13_lock : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t tzc_glb_swrst_s14_lock : 1; // @ 20 -- 20 # 0xffefffff + uint32_t tzc_glb_swrst_s15_lock : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t tzc_glb_swrst_s16_lock : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t tzc_glb_swrst_s17_lock : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t tzc_glb_swrst_s18_lock : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t tzc_glb_swrst_s19_lock : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t tzc_glb_swrst_s1a_lock : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t tzc_glb_swrst_s1b_lock : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t tzc_glb_swrst_s1c_lock : 1; // @ 28 -- 28 # 0xefffffff + uint32_t tzc_glb_swrst_s1d_lock : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t tzc_glb_swrst_s1e_lock : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t tzc_glb_swrst_s1f_lock : 1; // @ 31 -- 31 # 0x7fffffff + }; + } tzc_glb_ctrl_1; // @ 0xf04 + union { + uint32_t value; + struct { + uint32_t tzc_glb_gpio_0_lock : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tzc_glb_gpio_1_lock : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tzc_glb_gpio_2_lock : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t tzc_glb_gpio_3_lock : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t tzc_glb_gpio_4_lock : 1; // @ 4 -- 4 # 0xffffffef + uint32_t tzc_glb_gpio_5_lock : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t tzc_glb_gpio_6_lock : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t tzc_glb_gpio_7_lock : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t tzc_glb_gpio_8_lock : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t tzc_glb_gpio_9_lock : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t tzc_glb_gpio_10_lock : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t tzc_glb_gpio_11_lock : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t tzc_glb_gpio_12_lock : 1; // @ 12 -- 12 # 0xffffefff + uint32_t tzc_glb_gpio_13_lock : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t tzc_glb_gpio_14_lock : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t tzc_glb_gpio_15_lock : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t tzc_glb_gpio_16_lock : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t tzc_glb_gpio_17_lock : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t tzc_glb_gpio_18_lock : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t tzc_glb_gpio_19_lock : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t tzc_glb_gpio_20_lock : 1; // @ 20 -- 20 # 0xffefffff + uint32_t tzc_glb_gpio_21_lock : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t tzc_glb_gpio_22_lock : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t tzc_glb_gpio_23_lock : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t tzc_glb_gpio_24_lock : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t tzc_glb_gpio_25_lock : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t tzc_glb_gpio_26_lock : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t tzc_glb_gpio_27_lock : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t tzc_glb_gpio_28_lock : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad0 : 3; + }; + } tzc_glb_ctrl_2; // @ 0xf08 + uint32_t tzc_glb_ctrl_3; // @ 0xf0c + }; +} glb_regs; +#define GLB_BASE 0x40000000 +#define GLB ((volatile glb_regs*)(GLB_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/gpip.h b/src/include/soc/gpip.h new file mode 100644 index 0000000..b739503 --- /dev/null +++ b/src/include/soc/gpip.h @@ -0,0 +1,84 @@ +#ifndef GPIP_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t gpadc_dma_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpadc_fifo_clr : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t gpadc_fifo_ne : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t gpadc_fifo_full : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t gpadc_rdy : 1; // @ 4 -- 4 # 0xffffffef + uint32_t gpadc_fifo_overrun : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t gpadc_fifo_underrun : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 1; + uint32_t gpadc_rdy_clr : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t gpadc_fifo_overrun_clr : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t gpadc_fifo_underrun_clr : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad1 : 1; + uint32_t gpadc_rdy_mask : 1; // @ 12 -- 12 # 0xffffefff + uint32_t gpadc_fifo_overrun_mask : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t gpadc_fifo_underrun_mask : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pad2 : 1; + uint32_t gpadc_fifo_data_count : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t gpadc_fifo_thl : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t rsvd_31_24 : 8; // @ 31 -- 24 # 0xffffff + }; + } gpadc_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t gpadc_dma_rdata : 26; // @ 25 -- 0 # 0xfc000000 + uint32_t rsvd_31_26 : 6; // @ 31 -- 26 # 0x3ffffff + }; + } gpadc_dma_rdata; // @ 0x4 + uint8_t pad0[0x38]; + union { + uint32_t value; + struct { + uint32_t gpdac_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t gpdac_en2 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 2; + uint32_t dsm_mode : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t gpdac_mode : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad2 : 5; + uint32_t gpdac_ch_a_sel : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t gpdac_ch_b_sel : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t rsvd_31_24 : 8; // @ 31 -- 24 # 0xffffff + }; + } gpdac_config; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t gpdac_dma_tx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t gpdac_dma_format : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 26; + }; + } gpdac_dma_config; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t gpdac_dma_wdata : 32; // @ 31 -- 0 # 0x0 + }; + } gpdac_dma_wdata; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t tx_fifo_empty : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tx_fifo_full : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tx_cs : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t TxFifoRdPtr : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad0 : 1; + uint32_t TxFifoWrPtr : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 22; + }; + } gpdac_tx_fifo_status; // @ 0x4c + }; +} gpip_regs; +#define GPIP_BASE 0x40002000 +#define GPIP ((volatile gpip_regs*)(GPIP_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/i2c.h b/src/include/soc/i2c.h new file mode 100644 index 0000000..17ebd02 --- /dev/null +++ b/src/include/soc/i2c.h @@ -0,0 +1,144 @@ +#ifndef I2C_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cr_i2c_m_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_i2c_pkt_dir : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_i2c_deg_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_i2c_scl_sync_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_i2c_sub_addr_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_i2c_sub_addr_bc : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t pad0 : 1; + uint32_t cr_i2c_slv_addr : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t cr_i2c_pkt_len : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t pad2 : 4; + uint32_t cr_i2c_deg_cnt : 4; // @ 31 -- 28 # 0xfffffff + }; + } i2c_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t i2c_end_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t i2c_txf_int : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t i2c_rxf_int : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t i2c_nak_int : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t i2c_arb_int : 1; // @ 4 -- 4 # 0xffffffef + uint32_t i2c_fer_int : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t cr_i2c_end_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_i2c_txf_mask : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t cr_i2c_rxf_mask : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t cr_i2c_nak_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_i2c_arb_mask : 1; // @ 12 -- 12 # 0xffffefff + uint32_t cr_i2c_fer_mask : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad1 : 2; + uint32_t cr_i2c_end_clr : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t rsvd_17 : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t rsvd_18 : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t cr_i2c_nak_clr : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t cr_i2c_arb_clr : 1; // @ 20 -- 20 # 0xffefffff + uint32_t rsvd_21 : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t cr_i2c_end_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t cr_i2c_txf_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t cr_i2c_rxf_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t cr_i2c_nak_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t cr_i2c_arb_en : 1; // @ 28 -- 28 # 0xefffffff + uint32_t cr_i2c_fer_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad3 : 2; + }; + } i2c_int_sts; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t cr_i2c_sub_addr_b0 : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t cr_i2c_sub_addr_b1 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t cr_i2c_sub_addr_b2 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_i2c_sub_addr_b3 : 8; // @ 31 -- 24 # 0xffffff + }; + } i2c_sub_addr; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t sts_i2c_bus_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_i2c_bus_busy_clr : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } i2c_bus_busy; // @ 0xc + union { + uint32_t value; + struct { + uint32_t cr_i2c_prd_s_ph_0 : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t cr_i2c_prd_s_ph_1 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t cr_i2c_prd_s_ph_2 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_i2c_prd_s_ph_3 : 8; // @ 31 -- 24 # 0xffffff + }; + } i2c_prd_start; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t cr_i2c_prd_p_ph_0 : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t cr_i2c_prd_p_ph_1 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t cr_i2c_prd_p_ph_2 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_i2c_prd_p_ph_3 : 8; // @ 31 -- 24 # 0xffffff + }; + } i2c_prd_stop; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t cr_i2c_prd_d_ph_0 : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t cr_i2c_prd_d_ph_1 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t cr_i2c_prd_d_ph_2 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_i2c_prd_d_ph_3 : 8; // @ 31 -- 24 # 0xffffff + }; + } i2c_prd_data; // @ 0x18 + uint8_t pad0[0x64]; + union { + uint32_t value; + struct { + uint32_t i2c_dma_tx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t i2c_dma_rx_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tx_fifo_clr : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rx_fifo_clr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t tx_fifo_overflow : 1; // @ 4 -- 4 # 0xffffffef + uint32_t tx_fifo_underflow : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rx_fifo_overflow : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t rx_fifo_underflow : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } i2c_fifo_config_0; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t tx_fifo_cnt : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t rx_fifo_cnt : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t tx_fifo_th : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 7; + uint32_t rx_fifo_th : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad3 : 7; + }; + } i2c_fifo_config_1; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t i2c_fifo_wdata : 32; // @ 31 -- 0 # 0x0 + }; + } i2c_fifo_wdata; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t i2c_fifo_rdata : 32; // @ 31 -- 0 # 0x0 + }; + } i2c_fifo_rdata; // @ 0x8c + }; +} i2c_regs; +#define I2C_BASE 0x4000a300 +#define I2C ((volatile i2c_regs*)(I2C_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/ir.h b/src/include/soc/ir.h new file mode 100644 index 0000000..5330d7b --- /dev/null +++ b/src/include/soc/ir.h @@ -0,0 +1,197 @@ +#ifndef IR_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cr_irtx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_irtx_out_inv : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_irtx_mod_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_irtx_swm_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_irtx_data_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_irtx_logic0_hl_inv : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_irtx_logic1_hl_inv : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 1; + uint32_t cr_irtx_head_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_irtx_head_hl_inv : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t cr_irtx_tail_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t cr_irtx_tail_hl_inv : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_irtx_data_num : 6; // @ 17 -- 12 # 0xfffc0fff + uint32_t pad1 : 14; + }; + } irtx_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t irtx_end_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 7; + uint32_t cr_irtx_end_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 7; + uint32_t cr_irtx_end_clr : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 7; + uint32_t cr_irtx_end_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad3 : 7; + }; + } irtx_int_sts; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t cr_irtx_data_word0 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_data_word0; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t cr_irtx_data_word1 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_data_word1; // @ 0xc + union { + uint32_t value; + struct { + uint32_t cr_irtx_pw_unit : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 4; + uint32_t cr_irtx_mod_ph0_w : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_irtx_mod_ph1_w : 8; // @ 31 -- 24 # 0xffffff + }; + } irtx_pulse_width; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t cr_irtx_logic0_ph0_w : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t cr_irtx_logic0_ph1_w : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t cr_irtx_logic1_ph0_w : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t cr_irtx_logic1_ph1_w : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t cr_irtx_head_ph0_w : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t cr_irtx_head_ph1_w : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t cr_irtx_tail_ph0_w : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t cr_irtx_tail_ph1_w : 4; // @ 31 -- 28 # 0xfffffff + }; + } irtx_pw; // @ 0x14 + uint8_t pad0[0x28]; + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_0 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_0; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_1 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_1; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_2 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_2; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_3 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_3; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_4 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_4; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_5 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_5; // @ 0x54 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_6 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_6; // @ 0x58 + union { + uint32_t value; + struct { + uint32_t cr_irtx_swm_pw_7 : 32; // @ 31 -- 0 # 0x0 + }; + } irtx_swm_pw_7; // @ 0x5c + uint8_t pad1[0x20]; + union { + uint32_t value; + struct { + uint32_t cr_irrx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_irrx_in_inv : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_irrx_mode : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t cr_irrx_deg_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 3; + uint32_t cr_irrx_deg_cnt : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 20; + }; + } irrx_config; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t irrx_end_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 7; + uint32_t cr_irrx_end_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 7; + uint32_t cr_irrx_end_clr : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 7; + uint32_t cr_irrx_end_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad3 : 7; + }; + } irrx_int_sts; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t cr_irrx_data_th : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t cr_irrx_end_th : 16; // @ 31 -- 16 # 0xffff + }; + } irrx_pw_config; // @ 0x88 + uint8_t pad2[0x4]; + union { + uint32_t value; + struct { + uint32_t sts_irrx_data_cnt : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 25; + }; + } irrx_data_count; // @ 0x90 + union { + uint32_t value; + struct { + uint32_t sts_irrx_data_word0 : 32; // @ 31 -- 0 # 0x0 + }; + } irrx_data_word0; // @ 0x94 + union { + uint32_t value; + struct { + uint32_t sts_irrx_data_word1 : 32; // @ 31 -- 0 # 0x0 + }; + } irrx_data_word1; // @ 0x98 + uint8_t pad3[0x24]; + union { + uint32_t value; + struct { + uint32_t rx_fifo_clr : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 1; + uint32_t rx_fifo_overflow : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rx_fifo_underflow : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t rx_fifo_cnt : 7; // @ 10 -- 4 # 0xfffff80f + uint32_t pad1 : 21; + }; + } irrx_swm_fifo_config_0; // @ 0xc0 + union { + uint32_t value; + struct { + uint32_t rx_fifo_rdata : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } irrx_swm_fifo_rdata; // @ 0xc4 + }; +} ir_regs; +#define IR_BASE 0x4000a600 +#define IR ((volatile ir_regs*)(IR_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/l1c.h b/src/include/soc/l1c.h new file mode 100644 index 0000000..1241ea7 --- /dev/null +++ b/src/include/soc/l1c.h @@ -0,0 +1,86 @@ +#ifndef L1C_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t l1c_cacheable : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t l1c_cnt_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t l1c_invalid_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t l1c_invalid_done : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 4; + uint32_t l1c_way_dis : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t irom_2t_access : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad1 : 1; + uint32_t l1c_bypass : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t l1c_bmx_err_en : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t l1c_bmx_arb_mode : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 2; + uint32_t l1c_bmx_timeout_en : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t l1c_bmx_busy_option_dis : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t early_resp_dis : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t wrap_dis : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad3 : 5; + }; + } l1c_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t hit_cnt_lsb : 32; // @ 31 -- 0 # 0x0 + }; + } hit_cnt_lsb; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t hit_cnt_msb : 32; // @ 31 -- 0 # 0x0 + }; + } hit_cnt_msb; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t miss_cnt : 32; // @ 31 -- 0 # 0x0 + }; + } miss_cnt; // @ 0xc + uint32_t l1c_range; // @ 0x10 + uint8_t pad0[0x1ec]; + union { + uint32_t value; + struct { + uint32_t l1c_bmx_err_addr_dis : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t l1c_bmx_err_dec : 1; // @ 4 -- 4 # 0xffffffef + uint32_t l1c_bmx_err_tz : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 10; + uint32_t l1c_hsel_option : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t pad2 : 12; + }; + } l1c_bmx_err_addr_en; // @ 0x200 + union { + uint32_t value; + struct { + uint32_t l1c_bmx_err_addr : 32; // @ 31 -- 0 # 0x0 + }; + } l1c_bmx_err_addr; // @ 0x204 + union { + uint32_t value; + struct { + uint32_t irom1_misr_dataout_0 : 32; // @ 31 -- 0 # 0x0 + }; + } irom1_misr_dataout_0; // @ 0x208 + uint32_t irom1_misr_dataout_1; // @ 0x20c + union { + uint32_t value; + struct { + uint32_t force_e21_clock_on_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t force_e21_clock_on_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t force_e21_clock_on_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } cpu_clk_gate; // @ 0x210 + }; +} l1c_regs; +#define L1C_BASE 0x40009000 +#define L1C ((volatile l1c_regs*)(L1C_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/pds.h b/src/include/soc/pds.h new file mode 100644 index 0000000..7b97e92 --- /dev/null +++ b/src/include/soc/pds.h @@ -0,0 +1,286 @@ +#ifndef PDS_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t pds_start_ps : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_sleep_forever : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_xtal_force_off : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_wifi_pds_save_state : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_pds_pd_dcdc18 : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_pds_pd_bg_sys : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t cr_pds_gate_clk : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_pds_mem_stby : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad1 : 1; + uint32_t cr_pds_iso_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_pds_wait_xtal_rdy : 1; // @ 12 -- 12 # 0xffffefff + uint32_t cr_pds_pwr_off : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t cr_pds_pd_xtal : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t cr_pds_soc_enb_force_on : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t cr_pds_rst_soc_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t cr_pds_rc32m_off_dis : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t cr_pds_ldo_vsel_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad2 : 2; + uint32_t cr_np_wfi_mask : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t cr_pds_pd_ldo11 : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad3 : 1; + uint32_t cr_pds_ldo_vol : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t cr_pds_ctrl_rf : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t cr_pds_ctrl_pll : 2; // @ 31 -- 30 # 0x3fffffff + }; + } PDS_CTL; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t cr_sleep_duration : 32; // @ 31 -- 0 # 0x0 + }; + } PDS_TIME1; // @ 0x4 + uint8_t pad0[0x4]; + union { + uint32_t value; + struct { + uint32_t ro_pds_wake_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t ro_pds_irq_in : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t ro_pds_rf_done_int : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t ro_pds_pll_done_int : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 4; + uint32_t cr_pds_wake_int_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_pds_irq_in_dis : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t cr_pds_rf_done_int_mask : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t cr_pds_pll_done_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad1 : 4; + uint32_t cr_pds_int_clr : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 15; + }; + } PDS_INT; // @ 0xc + union { + uint32_t value; + struct { + uint32_t cr_pds_force_np_pwr_off : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 1; + uint32_t cr_pds_force_wb_pwr_off : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad1 : 1; + uint32_t cr_pds_force_np_iso_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad2 : 1; + uint32_t cr_pds_force_wb_iso_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad3 : 1; + uint32_t cr_pds_force_np_pds_rst : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad4 : 1; + uint32_t cr_pds_force_wb_pds_rst : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad5 : 1; + uint32_t cr_pds_force_np_mem_stby : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad6 : 1; + uint32_t cr_pds_force_wb_mem_stby : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pad7 : 1; + uint32_t cr_pds_force_np_gate_clk : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad8 : 1; + uint32_t cr_pds_force_wb_gate_clk : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad9 : 13; + }; + } PDS_CTL2; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t pad0 : 1; + uint32_t cr_pds_force_misc_pwr_off : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad1 : 2; + uint32_t cr_pds_force_misc_iso_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad2 : 2; + uint32_t cr_pds_force_misc_pds_rst : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad3 : 2; + uint32_t cr_pds_force_misc_mem_stby : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad4 : 2; + uint32_t cr_pds_force_misc_gate_clk : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad5 : 10; + uint32_t cr_pds_np_iso_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad6 : 2; + uint32_t cr_pds_wb_iso_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t pad7 : 2; + uint32_t cr_pds_misc_iso_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t pad8 : 1; + }; + } PDS_CTL3; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t cr_pds_np_pwr_off : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_pds_np_reset : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_pds_np_mem_stby : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_pds_np_gate_clk : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 8; + uint32_t cr_pds_wb_pwr_off : 1; // @ 12 -- 12 # 0xffffefff + uint32_t cr_pds_wb_reset : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t cr_pds_wb_mem_stby : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t cr_pds_wb_gate_clk : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t pad1 : 8; + uint32_t cr_pds_misc_pwr_off : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t cr_pds_misc_reset : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t cr_pds_misc_mem_stby : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t cr_pds_misc_gate_clk : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t pad2 : 4; + }; + } PDS_CTL4; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t ro_pds_state : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t pad0 : 4; + uint32_t ro_pds_rf_state : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pad1 : 4; + uint32_t ro_pds_pll_state : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } pds_stat; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t cr_np_sram_pwr : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } pds_ram1; // @ 0x20 + uint8_t pad1[0x2dc]; + union { + uint32_t value; + struct { + uint32_t rc32m_cal_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rc32m_rdy : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rc32m_cal_inprogress : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rc32m_cal_div : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t rc32m_cal_precharge : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rc32m_dig_code_fr_cal : 8; // @ 13 -- 6 # 0xffffc03f + uint32_t pad0 : 3; + uint32_t rc32m_allow_cal : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t rc32m_refclk_half : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t rc32m_ext_code_en : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t rc32m_cal_en : 1; // @ 20 -- 20 # 0xffefffff + uint32_t rc32m_pd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t rc32m_code_fr_ext : 8; // @ 29 -- 22 # 0xc03fffff + uint32_t pad1 : 2; + }; + } rc32m_ctrl0; // @ 0x300 + union { + uint32_t value; + struct { + uint32_t rc32m_test_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rc32m_soft_rst : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rc32m_clk_soft_rst : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rc32m_clk_inv : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t rc32m_clk_force_on : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 19; + uint32_t rc32m_reserved : 8; // @ 31 -- 24 # 0xffffff + }; + } rc32m_ctrl1; // @ 0x304 + uint8_t pad2[0xf8]; + union { + uint32_t value; + struct { + uint32_t clkpll_sdm_reset : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t clkpll_reset_postdiv : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t clkpll_reset_fbdv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t clkpll_reset_refdiv : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t clkpll_pu_postdiv : 1; // @ 4 -- 4 # 0xffffffef + uint32_t clkpll_pu_fbdv : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t clkpll_pu_clamp_op : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t clkpll_pu_pfd : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t clkpll_pu_cp : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pu_clkpll_sfreg : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pu_clkpll : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad0 : 21; + }; + } pu_rst_clkpll; // @ 0x400 + union { + uint32_t value; + struct { + uint32_t clkpll_postdiv : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t clkpll_refdiv_ratio : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t clkpll_xtal_rc32m_sel : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad1 : 3; + uint32_t clkpll_refclk_sel : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 3; + uint32_t clkpll_vg11_sel : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t pad3 : 2; + uint32_t clkpll_vg13_sel : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad4 : 6; + }; + } clkpll_top_ctrl; // @ 0x404 + union { + uint32_t value; + struct { + uint32_t clkpll_sel_cp_bias : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t clkpll_icp_5u : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t clkpll_icp_1u : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t clkpll_int_frac_sw : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t clkpll_cp_startup_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t clkpll_cp_opamp_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad1 : 21; + }; + } clkpll_cp; // @ 0x408 + union { + uint32_t value; + struct { + uint32_t clkpll_c4_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t clkpll_r4 : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t clkpll_r4_short : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 3; + uint32_t clkpll_c3 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t clkpll_cz : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t clkpll_rz : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad3 : 13; + }; + } clkpll_rz; // @ 0x40c + union { + uint32_t value; + struct { + uint32_t clkpll_sel_sample_clk : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t clkpll_sel_fb_clk : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t pad0 : 28; + }; + } clkpll_fbdv; // @ 0x410 + union { + uint32_t value; + struct { + uint32_t clkpll_vco_speed : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t clkpll_shrtr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 28; + }; + } clkpll_vco; // @ 0x414 + union { + uint32_t value; + struct { + uint32_t clkpll_sdmin : 24; // @ 23 -- 0 # 0xff000000 + uint32_t clkpll_dither_sel : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad0 : 2; + uint32_t clkpll_sdm_flag : 1; // @ 28 -- 28 # 0xefffffff + uint32_t clkpll_sdm_bypass : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad1 : 2; + }; + } clkpll_sdm; // @ 0x418 + union { + uint32_t value; + struct { + uint32_t clkpll_en_480m : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t clkpll_en_240m : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t clkpll_en_192m : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t clkpll_en_160m : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t clkpll_en_120m : 1; // @ 4 -- 4 # 0xffffffef + uint32_t clkpll_en_96m : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t clkpll_en_80m : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t clkpll_en_48m : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t clkpll_en_32m : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t clkpll_en_div2_480m : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad0 : 22; + }; + } clkpll_output_en; // @ 0x41c + }; +} pds_regs; +#define PDS_BASE 0x4000e000 +#define PDS ((volatile pds_regs*)(PDS_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/pwm.h b/src/include/soc/pwm.h new file mode 100644 index 0000000..43a0a25 --- /dev/null +++ b/src/include/soc/pwm.h @@ -0,0 +1,269 @@ +#ifndef PWM_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t pwm_interrupt_sts : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t pwm_int_clear : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 18; + }; + } pwm_int_config; // @ 0x0 + uint8_t pad0[0x1c]; + union { + uint32_t value; + struct { + uint32_t pwm_clk_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm0_clkdiv; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t pwm_thre1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm0_thre1; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t pwm_thre2 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm0_thre2; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t pwm_period : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm0_period; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t reg_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pwm_out_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pwm_stop_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pwm_sw_force_val : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pwm_sw_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pwm_stop_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pwm_sts_top : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } pwm0_config; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t pwm_int_period_cnt : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pwm_int_enable : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } pwm0_interrupt; // @ 0x34 + uint8_t pad1[0x8]; + union { + uint32_t value; + struct { + uint32_t pwm_clk_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm1_clkdiv; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t pwm_thre1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm1_thre1; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t pwm_thre2 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm1_thre2; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t pwm_period : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm1_period; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t reg_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pwm_out_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pwm_stop_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pwm_sw_force_val : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pwm_sw_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pwm_stop_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pwm_sts_top : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } pwm1_config; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t pwm_int_period_cnt : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pwm_int_enable : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } pwm1_interrupt; // @ 0x54 + uint8_t pad2[0x8]; + union { + uint32_t value; + struct { + uint32_t pwm_clk_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm2_clkdiv; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t pwm_thre1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm2_thre1; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t pwm_thre2 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm2_thre2; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t pwm_period : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm2_period; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t reg_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pwm_out_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pwm_stop_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pwm_sw_force_val : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pwm_sw_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pwm_stop_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pwm_sts_top : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } pwm2_config; // @ 0x70 + union { + uint32_t value; + struct { + uint32_t pwm_int_period_cnt : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pwm_int_enable : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } pwm2_interrupt; // @ 0x74 + uint8_t pad3[0x8]; + union { + uint32_t value; + struct { + uint32_t pwm_clk_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm3_clkdiv; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t pwm_thre1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm3_thre1; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t pwm_thre2 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm3_thre2; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t pwm_period : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm3_period; // @ 0x8c + union { + uint32_t value; + struct { + uint32_t reg_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pwm_out_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pwm_stop_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pwm_sw_force_val : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pwm_sw_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pwm_stop_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pwm_sts_top : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } pwm3_config; // @ 0x90 + union { + uint32_t value; + struct { + uint32_t pwm_int_period_cnt : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pwm_int_enable : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } pwm3_interrupt; // @ 0x94 + uint8_t pad4[0x8]; + union { + uint32_t value; + struct { + uint32_t pwm_clk_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm4_clkdiv; // @ 0xa0 + union { + uint32_t value; + struct { + uint32_t pwm_thre1 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm4_thre1; // @ 0xa4 + union { + uint32_t value; + struct { + uint32_t pwm_thre2 : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm4_thre2; // @ 0xa8 + union { + uint32_t value; + struct { + uint32_t pwm_period : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } pwm4_period; // @ 0xac + union { + uint32_t value; + struct { + uint32_t reg_clk_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pwm_out_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pwm_stop_mode : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pwm_sw_force_val : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pwm_sw_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pwm_stop_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pwm_sts_top : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } pwm4_config; // @ 0xb0 + union { + uint32_t value; + struct { + uint32_t pwm_int_period_cnt : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pwm_int_enable : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } pwm4_interrupt; // @ 0xb4 + }; +} pwm_regs; +#define PWM_BASE 0x4000a400 +#define PWM ((volatile pwm_regs*)(PWM_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/rf.h b/src/include/soc/rf.h new file mode 100644 index 0000000..554b583 --- /dev/null +++ b/src/include/soc/rf.h @@ -0,0 +1,1936 @@ +#ifndef RF_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t rf_id : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t fw_rev : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t hw_rev : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t pad0 : 8; + }; + } rf_rev; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t pad0 : 1; + uint32_t rf_fsm_ctrl_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rf_fsm_t2r_cal_mode : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t rf_fsm_state : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t rf_rc_state_dbg : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t rf_rc_state_dbg_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t rf_fsm_st_int_sel : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad2 : 1; + uint32_t rf_fsm_st_int : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad3 : 3; + uint32_t rf_fsm_st_int_clr : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad4 : 3; + uint32_t rf_fsm_st_int_set : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad5 : 3; + uint32_t rf_rc_state_value : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad6 : 1; + }; + } rf_fsm_ctrl_hw; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t rf_fsm_sw_st : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t rf_fsm_sw_st_vld : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 3; + uint32_t full_cal_en : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad2 : 3; + uint32_t inc_cal_timeout : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad3 : 3; + uint32_t lo_unlocked : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad4 : 11; + }; + } rf_fsm_ctrl_sw; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t pu_ctrl_hw : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rx_gain_ctrl_hw : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tx_gain_ctrl_hw : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t lna_ctrl_hw : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t rbb_bw_ctrl_hw : 1; // @ 4 -- 4 # 0xffffffef + uint32_t trxcal_ctrl_hw : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t lo_ctrl_hw : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t inc_acal_ctrl_en_hw : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t inc_fcal_ctrl_en_hw : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t sdm_ctrl_hw : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t rbb_pkdet_en_ctrl_hw : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t rbb_pkdet_out_rstn_ctrl_hw : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t adda_ctrl_hw : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad0 : 19; + }; + } rfctrl_hw_en; // @ 0xc + union { + uint32_t value; + struct { + uint32_t const_acal : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t const_fcal : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t temp_comp_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 15; + }; + } temp_comp; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t rcal_status : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t adc_oscal_status : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t fcal_status : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t acal_status : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t inc_fcal_status : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t inc_acal_status : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t clkpll_cal_status : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t ros_status : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t tos_status : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t rccal_status : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t lo_leakcal_status : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t tiqcal_status_resv : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t riqcal_status_resv : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pwdet_cal_status : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t tenscal_status : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t dpd_status : 2; // @ 31 -- 30 # 0x3fffffff + }; + } rfcal_status; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t dl_rfcal_table_status : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 30; + }; + } rfcal_status2; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t rcal_en_resv : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t adc_oscal_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t dl_rfcal_table_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t fcal_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t acal_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t fcal_inc_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t acal_inc_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t roscal_inc_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t clkpll_cal_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t roscal_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t toscal_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t rccal_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t lo_leakcal_en : 1; // @ 12 -- 12 # 0xffffefff + uint32_t tiqcal_en : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t riqcal_en : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pwdet_cal_en : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t tsencal_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t dpd_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pad0 : 14; + }; + } rfcal_ctrlen; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t rcal_sten_resv : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t adc_oscal_sten : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t dl_rfcal_table_sten : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t fcal_sten : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t acal_sten : 1; // @ 4 -- 4 # 0xffffffef + uint32_t inc_fcal_sten : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t inc_acal_sten : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t clkpll_cal_sten : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t roscal_sten : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t toscal_sten_resv : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t rccal_sten : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t lo_leakcal_sten : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t tiqcal_sten : 1; // @ 12 -- 12 # 0xffffefff + uint32_t riqcal_sten : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pwdet_cal_sten : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t tsencal_sten : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t dpd_sten : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad0 : 13; + uint32_t rfcal_level : 2; // @ 31 -- 30 # 0x3fffffff + }; + } rfcal_stateen; // @ 0x20 + uint32_t saradc_resv; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t aupll_sdm_rst_dly : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t lo_sdm_rst_dly : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t pad0 : 4; + uint32_t ppu_lead : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pud_vco_dly : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t pud_iref_dly : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pud_pa_dly : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t pad1 : 11; + uint32_t mbg_trim : 2; // @ 28 -- 27 # 0xe7ffffff + uint32_t pad2 : 3; + }; + } rf_base_ctrl1; // @ 0x28 + uint32_t rf_base_ctrl2; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t pu_sfreg : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 7; + uint32_t pu_lna : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pu_rmxgm : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pu_rmx : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pu_rbb : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pu_adda_ldo : 1; // @ 12 -- 12 # 0xffffefff + uint32_t adc_clk_en : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pu_adc : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pu_op_atest : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t pu_pa : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pu_tmx : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pu_tbb : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pu_dac : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pu_vco : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pu_fbdv : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pu_pfd : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pu_osmx : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pu_rxbuf : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pu_txbuf : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t trsw_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad1 : 1; + uint32_t pu_pkdet : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pu_rosdac : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pu_pwrmx : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t pu_tosdac : 1; // @ 31 -- 31 # 0x7fffffff + }; + } pucr1; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t pu_sfreg_hw : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 7; + uint32_t pu_lna_hw : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pu_rmxgm_hw : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pu_rmx_hw : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pu_rbb_hw : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pu_adda_ldo_hw : 1; // @ 12 -- 12 # 0xffffefff + uint32_t adc_clk_en_hw : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pu_adc_hw : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pad1 : 1; + uint32_t pu_pa_hw : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pu_tmx_hw : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pu_tbb_hw : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pu_dac_hw : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pu_vco_hw : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pu_fbdv_hw : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pu_pfd_hw : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pu_osmx_hw : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pu_rxbuf_hw : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pu_txbuf_hw : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t trsw_en_hw : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad2 : 1; + uint32_t pu_pkdet_hw : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pu_rosdac_hw : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad3 : 1; + uint32_t pu_tosdac_hw : 1; // @ 31 -- 31 # 0x7fffffff + }; + } pucr1_hw; // @ 0x34 + uint32_t pucr2; // @ 0x38 + uint32_t pucr2_hw; // @ 0x3c + union { + uint32_t value; + struct { + uint32_t pad0 : 8; + uint32_t ppu_lna_hw : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t ppu_rmxgm_hw : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad1 : 1; + uint32_t ppu_rbb_hw : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad2 : 8; + uint32_t ppu_vco_hw : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ppu_fbdv_hw : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ppu_pfd_hw : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t ppu_osmx_hw : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t ppu_rxbuf_hw : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t ppu_txbuf_hw : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t pad3 : 6; + }; + } ppu_ctrl_hw; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t pad0 : 20; + uint32_t pud_vco_hw : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad1 : 11; + }; + } pud_ctrl_hw; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t gc_lna : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t gc_rmxgm : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t gc_rbb1 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gc_rbb2 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gc_tmx : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad4 : 1; + uint32_t gc_tbb : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t pad5 : 3; + uint32_t gc_tbb_boost : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t pad6 : 2; + }; + } trx_gain1; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t gc_lna_hw : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t gc_rmxgm_hw : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t gc_rbb1_hw : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gc_rbb2_hw : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gc_tmx_hw : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad4 : 1; + uint32_t gc_tbb_hw : 5; // @ 24 -- 20 # 0xfe0fffff + uint32_t pad5 : 3; + uint32_t gc_tbb_boost_hw : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t pad6 : 2; + }; + } trx_gain_hw; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t tmux : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t dc_tp_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t dc_tp_clkpll_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 3; + uint32_t ten_clkpll : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t ten_clkpll_sfreg : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad1 : 2; + uint32_t ten_rrf_0 : 1; // @ 12 -- 12 # 0xffffefff + uint32_t ten_rrf_1 : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t ten_pa : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t ten_tmx : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t ten_tia : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t ten_bq : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t ten_atest : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t ten_tbb : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t ten_adc : 1; // @ 20 -- 20 # 0xffefffff + uint32_t ten_dac_i : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t ten_dac_q : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad2 : 1; + uint32_t ten_vco : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t ten_pfdcp : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t ten_lf : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t ten_lodist : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t pad3 : 4; + }; + } ten_dc; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t dten_clkpll_postdiv_clk : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t dten_clkpll_clk96m : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t dten_clkpll_clk32m : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t dten_clkpll_fsdm : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t dten_clkpll_fref : 1; // @ 4 -- 4 # 0xffffffef + uint32_t dten_clkpll_fin : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t dten_lo_fsdm : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 1; + uint32_t dten_lo_fref : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t dtest_pull_down : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad1 : 13; + uint32_t rf_dtest_en : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pad2 : 8; + }; + } ten_dig; // @ 0x54 + union { + uint32_t value; + struct { + uint32_t atest_op_cc : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t atest_dac_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t atest_in_trx_sw : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t atest_in_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 1; + uint32_t atest_gain_r9 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t atest_gain_r8 : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t atest_gain_r7 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t atest_gain_r6 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t atest_gain_r5 : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad1 : 1; + uint32_t atest_out_en_q : 1; // @ 20 -- 20 # 0xffefffff + uint32_t atest_out_en_i : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t atest_in_en_q : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t atest_in_en_i : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pad2 : 8; + }; + } ten_ac; // @ 0x58 + uint32_t pmip_mv2aon; // @ 0x5c + union { + uint32_t value; + struct { + uint32_t vg11_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t vg13_sel : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t pad0 : 28; + }; + } cip; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t pa_iaq : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pa_etb_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pa_iet : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t pa_vbcore : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pa_vbcas : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pa_half_on : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t pa_ib_fix : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pa_lz_bias_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pa_pwrmx_osdac : 4; // @ 21 -- 18 # 0xffc3ffff + uint32_t pa_pwrmx_dac_pn_switch : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad0 : 1; + uint32_t pa_pwrmx_bm : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad1 : 1; + uint32_t pa_att_gc : 4; // @ 31 -- 28 # 0xfffffff + }; + } pa1; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t pad0 : 3; + uint32_t pa_etb_en_hw : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pa_iet_hw : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t pa_vbcore_hw : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t pa_vbcas_hw : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad1 : 1; + uint32_t pa_half_on_hw : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pa_ib_fix_hw : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pad2 : 14; + }; + } pa2; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t tmx_cs : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t tmx_bm_sw : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t tmx_bm_cas : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad2 : 1; + uint32_t tmx_bm_cas_bulk : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t tx_tsense_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 15; + }; + } tmx; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t tbb_bm_sf : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t tbb_bm_cg : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t tbb_vcm : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t tbb_cflt : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t tbb_iq_bias_short : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t tbb_atest_out_en : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t tbb_tosdac_q : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad3 : 2; + uint32_t tbb_tosdac_i : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad4 : 2; + }; + } tbb; // @ 0x70 + union { + uint32_t value; + struct { + uint32_t lna_bm : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t lna_bm_hw : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t lna_load_csw : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t lna_load_csw_hw : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t lna_rfb_match : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad0 : 1; + uint32_t lna_cap_lg : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t pad1 : 2; + uint32_t lna_lg_gsel : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad2 : 5; + }; + } lna; // @ 0x74 + union { + uint32_t value; + struct { + uint32_t rmx_bm : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t rmxgm_bm : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t rmxgm_10m_mode_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 23; + }; + } rmxgm; // @ 0x78 + union { + uint32_t value; + struct { + uint32_t rosdac_q : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t rosdac_i : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t rosdac_q_hw : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t rosdac_i_hw : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 1; + uint32_t rosdac_range : 1; // @ 31 -- 31 # 0x7fffffff + }; + } rbb1; // @ 0x7c + union { + uint32_t value; + struct { + uint32_t rbb_cap2_fc_q : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t rbb_cap2_fc_i : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t rbb_cap1_fc_q : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t rbb_cap1_fc_i : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } rbb2; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t rbb_bt_mode_hw : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t rbb_bt_mode : 1; // @ 4 -- 4 # 0xffffffef + uint32_t rbb_bt_fif_tune : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t pad1 : 1; + uint32_t rbb_deq : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t rbb_bm_op : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t rbb_vcm : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t rbb_bq_iqbias_short : 1; // @ 20 -- 20 # 0xffefffff + uint32_t rbb_tia_iqbias_short : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad5 : 2; + uint32_t rbb_bw : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad6 : 2; + uint32_t rxiqcal_en : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad7 : 2; + uint32_t pwr_det_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } rbb3; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t rbb_pkdet_vth : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t rbb_pkdet_out_rstn : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 3; + uint32_t rbb_pkdet_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 3; + uint32_t rbb_pkdet_out_rstn_hw : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad2 : 3; + uint32_t rbb_pkdet_en_hw : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad3 : 3; + uint32_t pkdet_out_raw : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad4 : 3; + uint32_t pkdet_out_latch : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad5 : 7; + }; + } rbb4; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t dac_dvdd_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t dac_bias_sel : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t dac_clk_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t dac_rccalsel : 1; // @ 12 -- 12 # 0xffffefff + uint32_t dac_clk_sync_inv : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad3 : 2; + uint32_t adda_ldo_byps : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 3; + uint32_t adda_ldo_dvdd_sel : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t adda_ldo_dvdd_sel_hw : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad6 : 5; + }; + } adda1; // @ 0x8c + union { + uint32_t value; + struct { + uint32_t adc_vref_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t adc_dly_ctl : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t adc_dvdd_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t adc_sar_ascal_en : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad3 : 3; + uint32_t adc_gt_rm : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 3; + uint32_t adc_clk_sync_inv : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad5 : 3; + uint32_t adc_clk_inv : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad6 : 3; + uint32_t adc_clk_div_sel : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad7 : 3; + }; + } adda2; // @ 0x90 + uint8_t pad0[0xc]; + union { + uint32_t value; + struct { + uint32_t lo_vco_freq_cw : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t lo_vco_freq_cw_hw : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad0 : 3; + uint32_t lo_vco_idac_cw_hw : 5; // @ 28 -- 24 # 0xe0ffffff + uint32_t pad1 : 3; + }; + } vco1; // @ 0xa0 + union { + uint32_t value; + struct { + uint32_t lo_vco_vbias_cw : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t lo_vco_idac_boot : 1; // @ 4 -- 4 # 0xffffffef + uint32_t lo_vco_short_vbias_filter : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t lo_vco_short_idac_filter : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad1 : 1; + uint32_t acal_vref_cw : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad2 : 1; + uint32_t acal_vco_ud : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad3 : 3; + uint32_t acal_inc_en_hw : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 15; + }; + } vco2; // @ 0xa4 + union { + uint32_t value; + struct { + uint32_t fcal_div : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t fcal_cnt_op : 16; // @ 31 -- 16 # 0xffff + }; + } vco3; // @ 0xa8 + union { + uint32_t value; + struct { + uint32_t pad0 : 4; + uint32_t fcal_cnt_start : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t fcal_inc_en_hw : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 7; + uint32_t fcal_inc_large_range : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad3 : 3; + uint32_t fcal_cnt_rdy : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad4 : 3; + uint32_t fcal_inc_vctrl_ud : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad5 : 6; + }; + } vco4; // @ 0xac + union { + uint32_t value; + struct { + uint32_t lo_cp_sel : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t lo_cp_sel_hw : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t lo_cp_startup_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 3; + uint32_t lo_cp_ota_en : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad3 : 3; + uint32_t lo_cp_opamp_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 3; + uint32_t lo_cp_hiz : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad5 : 3; + uint32_t lo_pfd_rvdd_boost : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad6 : 3; + uint32_t lo_pfd_rst_csd : 1; // @ 28 -- 28 # 0xefffffff + uint32_t lo_pfd_rst_csd_hw : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad7 : 2; + }; + } pfdcp; // @ 0xb0 + union { + uint32_t value; + struct { + uint32_t lo_lf_rz_hw : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t lo_lf_r4_hw : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad1 : 2; + uint32_t lo_lf_cz_hw : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t lo_lf_rz : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t lo_lf_cz : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t lo_lf_r4 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t lo_lf_r4_short : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad3 : 1; + uint32_t lo_slipped_dn : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad4 : 3; + uint32_t lo_slipped_up : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad5 : 7; + }; + } lo; // @ 0xb4 + union { + uint32_t value; + struct { + uint32_t lo_fbdv_halfstep_en_hw : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t lo_fbdv_halfstep_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t lo_fbdv_sel_sample_clk : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t lo_fbdv_sel_fb_clk : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pad3 : 2; + uint32_t lo_fbdv_rst : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad4 : 3; + uint32_t lo_fbdv_rst_hw : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad5 : 11; + }; + } fbdv; // @ 0xb8 + union { + uint32_t value; + struct { + uint32_t lo_osmx_xgm_boost : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 3; + uint32_t lo_osmx_en_xgm : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t lo_osmx_fix_cap : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad2 : 3; + uint32_t lo_osmx_vbuf_stre : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad3 : 3; + uint32_t lo_osmx_capbank_bias : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t lo_osmx_cap : 4; // @ 23 -- 20 # 0xff0fffff + uint32_t lo_lodist_txbuf_stre : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t pad5 : 3; + uint32_t lo_lodist_rxbuf_stre : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad6 : 3; + }; + } lodist; // @ 0xbc + union { + uint32_t value; + struct { + uint32_t lo_sdm_dither_sel_hw : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t lo_sdm_bypass_hw : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad1 : 3; + uint32_t lo_sdm_dither_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t lo_sdm_bypass : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad3 : 3; + uint32_t lo_sdm_rstb : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t lo_sdm_rstb_hw : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t pad4 : 2; + uint32_t lo_sdm_flag : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad5 : 11; + }; + } sdm1; // @ 0xc0 + union { + uint32_t value; + struct { + uint32_t lo_sdmin : 30; // @ 29 -- 0 # 0xc0000000 + uint32_t pad0 : 2; + }; + } sdm2; // @ 0xc4 + union { + uint32_t value; + struct { + uint32_t lo_sdmin_hw : 30; // @ 29 -- 0 # 0xc0000000 + uint32_t pad0 : 2; + }; + } sdm3; // @ 0xc8 + uint8_t pad1[0x20]; + union { + uint32_t value; + struct { + uint32_t rf_reserved0 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_resv_reg_0; // @ 0xec + union { + uint32_t value; + struct { + uint32_t rf_reserved1 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_resv_reg_1; // @ 0xf0 + union { + uint32_t value; + struct { + uint32_t rf_reserved2 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_resv_reg_2; // @ 0xf4 + union { + uint32_t value; + struct { + uint32_t gain_ctrl0_gc_rmxgm : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t gain_ctrl0_gc_lna : 3; // @ 4 -- 2 # 0xffffffe3 + uint32_t gain_ctrl1_gc_rmxgm : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t gain_ctrl1_gc_lna : 3; // @ 9 -- 7 # 0xfffffc7f + uint32_t gain_ctrl2_gc_rmxgm : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t gain_ctrl2_gc_lna : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t gain_ctrl3_gc_rmxgm : 2; // @ 16 -- 15 # 0xfffe7fff + uint32_t gain_ctrl3_gc_lna : 3; // @ 19 -- 17 # 0xfff1ffff + uint32_t gain_ctrl4_gc_rmxgm : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t gain_ctrl4_gc_lna : 3; // @ 24 -- 22 # 0xfe3fffff + uint32_t gain_ctrl5_gc_rmxgm : 2; // @ 26 -- 25 # 0xf9ffffff + uint32_t gain_ctrl5_gc_lna : 3; // @ 29 -- 27 # 0xc7ffffff + uint32_t pad0 : 2; + }; + } rrf_gain_index1; // @ 0xf8 + union { + uint32_t value; + struct { + uint32_t gain_ctrl8_gc_rmxgm : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t gain_ctrl8_gc_lna : 3; // @ 4 -- 2 # 0xffffffe3 + uint32_t gain_ctrl7_gc_rmxgm : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t gain_ctrl7_gc_lna : 3; // @ 9 -- 7 # 0xfffffc7f + uint32_t gain_ctrl6_gc_rmxgm : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t gain_ctrl6_gc_lna : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad0 : 17; + }; + } rrf_gain_index2; // @ 0xfc + union { + uint32_t value; + struct { + uint32_t lna_bm_hg : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t lna_bm_lg : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t lna_load_csw_hg : 4; // @ 11 -- 8 # 0xfffff0ff + uint32_t lna_load_csw_lg : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t pad0 : 16; + }; + } lna_ctrl_hw_mux; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t gain_ctrl0_gc_rbb1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t gain_ctrl0_gc_rbb2 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t gain_ctrl1_gc_rbb1 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gain_ctrl1_gc_rbb2 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gain_ctrl2_gc_rbb1 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t gain_ctrl2_gc_rbb2 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t gain_ctrl3_gc_rbb1 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad6 : 2; + uint32_t gain_ctrl3_gc_rbb2 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } rbb_gain_index1; // @ 0x104 + union { + uint32_t value; + struct { + uint32_t gain_ctrl4_gc_rbb1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t gain_ctrl4_gc_rbb2 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t gain_ctrl5_gc_rbb1 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gain_ctrl5_gc_rbb2 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gain_ctrl6_gc_rbb1 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t gain_ctrl6_gc_rbb2 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t gain_ctrl7_gc_rbb1 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad6 : 2; + uint32_t gain_ctrl7_gc_rbb2 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } rbb_gain_index2; // @ 0x108 + union { + uint32_t value; + struct { + uint32_t gain_ctrl8_gc_rbb1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t gain_ctrl8_gc_rbb2 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t gain_ctrl9_gc_rbb1 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gain_ctrl9_gc_rbb2 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gain_ctrl10_gc_rbb1 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t gain_ctrl10_gc_rbb2 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t gain_ctrl11_gc_rbb1 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad6 : 2; + uint32_t gain_ctrl11_gc_rbb2 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } rbb_gain_index3; // @ 0x10c + union { + uint32_t value; + struct { + uint32_t gain_ctrl12_gc_rbb1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t gain_ctrl12_gc_rbb2 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t gain_ctrl13_gc_rbb1 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad2 : 2; + uint32_t gain_ctrl13_gc_rbb2 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t gain_ctrl14_gc_rbb1 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad4 : 2; + uint32_t gain_ctrl14_gc_rbb2 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t gain_ctrl15_gc_rbb1 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad6 : 2; + uint32_t gain_ctrl15_gc_rbb2 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } rbb_gain_index4; // @ 0x110 + union { + uint32_t value; + struct { + uint32_t gain_ctrl16_gc_rbb1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 2; + uint32_t gain_ctrl16_gc_rbb2 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 25; + }; + } rbb_gain_index5; // @ 0x114 + union { + uint32_t value; + struct { + uint32_t gain_ctrl0_gc_tbb : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t gain_ctrl0_gc_tmx : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 1; + uint32_t gain_ctrl0_dac_bias_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t gain_ctrl0_gc_tbb_boost : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t gain_ctrl1_gc_tbb : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad2 : 3; + uint32_t gain_ctrl1_gc_tmx : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad3 : 1; + uint32_t gain_ctrl1_dac_bias_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t gain_ctrl1_gc_tbb_boost : 2; // @ 31 -- 30 # 0x3fffffff + }; + } tbb_gain_index1; // @ 0x118 + union { + uint32_t value; + struct { + uint32_t gain_ctrl2_gc_tbb : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t gain_ctrl2_gc_tmx : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 1; + uint32_t gain_ctrl2_dac_bias_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t gain_ctrl2_gc_tbb_boost : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t gain_ctrl3_gc_tbb : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad2 : 3; + uint32_t gain_ctrl3_gc_tmx : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad3 : 1; + uint32_t gain_ctrl3_dac_bias_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t gain_ctrl3_gc_tbb_boost : 2; // @ 31 -- 30 # 0x3fffffff + }; + } tbb_gain_index2; // @ 0x11c + union { + uint32_t value; + struct { + uint32_t gain_ctrl4_gc_tbb : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t gain_ctrl4_gc_tmx : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 1; + uint32_t gain_ctrl4_dac_bias_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t gain_ctrl4_gc_tbb_boost : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t gain_ctrl5_gc_tbb : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad2 : 3; + uint32_t gain_ctrl5_gc_tmx : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad3 : 1; + uint32_t gain_ctrl5_dac_bias_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t gain_ctrl5_gc_tbb_boost : 2; // @ 31 -- 30 # 0x3fffffff + }; + } tbb_gain_index3; // @ 0x120 + union { + uint32_t value; + struct { + uint32_t gain_ctrl6_gc_tbb : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t gain_ctrl6_gc_tmx : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 1; + uint32_t gain_ctrl6_dac_bias_sel : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t gain_ctrl6_gc_tbb_boost : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t gain_ctrl7_gc_tbb : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad2 : 3; + uint32_t gain_ctrl7_gc_tmx : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad3 : 1; + uint32_t gain_ctrl7_dac_bias_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t gain_ctrl7_gc_tbb_boost : 2; // @ 31 -- 30 # 0x3fffffff + }; + } tbb_gain_index4; // @ 0x124 + union { + uint32_t value; + struct { + uint32_t pad0 : 12; + uint32_t pa_iet_11n : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t pa_vbcore_11n : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t pa_vbcas_11n : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 9; + }; + } pa_reg_ctrl_hw1; // @ 0x128 + union { + uint32_t value; + struct { + uint32_t pa_iet_11g : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t pa_vbcore_11g : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t pa_vbcas_11g : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad0 : 1; + uint32_t pa_iet_11b : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t pa_vbcore_11b : 4; // @ 19 -- 16 # 0xfff0ffff + uint32_t pa_vbcas_11b : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 9; + }; + } pa_reg_ctrl_hw2; // @ 0x12c + union { + uint32_t value; + struct { + uint32_t pa_half_on_wifi : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 7; + uint32_t pa_etb_en_wifi : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t pad1 : 7; + uint32_t pa_ib_fix_wifi : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t pad2 : 15; + }; + } pa_reg_wifi_ctrl_hw; // @ 0x130 + union { + uint32_t value; + struct { + uint32_t adda_ldo_dvdd_sel_rx : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t adda_ldo_dvdd_sel_tx : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 25; + }; + } adda_reg_ctrl_hw; // @ 0x134 + union { + uint32_t value; + struct { + uint32_t lo_fbdv_halfstep_en_rx : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t lo_fbdv_halfstep_en_tx : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t lo_cp_sel_rx : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t lo_cp_sel_tx : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t lo_lf_cz_rx : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t pad0 : 2; + uint32_t lo_lf_cz_tx : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 2; + uint32_t lo_lf_rz_rx : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pad2 : 2; + uint32_t lo_lf_rz_tx : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad3 : 2; + uint32_t lo_lf_r4_rx : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t pad4 : 2; + uint32_t lo_lf_r4_tx : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad5 : 6; + }; + } lo_reg_ctrl_hw1; // @ 0x138 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2404 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2404 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2408 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2408 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw1; // @ 0x13c + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2412 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2412 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2416 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2416 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw2; // @ 0x140 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2420 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2420 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2424 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2424 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw3; // @ 0x144 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2428 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2428 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2432 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2432 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw4; // @ 0x148 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2436 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2436 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2440 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2440 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw5; // @ 0x14c + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2444 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2444 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2448 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2448 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw6; // @ 0x150 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2452 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2452 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2456 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2456 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw7; // @ 0x154 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2460 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2460 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2464 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2464 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw8; // @ 0x158 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2468 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2468 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2472 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2472 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw9; // @ 0x15c + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2476 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2476 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t lo_vco_idac_cw_2480 : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 3; + uint32_t lo_vco_freq_cw_2480 : 8; // @ 31 -- 24 # 0xffffff + }; + } lo_cal_ctrl_hw10; // @ 0x160 + union { + uint32_t value; + struct { + uint32_t lo_vco_idac_cw_2484 : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 3; + uint32_t lo_vco_freq_cw_2484 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t pad1 : 16; + }; + } lo_cal_ctrl_hw11; // @ 0x164 + union { + uint32_t value; + struct { + uint32_t rosdac_i_gc0 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t rosdac_q_gc0 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t rosdac_i_gc1 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t rosdac_q_gc1 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } rosdac_ctrl_hw1; // @ 0x168 + union { + uint32_t value; + struct { + uint32_t rosdac_i_gc2 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t rosdac_q_gc2 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t rosdac_i_gc3 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t rosdac_q_gc3 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } rosdac_ctrl_hw2; // @ 0x16c + union { + uint32_t value; + struct { + uint32_t rx_iq_phase_comp_gc0 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_iq_gain_comp_gc0 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } rxiq_ctrl_hw1; // @ 0x170 + union { + uint32_t value; + struct { + uint32_t rx_iq_phase_comp_gc1 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_iq_gain_comp_gc1 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } rxiq_ctrl_hw2; // @ 0x174 + union { + uint32_t value; + struct { + uint32_t rx_iq_phase_comp_gc2 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_iq_gain_comp_gc2 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } rxiq_ctrl_hw3; // @ 0x178 + union { + uint32_t value; + struct { + uint32_t rx_iq_phase_comp_gc3 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_iq_gain_comp_gc3 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } rxiq_ctrl_hw4; // @ 0x17c + union { + uint32_t value; + struct { + uint32_t tbb_tosdac_i_gc0 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t tbb_tosdac_q_gc0 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t tbb_tosdac_i_gc1 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t tbb_tosdac_q_gc1 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } tosdac_ctrl_hw1; // @ 0x180 + union { + uint32_t value; + struct { + uint32_t tbb_tosdac_i_gc2 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t tbb_tosdac_q_gc2 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t tbb_tosdac_i_gc3 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t tbb_tosdac_q_gc3 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } tosdac_ctrl_hw2; // @ 0x184 + union { + uint32_t value; + struct { + uint32_t tbb_tosdac_i_gc4 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t tbb_tosdac_q_gc4 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t tbb_tosdac_i_gc5 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t tbb_tosdac_q_gc5 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } tosdac_ctrl_hw3; // @ 0x188 + union { + uint32_t value; + struct { + uint32_t tbb_tosdac_i_gc6 : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t tbb_tosdac_q_gc6 : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t tbb_tosdac_i_gc7 : 6; // @ 21 -- 16 # 0xffc0ffff + uint32_t pad2 : 2; + uint32_t tbb_tosdac_q_gc7 : 6; // @ 29 -- 24 # 0xc0ffffff + uint32_t pad3 : 2; + }; + } tosdac_ctrl_hw4; // @ 0x18c + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc0 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc0 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw0; // @ 0x190 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc1 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc1 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw1; // @ 0x194 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc2 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc2 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw2; // @ 0x198 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc3 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc3 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw3; // @ 0x19c + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc4 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc4 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw4; // @ 0x1a0 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc5 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc5 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw5; // @ 0x1a4 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc6 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc6 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw6; // @ 0x1a8 + union { + uint32_t value; + struct { + uint32_t tx_iq_phase_comp_gc7 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t tx_iq_gain_comp_gc7 : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } tx_iq_gain_hw7; // @ 0x1ac + union { + uint32_t value; + struct { + uint32_t lo_sdm_dither_sel_wlan_2412 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t lo_sdm_dither_sel_wlan_2417 : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t lo_sdm_dither_sel_wlan_2422 : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t lo_sdm_dither_sel_wlan_2427 : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t lo_sdm_dither_sel_wlan_2432 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t lo_sdm_dither_sel_wlan_2437 : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t lo_sdm_dither_sel_wlan_2442 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t lo_sdm_dither_sel_wlan_2447 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t lo_sdm_dither_sel_wlan_2452 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t lo_sdm_dither_sel_wlan_2457 : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t lo_sdm_dither_sel_wlan_2462 : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t lo_sdm_dither_sel_wlan_2467 : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t lo_sdm_dither_sel_wlan_2472 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t lo_sdm_dither_sel_wlan_2484 : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t pad0 : 4; + }; + } lo_sdm_ctrl_hw1; // @ 0x1b0 + union { + uint32_t value; + struct { + uint32_t lo_sdm_dither_sel_ble_2402 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t lo_sdm_dither_sel_ble_2404 : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t lo_sdm_dither_sel_ble_2406 : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t lo_sdm_dither_sel_ble_2408 : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t lo_sdm_dither_sel_ble_2410 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t lo_sdm_dither_sel_ble_2412 : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t lo_sdm_dither_sel_ble_2414 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t lo_sdm_dither_sel_ble_2416 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t lo_sdm_dither_sel_ble_2418 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t lo_sdm_dither_sel_ble_2420 : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t lo_sdm_dither_sel_ble_2422 : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t lo_sdm_dither_sel_ble_2424 : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t lo_sdm_dither_sel_ble_2426 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t lo_sdm_dither_sel_ble_2428 : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t lo_sdm_dither_sel_ble_2430 : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t lo_sdm_dither_sel_ble_2432 : 2; // @ 31 -- 30 # 0x3fffffff + }; + } lo_sdm_ctrl_hw2; // @ 0x1b4 + union { + uint32_t value; + struct { + uint32_t lo_sdm_dither_sel_ble_2434 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t lo_sdm_dither_sel_ble_2436 : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t lo_sdm_dither_sel_ble_2438 : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t lo_sdm_dither_sel_ble_2440 : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t lo_sdm_dither_sel_ble_2442 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t lo_sdm_dither_sel_ble_2444 : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t lo_sdm_dither_sel_ble_2446 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t lo_sdm_dither_sel_ble_2448 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t lo_sdm_dither_sel_ble_2450 : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t lo_sdm_dither_sel_ble_2452 : 2; // @ 19 -- 18 # 0xfff3ffff + uint32_t lo_sdm_dither_sel_ble_2454 : 2; // @ 21 -- 20 # 0xffcfffff + uint32_t lo_sdm_dither_sel_ble_2456 : 2; // @ 23 -- 22 # 0xff3fffff + uint32_t lo_sdm_dither_sel_ble_2458 : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t lo_sdm_dither_sel_ble_2460 : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t lo_sdm_dither_sel_ble_2462 : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t lo_sdm_dither_sel_ble_2464 : 2; // @ 31 -- 30 # 0x3fffffff + }; + } lo_sdm_ctrl_hw3; // @ 0x1b8 + union { + uint32_t value; + struct { + uint32_t lo_sdm_dither_sel_ble_2466 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t lo_sdm_dither_sel_ble_2468 : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t lo_sdm_dither_sel_ble_2470 : 2; // @ 5 -- 4 # 0xffffffcf + uint32_t lo_sdm_dither_sel_ble_2472 : 2; // @ 7 -- 6 # 0xffffff3f + uint32_t lo_sdm_dither_sel_ble_2474 : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t lo_sdm_dither_sel_ble_2476 : 2; // @ 11 -- 10 # 0xfffff3ff + uint32_t lo_sdm_dither_sel_ble_2478 : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t lo_sdm_dither_sel_ble_2480 : 2; // @ 15 -- 14 # 0xffff3fff + uint32_t lo_sdm_dither_sel_ble_tx : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad0 : 14; + }; + } lo_sdm_ctrl_hw4; // @ 0x1bc + union { + uint32_t value; + struct { + uint32_t lo_center_freq_mhz : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t lo_sdm_bypass_mode : 6; // @ 17 -- 12 # 0xfffc0fff + uint32_t pad0 : 14; + }; + } lo_sdm_ctrl_hw5; // @ 0x1c0 + union { + uint32_t value; + struct { + uint32_t lo_sdmin_center : 29; // @ 28 -- 0 # 0xe0000000 + uint32_t pad0 : 3; + }; + } lo_sdm_ctrl_hw6; // @ 0x1c4 + union { + uint32_t value; + struct { + uint32_t lo_sdmin_1m : 20; // @ 19 -- 0 # 0xfff00000 + uint32_t pad0 : 12; + }; + } lo_sdm_ctrl_hw7; // @ 0x1c8 + union { + uint32_t value; + struct { + uint32_t lo_sdmin_if : 20; // @ 19 -- 0 # 0xfff00000 + uint32_t pad0 : 12; + }; + } lo_sdm_ctrl_hw8; // @ 0x1cc + union { + uint32_t value; + struct { + uint32_t rbb_bt_mode_ble : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } rbb_bw_ctrl_hw; // @ 0x1d0 + uint8_t pad2[0x38]; + union { + uint32_t value; + struct { + uint32_t singen_inc_step1 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t singen_inc_step0 : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 2; + uint32_t singen_unsign_en : 1; // @ 28 -- 28 # 0xefffffff + uint32_t singen_clkdiv_n : 2; // @ 30 -- 29 # 0x9fffffff + uint32_t singen_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } singen_ctrl0; // @ 0x20c + union { + uint32_t value; + struct { + uint32_t singen_clkdiv_q : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 2; + uint32_t singen_mode_q : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t singen_clkdiv_i : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 2; + uint32_t singen_mode_i : 4; // @ 31 -- 28 # 0xfffffff + }; + } singen_ctrl1; // @ 0x210 + union { + uint32_t value; + struct { + uint32_t singen_gain_i : 11; // @ 10 -- 0 # 0xfffff800 + uint32_t pad0 : 1; + uint32_t singen_start_addr1_i : 10; // @ 21 -- 12 # 0xffc00fff + uint32_t singen_start_addr0_i : 10; // @ 31 -- 22 # 0x3fffff + }; + } singen_ctrl2; // @ 0x214 + union { + uint32_t value; + struct { + uint32_t singen_gain_q : 11; // @ 10 -- 0 # 0xfffff800 + uint32_t pad0 : 1; + uint32_t singen_start_addr1_q : 10; // @ 21 -- 12 # 0xffc00fff + uint32_t singen_start_addr0_q : 10; // @ 31 -- 22 # 0x3fffff + }; + } singen_ctrl3; // @ 0x218 + union { + uint32_t value; + struct { + uint32_t singen_fix_q : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t singen_fix_en_q : 1; // @ 12 -- 12 # 0xffffefff + uint32_t pad0 : 3; + uint32_t singen_fix_i : 12; // @ 27 -- 16 # 0xf000ffff + uint32_t singen_fix_en_i : 1; // @ 28 -- 28 # 0xefffffff + uint32_t pad1 : 3; + }; + } singen_ctrl4; // @ 0x21c + union { + uint32_t value; + struct { + uint32_t rfckg_rxclk_4s_on : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rfckg_txclk_4s_on : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rfckg_adc_afifo_inv : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rfckg_adc_clkout_sel : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t rfckg_dac_afifo_inv : 1; // @ 4 -- 4 # 0xffffffef + uint32_t rx_dfe_en_4s : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rx_dfe_en_4s_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t tx_dfe_en_4s : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t tx_dfe_en_4s_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t rx_test_sel : 2; // @ 10 -- 9 # 0xfffff9ff + uint32_t tx_test_sel : 2; // @ 12 -- 11 # 0xffffe7ff + uint32_t pad_adc_clkout_inv_en : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad_dac_clkout_inv_en : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t rf_ch_ind_ble_4s : 7; // @ 21 -- 15 # 0xffc07fff + uint32_t rf_ch_ind_ble_4s_en : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t wifimode_4s : 2; // @ 24 -- 23 # 0xfe7fffff + uint32_t wifimode_4s_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t bbmode_4s : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t bbmode_4s_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t test_sel : 4; // @ 31 -- 28 # 0xfffffff + }; + } rfif_dfe_ctrl0; // @ 0x220 + union { + uint32_t value; + struct { + uint32_t test_read : 32; // @ 31 -- 0 # 0x0 + }; + } rfif_test_read; // @ 0x224 + union { + uint32_t value; + struct { + uint32_t test_from_pad_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t test_gc_from_pad_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rfckg_rxclk_div2_mode : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rfif_int_lo_unlocked_mask : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 12; + uint32_t rfif_ppud_cnt2 : 9; // @ 24 -- 16 # 0xfe00ffff + uint32_t rfif_ppud_cnt1 : 5; // @ 29 -- 25 # 0xc1ffffff + uint32_t rfif_ppud_manaual_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t pad1 : 1; + }; + } rfif_dig_ctrl; // @ 0x228 + union { + uint32_t value; + struct { + uint32_t rf_data_temp_0 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_data_temp_0; // @ 0x22c + union { + uint32_t value; + struct { + uint32_t rf_data_temp_1 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_data_temp_1; // @ 0x230 + union { + uint32_t value; + struct { + uint32_t rf_data_temp_2 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_data_temp_2; // @ 0x234 + union { + uint32_t value; + struct { + uint32_t rf_data_temp_3 : 32; // @ 31 -- 0 # 0x0 + }; + } rf_data_temp_3; // @ 0x238 + union { + uint32_t value; + struct { + uint32_t rf_sram_link_dly : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t rf_sram_link_mode : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t rf_sram_swap : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t rf_sram_ext_clr : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pad0 : 12; + }; + } rf_sram_ctrl0; // @ 0x23c + union { + uint32_t value; + struct { + uint32_t rf_sram_adc_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rf_sram_adc_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rf_sram_adc_loop_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rf_sram_adc_sts_clr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 12; + uint32_t rf_sram_adc_done_cnt : 16; // @ 31 -- 16 # 0xffff + }; + } rf_sram_ctrl1; // @ 0x240 + union { + uint32_t value; + struct { + uint32_t rf_sram_adc_addr_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t rf_sram_adc_addr_start : 16; // @ 31 -- 16 # 0xffff + }; + } rf_sram_ctrl2; // @ 0x244 + union { + uint32_t value; + struct { + uint32_t rf_sram_adc_sts : 32; // @ 31 -- 0 # 0x0 + }; + } rf_sram_ctrl3; // @ 0x248 + union { + uint32_t value; + struct { + uint32_t rf_sram_dac_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t rf_sram_dac_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rf_sram_dac_loop_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rf_sram_dac_sts_clr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 12; + uint32_t rf_sram_dac_done_cnt : 16; // @ 31 -- 16 # 0xffff + }; + } rf_sram_ctrl4; // @ 0x24c + union { + uint32_t value; + struct { + uint32_t rf_sram_dac_addr_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t rf_sram_dac_addr_start : 16; // @ 31 -- 16 # 0xffff + }; + } rf_sram_ctrl5; // @ 0x250 + union { + uint32_t value; + struct { + uint32_t rf_sram_dac_sts : 32; // @ 31 -- 0 # 0x0 + }; + } rf_sram_ctrl6; // @ 0x254 + union { + uint32_t value; + struct { + uint32_t rf_ical_r_cnt_n : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t rf_ical_a_cnt_n : 10; // @ 19 -- 10 # 0xfff003ff + uint32_t rf_ical_f_cnt_n : 10; // @ 29 -- 20 # 0xc00fffff + uint32_t rf_ical_a_ud_inv_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t rf_ical_f_ud_inv_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } rf_ical_ctrl0; // @ 0x258 + union { + uint32_t value; + struct { + uint32_t rf_ical_r_avg_n : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 5; + uint32_t rf_ical_r_os_q : 10; // @ 19 -- 10 # 0xfff003ff + uint32_t rf_ical_r_os_i : 10; // @ 29 -- 20 # 0xc00fffff + uint32_t pad1 : 2; + }; + } rf_ical_ctrl1; // @ 0x25c + union { + uint32_t value; + struct { + uint32_t rf_ical_period_n : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } rf_ical_ctrl2; // @ 0x260 + union { + uint32_t value; + struct { + uint32_t rf_ch_ind_wifi : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 20; + }; + } rf_fsm_ctrl0; // @ 0x264 + union { + uint32_t value; + struct { + uint32_t rf_fsm_lo_time : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t rf_fsm_lo_rdy : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t rf_fsm_lo_rdy_rst : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t rf_fsm_lo_rdy_4s_1 : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t rf_fsm_lo_rdy_sbclr : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t rf_fsm_pu_pa_dly_n : 10; // @ 29 -- 20 # 0xc00fffff + uint32_t pad0 : 2; + }; + } rf_fsm_ctrl1; // @ 0x268 + union { + uint32_t value; + struct { + uint32_t rf_fsm_st_dbg : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t rf_fsm_st_dbg_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t rf_trx_en_ble_4s : 1; // @ 4 -- 4 # 0xffffffef + uint32_t rf_trx_sw_ble_4s : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rf_trx_ble_4s_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 3; + uint32_t rf_fsm_dfe_tx_dly_n : 10; // @ 19 -- 10 # 0xfff003ff + uint32_t rf_fsm_dfe_rx_dly_n : 10; // @ 29 -- 20 # 0xc00fffff + uint32_t pad1 : 2; + }; + } rf_fsm_ctrl2; // @ 0x26c + union { + uint32_t value; + struct { + uint32_t pkdet_out_cnt_sts : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t pkdet_out_cnt_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pkdet_out_mode : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 26; + }; + } rf_pkdet_ctrl0; // @ 0x270 + uint8_t pad3[0x38c]; + union { + uint32_t value; + struct { + uint32_t tx_iqc_phase : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t tx_iqc_phase_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad0 : 1; + uint32_t tx_iqc_gain : 11; // @ 22 -- 12 # 0xff800fff + uint32_t tx_iqc_gain_en : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t tx_dvga_gain_qdb : 7; // @ 30 -- 24 # 0x80ffffff + uint32_t tx_dvga_gain_ctrl_hw : 1; // @ 31 -- 31 # 0x7fffffff + }; + } dfe_ctrl_0; // @ 0x600 + union { + uint32_t value; + struct { + uint32_t tx_dac_os_i : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 4; + uint32_t tx_dac_os_q : 12; // @ 27 -- 16 # 0xf000ffff + uint32_t pad1 : 2; + uint32_t tx_dac_dat_format : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t tx_dac_iq_swap : 1; // @ 31 -- 31 # 0x7fffffff + }; + } dfe_ctrl_1; // @ 0x604 + union { + uint32_t value; + struct { + uint32_t rx_adc_os_i : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_adc_os_q : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 2; + uint32_t rx_adc_dce_flt_en : 1; // @ 28 -- 28 # 0xefffffff + uint32_t rx_adc_low_pow_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t rx_adc_dat_format : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t rx_adc_iq_swap : 1; // @ 31 -- 31 # 0x7fffffff + }; + } dfe_ctrl_2; // @ 0x608 + union { + uint32_t value; + struct { + uint32_t rx_adc_4s_i_val : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t rx_adc_4s_i_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad0 : 5; + uint32_t rx_adc_4s_q_val : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t rx_adc_4s_q_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad1 : 5; + }; + } dfe_ctrl_3; // @ 0x60c + union { + uint32_t value; + struct { + uint32_t rx_pf_th2 : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t rx_pf_th1 : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 4; + uint32_t rx_pf_q_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t rx_pf_i_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } dfe_ctrl_4; // @ 0x610 + union { + uint32_t value; + struct { + uint32_t rx_iqc_phase : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t rx_iqc_phase_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad0 : 1; + uint32_t rx_iqc_gain : 11; // @ 22 -- 12 # 0xff800fff + uint32_t rx_iqc_gain_en : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t pad1 : 8; + }; + } dfe_ctrl_5; // @ 0x614 + union { + uint32_t value; + struct { + uint32_t rx_pm_freqshift_cw : 20; // @ 19 -- 0 # 0xfff00000 + uint32_t rx_pm_freqshift_en : 1; // @ 20 -- 20 # 0xffefffff + uint32_t pad0 : 7; + uint32_t rx_pm_done : 1; // @ 28 -- 28 # 0xefffffff + uint32_t rx_pm_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t rx_pm_in_sel : 2; // @ 31 -- 30 # 0x3fffffff + }; + } dfe_ctrl_6; // @ 0x618 + union { + uint32_t value; + struct { + uint32_t rx_pm_start_ofs : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t rx_pm_acc_len : 16; // @ 31 -- 16 # 0xffff + }; + } dfe_ctrl_7; // @ 0x61c + union { + uint32_t value; + struct { + uint32_t rx_pm_iqacc_i : 25; // @ 24 -- 0 # 0xfe000000 + uint32_t pad0 : 7; + }; + } dfe_ctrl_8; // @ 0x620 + union { + uint32_t value; + struct { + uint32_t rx_pm_iqacc_q : 25; // @ 24 -- 0 # 0xfe000000 + uint32_t pad0 : 7; + }; + } dfe_ctrl_9; // @ 0x624 + union { + uint32_t value; + struct { + uint32_t dfe_dac_raw_i : 11; // @ 10 -- 0 # 0xfffff800 + uint32_t pad0 : 5; + uint32_t dfe_dac_raw_q : 11; // @ 26 -- 16 # 0xf800ffff + uint32_t pad1 : 5; + }; + } dfe_ctrl_10; // @ 0x628 + union { + uint32_t value; + struct { + uint32_t dfe_adc_raw_i : 10; // @ 9 -- 0 # 0xfffffc00 + uint32_t pad0 : 6; + uint32_t dfe_adc_raw_q : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t pad1 : 6; + }; + } dfe_ctrl_11; // @ 0x62c + union { + uint32_t value; + struct { + uint32_t tx_dvga_gain_qdb_gc0 : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t tx_dvga_gain_qdb_gc1 : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t tx_dvga_gain_qdb_gc2 : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 1; + uint32_t tx_dvga_gain_qdb_gc3 : 7; // @ 30 -- 24 # 0x80ffffff + uint32_t pad3 : 1; + }; + } dfe_ctrl_12; // @ 0x630 + union { + uint32_t value; + struct { + uint32_t tx_dvga_gain_qdb_gc4 : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t tx_dvga_gain_qdb_gc5 : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t tx_dvga_gain_qdb_gc6 : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 1; + uint32_t tx_dvga_gain_qdb_gc7 : 7; // @ 30 -- 24 # 0x80ffffff + uint32_t pad3 : 1; + }; + } dfe_ctrl_13; // @ 0x634 + union { + uint32_t value; + struct { + uint32_t tx_dvga_gain_qdb_gc8 : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t tx_dvga_gain_qdb_gc9 : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t tx_dvga_gain_qdb_gc10 : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 1; + uint32_t tx_dvga_gain_qdb_gc11 : 7; // @ 30 -- 24 # 0x80ffffff + uint32_t pad3 : 1; + }; + } dfe_ctrl_14; // @ 0x638 + union { + uint32_t value; + struct { + uint32_t tx_dvga_gain_qdb_gc12 : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t tx_dvga_gain_qdb_gc13 : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t tx_dvga_gain_qdb_gc14 : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 1; + uint32_t tx_dvga_gain_qdb_gc15 : 7; // @ 30 -- 24 # 0x80ffffff + uint32_t pad3 : 1; + }; + } dfe_ctrl_15; // @ 0x63c + union { + uint32_t value; + struct { + uint32_t rf_tbb_ind_gc0 : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t rf_tbb_ind_gc1 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t rf_tbb_ind_gc2 : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad2 : 1; + uint32_t rf_tbb_ind_gc3 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t rf_tbb_ind_gc4 : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad4 : 1; + uint32_t rf_tbb_ind_gc5 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t rf_tbb_ind_gc6 : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad6 : 1; + uint32_t rf_tbb_ind_gc7 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } dfe_ctrl_16; // @ 0x640 + union { + uint32_t value; + struct { + uint32_t rf_tbb_ind_gc8 : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 1; + uint32_t rf_tbb_ind_gc9 : 3; // @ 6 -- 4 # 0xffffff8f + uint32_t pad1 : 1; + uint32_t rf_tbb_ind_gc10 : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad2 : 1; + uint32_t rf_tbb_ind_gc11 : 3; // @ 14 -- 12 # 0xffff8fff + uint32_t pad3 : 1; + uint32_t rf_tbb_ind_gc12 : 3; // @ 18 -- 16 # 0xfff8ffff + uint32_t pad4 : 1; + uint32_t rf_tbb_ind_gc13 : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad5 : 1; + uint32_t rf_tbb_ind_gc14 : 3; // @ 26 -- 24 # 0xf8ffffff + uint32_t pad6 : 1; + uint32_t rf_tbb_ind_gc15 : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t pad7 : 1; + }; + } dfe_ctrl_17; // @ 0x644 + union { + uint32_t value; + struct { + uint32_t tx_dvga_gain_qdb_ble_gc0 : 7; // @ 6 -- 0 # 0xffffff80 + uint32_t pad0 : 1; + uint32_t tx_dvga_gain_qdb_ble_gc1 : 7; // @ 14 -- 8 # 0xffff80ff + uint32_t pad1 : 1; + uint32_t tx_dvga_gain_qdb_ble_gc2 : 7; // @ 22 -- 16 # 0xff80ffff + uint32_t pad2 : 9; + }; + } dfe_ctrl_18; // @ 0x648 + uint8_t pad4[0xb4]; + union { + uint32_t value; + struct { + uint32_t rf_rx_notch0_alpha : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t rf_rx_notch1_alpha : 3; // @ 5 -- 3 # 0xffffffc7 + uint32_t rf_rx_notch0_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t rf_rx_notch1_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t rf_rx_notch0_nrmfc : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t rf_rx_notch1_nrmfc : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t pad0 : 8; + }; + } r0x1700; // @ 0x700 + }; +} rf_regs; +#define RF_BASE 0x40001000 +#define RF ((volatile rf_regs*)(RF_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/sec_dbg.h b/src/include/soc/sec_dbg.h new file mode 100644 index 0000000..7e58a04 --- /dev/null +++ b/src/include/soc/sec_dbg.h @@ -0,0 +1,64 @@ +#ifndef SEC_DBG_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t sd_chip_id_low : 32; // @ 31 -- 0 # 0x0 + }; + } sd_chip_id_low; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t sd_chip_id_high : 32; // @ 31 -- 0 # 0x0 + }; + } sd_chip_id_high; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t sd_wifi_mac_low : 32; // @ 31 -- 0 # 0x0 + }; + } sd_wifi_mac_low; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t sd_wifi_mac_high : 32; // @ 31 -- 0 # 0x0 + }; + } sd_wifi_mac_high; // @ 0xc + union { + uint32_t value; + struct { + uint32_t sd_dbg_pwd_low : 32; // @ 31 -- 0 # 0x0 + }; + } sd_dbg_pwd_low; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t sd_dbg_pwd_high : 32; // @ 31 -- 0 # 0x0 + }; + } sd_dbg_pwd_high; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t sd_dbg_pwd_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sd_dbg_pwd_trig : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t sd_dbg_cci_read_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t sd_dbg_cci_clk_sel : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t sd_dbg_pwd_cnt : 20; // @ 23 -- 4 # 0xff00000f + uint32_t sd_dbg_mode : 4; // @ 27 -- 24 # 0xf0ffffff + uint32_t sd_dbg_ena : 4; // @ 31 -- 28 # 0xfffffff + }; + } sd_status; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t sd_dbg_reserved : 32; // @ 31 -- 0 # 0x0 + }; + } sd_dbg_reserved; // @ 0x1c + }; +} sec_dbg_regs; +#define SEC_DBG_BASE 0x40003000 +#define SEC_DBG ((volatile sec_dbg_regs*)(SEC_DBG_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/sec_eng.h b/src/include/soc/sec_eng.h new file mode 100644 index 0000000..1213feb --- /dev/null +++ b/src/include/soc/sec_eng.h @@ -0,0 +1,626 @@ +#ifndef SEC_ENG_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t se_sha_0_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_sha_0_trig_1t : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_sha_0_mode : 3; // @ 4 -- 2 # 0xffffffe3 + uint32_t se_sha_0_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t se_sha_0_hash_sel : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad0 : 1; + uint32_t se_sha_0_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_sha_0_int_clr_1t : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_sha_0_int_set_1t : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t se_sha_0_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad1 : 3; + uint32_t se_sha_0_link_mode : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t se_sha_0_msg_len : 16; // @ 31 -- 16 # 0xffff + }; + } se_sha_0_ctrl; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t se_sha_0_msa : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_msa; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t se_sha_0_status : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_status; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t se_sha_0_dout_endian : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } se_sha_0_endian; // @ 0xc + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_0; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_1; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_2; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_3; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_4 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_4; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_5 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_5; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_6 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_6; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_l_7 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_l_7; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_0; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_1; // @ 0x34 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_2; // @ 0x38 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_3; // @ 0x3c + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_4 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_4; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_5 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_5; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_6 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_6; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t se_sha_0_hash_h_7 : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_hash_h_7; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t se_sha_0_lca : 32; // @ 31 -- 0 # 0x0 + }; + } se_sha_0_link; // @ 0x50 + uint8_t pad0[0xa8]; + union { + uint32_t value; + struct { + uint32_t se_sha_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_sha_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_sha_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_sha_0_ctrl_prot; // @ 0xfc + union { + uint32_t value; + struct { + uint32_t se_aes_0_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_aes_0_trig_1t : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_aes_0_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t se_aes_0_mode : 2; // @ 4 -- 3 # 0xffffffe7 + uint32_t se_aes_0_dec_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t se_aes_0_dec_key_sel : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t se_aes_0_hw_key_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t se_aes_0_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_aes_0_int_clr_1t : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_aes_0_int_set_1t : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t se_aes_0_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t se_aes_0_block_mode : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t se_aes_0_iv_sel : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t se_aes_0_link_mode : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t se_aes_0_msg_len : 16; // @ 31 -- 16 # 0xffff + }; + } se_aes_0_ctrl; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t se_aes_0_msa : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_msa; // @ 0x104 + union { + uint32_t value; + struct { + uint32_t se_aes_0_mda : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_mda; // @ 0x108 + union { + uint32_t value; + struct { + uint32_t se_aes_0_status : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_status; // @ 0x10c + union { + uint32_t value; + struct { + uint32_t se_aes_0_iv_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_iv_0; // @ 0x110 + union { + uint32_t value; + struct { + uint32_t se_aes_0_iv_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_iv_1; // @ 0x114 + union { + uint32_t value; + struct { + uint32_t se_aes_0_iv_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_iv_2; // @ 0x118 + union { + uint32_t value; + struct { + uint32_t se_aes_0_iv_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_iv_3; // @ 0x11c + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_0; // @ 0x120 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_1; // @ 0x124 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_2; // @ 0x128 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_3; // @ 0x12c + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_4 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_4; // @ 0x130 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_5 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_5; // @ 0x134 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_6 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_6; // @ 0x138 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_7 : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_key_7; // @ 0x13c + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_sel_0 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 30; + }; + } se_aes_0_key_sel_0; // @ 0x140 + union { + uint32_t value; + struct { + uint32_t se_aes_0_key_sel_1 : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 30; + }; + } se_aes_0_key_sel_1; // @ 0x144 + union { + uint32_t value; + struct { + uint32_t se_aes_0_dout_endian : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_aes_0_din_endian : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_aes_0_key_endian : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t se_aes_0_iv_endian : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 26; + uint32_t se_aes_0_ctr_len : 2; // @ 31 -- 30 # 0x3fffffff + }; + } se_aes_0_endian; // @ 0x148 + union { + uint32_t value; + struct { + uint32_t se_aes_0_sboot_key_sel : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } se_aes_0_sboot; // @ 0x14c + union { + uint32_t value; + struct { + uint32_t se_aes_0_lca : 32; // @ 31 -- 0 # 0x0 + }; + } se_aes_0_link; // @ 0x150 + uint8_t pad1[0xa8]; + union { + uint32_t value; + struct { + uint32_t se_aes_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_aes_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_aes_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_aes_0_ctrl_prot; // @ 0x1fc + union { + uint32_t value; + struct { + uint32_t se_trng_0_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_trng_0_trig_1t : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_trng_0_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t se_trng_0_dout_clr_1t : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t se_trng_0_ht_error : 1; // @ 4 -- 4 # 0xffffffef + uint32_t pad0 : 3; + uint32_t se_trng_0_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_trng_0_int_clr_1t : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_trng_0_int_set_1t : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t se_trng_0_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad1 : 1; + uint32_t se_trng_0_manual_fun_sel : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t se_trng_0_manual_reseed : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t se_trng_0_manual_en : 1; // @ 15 -- 15 # 0xffff7fff + uint32_t pad2 : 16; + }; + } se_trng_0_ctrl_0; // @ 0x200 + union { + uint32_t value; + struct { + uint32_t se_trng_0_status : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_status; // @ 0x204 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_0; // @ 0x208 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_1; // @ 0x20c + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_2; // @ 0x210 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_3; // @ 0x214 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_4 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_4; // @ 0x218 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_5 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_5; // @ 0x21c + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_6 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_6; // @ 0x220 + union { + uint32_t value; + struct { + uint32_t se_trng_0_dout_7 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_dout_7; // @ 0x224 + union { + uint32_t value; + struct { + uint32_t se_trng_0_test_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_trng_0_cp_test_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_trng_0_cp_bypass : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t se_trng_0_ht_dis : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t se_trng_0_ht_alarm_n : 8; // @ 11 -- 4 # 0xfffff00f + uint32_t pad0 : 20; + }; + } se_trng_0_test; // @ 0x228 + union { + uint32_t value; + struct { + uint32_t se_trng_0_reseed_n_lsb : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_ctrl_1; // @ 0x22c + union { + uint32_t value; + struct { + uint32_t se_trng_0_reseed_n_msb : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } se_trng_0_ctrl_2; // @ 0x230 + union { + uint32_t value; + struct { + uint32_t se_trng_0_cp_ratio : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t se_trng_0_ht_rct_c : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t se_trng_0_ht_apt_c : 10; // @ 25 -- 16 # 0xfc00ffff + uint32_t se_trng_0_ht_od_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t pad0 : 4; + uint32_t se_trng_0_rosc_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } se_trng_0_ctrl_3; // @ 0x234 + uint8_t pad2[0x8]; + union { + uint32_t value; + struct { + uint32_t se_trng_0_test_out_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_test_out_0; // @ 0x240 + union { + uint32_t value; + struct { + uint32_t se_trng_0_test_out_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_test_out_1; // @ 0x244 + union { + uint32_t value; + struct { + uint32_t se_trng_0_test_out_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_test_out_2; // @ 0x248 + union { + uint32_t value; + struct { + uint32_t se_trng_0_test_out_3 : 32; // @ 31 -- 0 # 0x0 + }; + } se_trng_0_test_out_3; // @ 0x24c + uint8_t pad3[0xac]; + union { + uint32_t value; + struct { + uint32_t se_trng_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_trng_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_trng_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_trng_0_ctrl_prot; // @ 0x2fc + union { + uint32_t value; + struct { + uint32_t se_pka_0_done : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_pka_0_done_clr_1t : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_pka_0_busy : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t se_pka_0_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t se_pka_0_prot_md : 4; // @ 7 -- 4 # 0xffffff0f + uint32_t se_pka_0_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_pka_0_int_clr_1t : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_pka_0_int_set : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t se_pka_0_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t se_pka_0_endian : 1; // @ 12 -- 12 # 0xffffefff + uint32_t se_pka_0_ram_clr_md : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad0 : 2; + uint32_t se_pka_0_status_clr_1t : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t se_pka_0_status : 15; // @ 31 -- 17 # 0x1ffff + }; + } se_pka_0_ctrl_0; // @ 0x300 + uint8_t pad4[0x8]; + union { + uint32_t value; + struct { + uint32_t se_pka_0_seed : 32; // @ 31 -- 0 # 0x0 + }; + } se_pka_0_seed; // @ 0x30c + union { + uint32_t value; + struct { + uint32_t se_pka_0_hburst : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t se_pka_0_hbypass : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 28; + }; + } se_pka_0_ctrl_1; // @ 0x310 + uint8_t pad5[0x2c]; + uint32_t se_pka_0_rw; // @ 0x340 + uint8_t pad6[0x1c]; + uint32_t se_pka_0_rw_burst; // @ 0x360 + uint8_t pad7[0x98]; + union { + uint32_t value; + struct { + uint32_t se_pka_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_pka_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_pka_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_pka_0_ctrl_prot; // @ 0x3fc + union { + uint32_t value; + struct { + uint32_t se_cdet_0_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_cdet_0_error : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_cdet_0_status : 14; // @ 15 -- 2 # 0xffff0003 + uint32_t se_cdet_0_g_loop_max : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t se_cdet_0_g_loop_min : 8; // @ 31 -- 24 # 0xffffff + }; + } se_cdet_0_ctrl_0; // @ 0x400 + union { + uint32_t value; + struct { + uint32_t se_cdet_0_t_loop_n : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t se_cdet_0_t_dly_n : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t se_cdet_0_g_slp_n : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t pad0 : 8; + }; + } se_cdet_0_ctrl_1; // @ 0x404 + uint8_t pad8[0xf4]; + union { + uint32_t value; + struct { + uint32_t se_cdet_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_cdet_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_cdet_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_cdet_0_ctrl_prot; // @ 0x4fc + union { + uint32_t value; + struct { + uint32_t se_gmac_0_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_gmac_0_trig_1t : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_gmac_0_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 5; + uint32_t se_gmac_0_int : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_gmac_0_int_clr_1t : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_gmac_0_int_set_1t : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t se_gmac_0_int_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t se_gmac_0_t_endian : 1; // @ 12 -- 12 # 0xffffefff + uint32_t se_gmac_0_h_endian : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t se_gmac_0_x_endian : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pad1 : 17; + }; + } se_gmac_0_ctrl_0; // @ 0x500 + union { + uint32_t value; + struct { + uint32_t se_gmac_0_lca : 32; // @ 31 -- 0 # 0x0 + }; + } se_gmac_0_lca; // @ 0x504 + union { + uint32_t value; + struct { + uint32_t se_gmac_0_status : 32; // @ 31 -- 0 # 0x0 + }; + } se_gmac_0_status; // @ 0x508 + uint8_t pad9[0xf0]; + union { + uint32_t value; + struct { + uint32_t se_gmac_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_gmac_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_gmac_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } se_gmac_0_ctrl_prot; // @ 0x5fc + uint8_t pad10[0x900]; + union { + uint32_t value; + struct { + uint32_t se_sha_prot_en_rd : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t se_sha_id0_en_rd : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t se_sha_id1_en_rd : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t se_aes_prot_en_rd : 1; // @ 4 -- 4 # 0xffffffef + uint32_t se_aes_id0_en_rd : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t se_aes_id1_en_rd : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t pad1 : 1; + uint32_t se_trng_prot_en_rd : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t se_trng_id0_en_rd : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t se_trng_id1_en_rd : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad2 : 1; + uint32_t se_pka_prot_en_rd : 1; // @ 12 -- 12 # 0xffffefff + uint32_t se_pka_id0_en_rd : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t se_pka_id1_en_rd : 1; // @ 14 -- 14 # 0xffffbfff + uint32_t pad3 : 1; + uint32_t se_cdet_prot_en_rd : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t se_cdet_id0_en_rd : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t se_cdet_id1_en_rd : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad4 : 1; + uint32_t se_gmac_prot_en_rd : 1; // @ 20 -- 20 # 0xffefffff + uint32_t se_gmac_id0_en_rd : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t se_gmac_id1_en_rd : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t pad5 : 8; + uint32_t se_dbg_dis : 1; // @ 31 -- 31 # 0x7fffffff + }; + } se_ctrl_prot_rd; // @ 0xf00 + union { + uint32_t value; + struct { + uint32_t se_ctrl_reserved_0 : 32; // @ 31 -- 0 # 0x0 + }; + } se_ctrl_reserved_0; // @ 0xf04 + union { + uint32_t value; + struct { + uint32_t se_ctrl_reserved_1 : 32; // @ 31 -- 0 # 0x0 + }; + } se_ctrl_reserved_1; // @ 0xf08 + union { + uint32_t value; + struct { + uint32_t se_ctrl_reserved_2 : 32; // @ 31 -- 0 # 0x0 + }; + } se_ctrl_reserved_2; // @ 0xf0c + }; +} sec_eng_regs; +#define SEC_ENG_BASE 0x40004000 +#define SEC_ENG ((volatile sec_eng_regs*)(SEC_ENG_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/sf_ctrl.h b/src/include/soc/sf_ctrl.h new file mode 100644 index 0000000..f3cc483 --- /dev/null +++ b/src/include/soc/sf_ctrl.h @@ -0,0 +1,669 @@ +#ifndef SF_CTRL_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t sf_clk_sf_rx_inv_sel : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t sf_clk_out_gate_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t sf_clk_out_inv_sel : 1; // @ 4 -- 4 # 0xffffffef + uint32_t sf_clk_sahb_sram_sel : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 2; + uint32_t sf_if_read_dly_n : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t sf_if_read_dly_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad2 : 4; + uint32_t sf_if_int : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t sf_if_int_clr : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t sf_if_int_set : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t sf_aes_dly_mode : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t sf_aes_dout_endian : 1; // @ 20 -- 20 # 0xffefffff + uint32_t sf_aes_ctr_plus_en : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t sf_aes_key_endian : 1; // @ 22 -- 22 # 0xffbfffff + uint32_t sf_aes_iv_endian : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t sf_id : 8; // @ 31 -- 24 # 0xffffff + }; + } sf_ctrl_0; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t sf_if_sr_pat_mask : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t sf_if_sr_pat : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t sf_if_sr_int : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t sf_if_sr_int_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t sf_if_sr_int_set : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t pad0 : 1; + uint32_t sf_if_0_ack_lat : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 1; + uint32_t sf_if_reg_hold : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t sf_if_reg_wp : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t sf_ahb2sif_stopped : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t sf_ahb2sif_stop : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t sf_if_fn_sel : 1; // @ 28 -- 28 # 0xefffffff + uint32_t sf_if_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t sf_ahb2sif_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t sf_ahb2sram_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_ctrl_1; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t sf_if_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sf_if_0_trig : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t sf_if_0_dat_byte : 10; // @ 11 -- 2 # 0xfffff003 + uint32_t sf_if_0_dmy_byte : 5; // @ 16 -- 12 # 0xfffe0fff + uint32_t sf_if_0_adr_byte : 3; // @ 19 -- 17 # 0xfff1ffff + uint32_t sf_if_0_cmd_byte : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t sf_if_0_dat_rw : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t sf_if_0_dat_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t sf_if_0_dmy_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t sf_if_0_adr_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t sf_if_0_cmd_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t sf_if_0_spi_mode : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t sf_if_0_qpi_mode_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_if_sahb_0; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t sf_if_0_cmd_buf_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_sahb_1; // @ 0xc + union { + uint32_t value; + struct { + uint32_t sf_if_0_cmd_buf_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_sahb_2; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t pad0 : 12; + uint32_t sf_if_1_dmy_byte : 5; // @ 16 -- 12 # 0xfffe0fff + uint32_t sf_if_1_adr_byte : 3; // @ 19 -- 17 # 0xfff1ffff + uint32_t sf_if_1_cmd_byte : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t sf_if_1_dat_rw : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t sf_if_1_dat_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t sf_if_1_dmy_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t sf_if_1_adr_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t sf_if_1_cmd_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t sf_if_1_spi_mode : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t sf_if_1_qpi_mode_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_if_iahb_0; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t sf_if_1_cmd_buf_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_iahb_1; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t sf_if_1_cmd_buf_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_iahb_2; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t sf_if_status_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_status_0; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t sf_if_status_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_status_1; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t sf_aes_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sf_aes_mode : 2; // @ 2 -- 1 # 0xfffffff9 + uint32_t sf_aes_pref_trig : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t sf_aes_pref_busy : 1; // @ 4 -- 4 # 0xffffffef + uint32_t sf_aes_status : 27; // @ 31 -- 5 # 0x1f + }; + } sf_aes; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t sf_ahb2sif_status : 32; // @ 31 -- 0 # 0x0 + }; + } sf_ahb2sif_status; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t sf_cs_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf_clk_out_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 16; + uint32_t sf_dqs_oe_dly_sel : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t sf_dqs_di_dly_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t sf_dqs_do_dly_sel : 2; // @ 31 -- 30 # 0x3fffffff + }; + } sf_if_io_dly_0; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t sf_io_0_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf_io_0_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf_io_0_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf_if_io_dly_1; // @ 0x34 + union { + uint32_t value; + struct { + uint32_t sf_io_1_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf_io_1_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf_io_1_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf_if_io_dly_2; // @ 0x38 + union { + uint32_t value; + struct { + uint32_t sf_io_2_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf_io_2_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf_io_2_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf_if_io_dly_3; // @ 0x3c + union { + uint32_t value; + struct { + uint32_t sf_io_3_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf_io_3_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf_io_3_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf_if_io_dly_4; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t sf_reserved : 32; // @ 31 -- 0 # 0x0 + }; + } sf_reserved; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t sf2_cs_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf2_clk_out_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 16; + uint32_t sf2_dqs_oe_dly_sel : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t sf2_dqs_di_dly_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t sf2_dqs_do_dly_sel : 2; // @ 31 -- 30 # 0x3fffffff + }; + } sf2_if_io_dly_0; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t sf2_io_0_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf2_io_0_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf2_io_0_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf2_if_io_dly_1; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t sf2_io_1_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf2_io_1_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf2_io_1_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf2_if_io_dly_2; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t sf2_io_2_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf2_io_2_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf2_io_2_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf2_if_io_dly_3; // @ 0x54 + union { + uint32_t value; + struct { + uint32_t sf2_io_3_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf2_io_3_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf2_io_3_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf2_if_io_dly_4; // @ 0x58 + union { + uint32_t value; + struct { + uint32_t sf3_cs_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf3_clk_out_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 16; + uint32_t sf3_dqs_oe_dly_sel : 2; // @ 27 -- 26 # 0xf3ffffff + uint32_t sf3_dqs_di_dly_sel : 2; // @ 29 -- 28 # 0xcfffffff + uint32_t sf3_dqs_do_dly_sel : 2; // @ 31 -- 30 # 0x3fffffff + }; + } sf3_if_io_dly_0; // @ 0x5c + union { + uint32_t value; + struct { + uint32_t sf3_io_0_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf3_io_0_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf3_io_0_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf3_if_io_dly_1; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t sf3_io_1_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf3_io_1_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf3_io_1_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf3_if_io_dly_2; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t sf3_io_2_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf3_io_2_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf3_io_2_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf3_if_io_dly_3; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t sf3_io_3_oe_dly_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 6; + uint32_t sf3_io_3_di_dly_sel : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 6; + uint32_t sf3_io_3_do_dly_sel : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 14; + }; + } sf3_if_io_dly_4; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t sf_if_pad_sel : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 1; + uint32_t sf_if_pad_sel_lock : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t sf_if_dtr_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t sf_if_dqs_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad1 : 26; + }; + } sf_ctrl_2; // @ 0x70 + union { + uint32_t value; + struct { + uint32_t sf_cmds_wrap_len : 4; // @ 3 -- 0 # 0xfffffff0 + uint32_t sf_cmds_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t sf_cmds_bt_dly : 3; // @ 7 -- 5 # 0xffffff1f + uint32_t sf_cmds_bt_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t sf_cmds_wrap_q_ini : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t sf_cmds_wrap_mode : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t pad0 : 18; + uint32_t sf_if_1_ack_lat : 3; // @ 31 -- 29 # 0x1fffffff + }; + } sf_ctrl_3; // @ 0x74 + union { + uint32_t value; + struct { + uint32_t pad0 : 12; + uint32_t sf_if_2_dmy_byte : 5; // @ 16 -- 12 # 0xfffe0fff + uint32_t sf_if_2_adr_byte : 3; // @ 19 -- 17 # 0xfff1ffff + uint32_t sf_if_2_cmd_byte : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t sf_if_2_dat_rw : 1; // @ 23 -- 23 # 0xff7fffff + uint32_t sf_if_2_dat_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t sf_if_2_dmy_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t sf_if_2_adr_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t sf_if_2_cmd_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t sf_if_2_spi_mode : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t sf_if_2_qpi_mode_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_if_iahb_3; // @ 0x78 + union { + uint32_t value; + struct { + uint32_t sf_if_2_cmd_buf_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_iahb_4; // @ 0x7c + union { + uint32_t value; + struct { + uint32_t sf_if_2_cmd_buf_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_iahb_5; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t pad0 : 20; + uint32_t sf_if_3_cmd_byte : 3; // @ 22 -- 20 # 0xff8fffff + uint32_t pad1 : 5; + uint32_t sf_if_3_spi_mode : 3; // @ 30 -- 28 # 0x8fffffff + uint32_t sf_if_3_qpi_mode_en : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_if_iahb_6; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t sf_if_3_cmd_buf_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_if_iahb_7; // @ 0x88 + uint8_t pad0[0x74]; + union { + uint32_t value; + struct { + uint32_t sf_ctrl_prot_en_rd : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sf_ctrl_id0_en_rd : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t sf_ctrl_id1_en_rd : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 27; + uint32_t sf_if_0_trig_wr_lock : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t sf_dbg_dis : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_ctrl_prot_en_rd; // @ 0x100 + union { + uint32_t value; + struct { + uint32_t sf_ctrl_prot_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sf_ctrl_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t sf_ctrl_id1_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } sf_ctrl_prot_en; // @ 0x104 + uint8_t pad1[0xf8]; + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_0; // @ 0x200 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_1; // @ 0x204 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_2; // @ 0x208 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_3; // @ 0x20c + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_4 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_4; // @ 0x210 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_5 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_5; // @ 0x214 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_6 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_6; // @ 0x218 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r0_7 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r0_7; // @ 0x21c + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r0_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r0_w0; // @ 0x220 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r0_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r0_w1; // @ 0x224 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r0_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r0_w2; // @ 0x228 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r0_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r0_w3; // @ 0x22c + union { + uint32_t value; + struct { + uint32_t sf_aes_region_r0_end : 14; // @ 13 -- 0 # 0xffffc000 + uint32_t sf_aes_region_r0_start : 14; // @ 27 -- 14 # 0xf0003fff + uint32_t pad0 : 1; + uint32_t sf_aes_region_r0_hw_key_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t sf_aes_region_r0_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t sf_aes_region_r0_lock : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_aes_cfg_r0; // @ 0x230 + uint8_t pad2[0xcc]; + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_0; // @ 0x300 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_1; // @ 0x304 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_2; // @ 0x308 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_3; // @ 0x30c + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_4 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_4; // @ 0x310 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_5 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_5; // @ 0x314 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_6 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_6; // @ 0x318 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r1_7 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r1_7; // @ 0x31c + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r1_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r1_w0; // @ 0x320 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r1_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r1_w1; // @ 0x324 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r1_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r1_w2; // @ 0x328 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r1_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r1_w3; // @ 0x32c + union { + uint32_t value; + struct { + uint32_t sf_aes_r1_end : 14; // @ 13 -- 0 # 0xffffc000 + uint32_t sf_aes_r1_start : 14; // @ 27 -- 14 # 0xf0003fff + uint32_t pad0 : 1; + uint32_t sf_aes_r1_hw_key_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t sf_aes_r1_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t sf_aes_r1_lock : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_aes_r1; // @ 0x330 + uint8_t pad3[0xcc]; + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_0; // @ 0x400 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_1; // @ 0x404 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_2; // @ 0x408 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_3; // @ 0x40c + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_4 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_4; // @ 0x410 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_5 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_5; // @ 0x414 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_6 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_6; // @ 0x418 + union { + uint32_t value; + struct { + uint32_t sf_aes_key_r2_7 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_key_r2_7; // @ 0x41c + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r2_w0 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r2_w0; // @ 0x420 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r2_w1 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r2_w1; // @ 0x424 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r2_w2 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r2_w2; // @ 0x428 + union { + uint32_t value; + struct { + uint32_t sf_aes_iv_r2_w3 : 32; // @ 31 -- 0 # 0x0 + }; + } sf_aes_iv_r2_w3; // @ 0x42c + union { + uint32_t value; + struct { + uint32_t sf_aes_r2_end : 14; // @ 13 -- 0 # 0xffffc000 + uint32_t sf_aes_r2_start : 14; // @ 27 -- 14 # 0xf0003fff + uint32_t pad0 : 1; + uint32_t sf_aes_r2_hw_key_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t sf_aes_r2_en : 1; // @ 30 -- 30 # 0xbfffffff + uint32_t sf_aes_r2_lock : 1; // @ 31 -- 31 # 0x7fffffff + }; + } sf_aes_r2; // @ 0x430 + union { + uint32_t value; + struct { + uint32_t sf_id0_offset : 24; // @ 23 -- 0 # 0xff000000 + uint32_t pad0 : 8; + }; + } sf_id0_offset; // @ 0x434 + union { + uint32_t value; + struct { + uint32_t sf_id1_offset : 24; // @ 23 -- 0 # 0xff000000 + uint32_t pad0 : 8; + }; + } sf_id1_offset; // @ 0x438 + }; +} sf_ctrl_regs; +#define SF_CTRL_BASE 0x4000b000 +#define SF_CTRL ((volatile sf_ctrl_regs*)(SF_CTRL_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/spi.h b/src/include/soc/spi.h new file mode 100644 index 0000000..eddb3d6 --- /dev/null +++ b/src/include/soc/spi.h @@ -0,0 +1,141 @@ +#ifndef SPI_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cr_spi_m_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_spi_s_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_spi_frame_size : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t cr_spi_sclk_pol : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_spi_sclk_ph : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_spi_bit_inv : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t cr_spi_byte_inv : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t cr_spi_rxd_ignr_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_spi_m_cont_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t pad0 : 1; + uint32_t cr_spi_deg_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_spi_deg_cnt : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t pad1 : 16; + }; + } spi_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t spi_end_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t spi_txf_int : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t spi_rxf_int : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t spi_sto_int : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t spi_txu_int : 1; // @ 4 -- 4 # 0xffffffef + uint32_t spi_fer_int : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t pad0 : 2; + uint32_t cr_spi_end_mask : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t cr_spi_txf_mask : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t cr_spi_rxf_mask : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t cr_spi_sto_mask : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_spi_txu_mask : 1; // @ 12 -- 12 # 0xffffefff + uint32_t cr_spi_fer_mask : 1; // @ 13 -- 13 # 0xffffdfff + uint32_t pad1 : 2; + uint32_t cr_spi_end_clr : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t rsvd_17 : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t rsvd_18 : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t cr_spi_sto_clr : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t cr_spi_txu_clr : 1; // @ 20 -- 20 # 0xffefffff + uint32_t rsvd_21 : 1; // @ 21 -- 21 # 0xffdfffff + uint32_t pad2 : 2; + uint32_t cr_spi_end_en : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t cr_spi_txf_en : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t cr_spi_rxf_en : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t cr_spi_sto_en : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t cr_spi_txu_en : 1; // @ 28 -- 28 # 0xefffffff + uint32_t cr_spi_fer_en : 1; // @ 29 -- 29 # 0xdfffffff + uint32_t pad3 : 2; + }; + } spi_int_sts; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t sts_spi_bus_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } spi_bus_busy; // @ 0x8 + uint8_t pad0[0x4]; + union { + uint32_t value; + struct { + uint32_t cr_spi_prd_s : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t cr_spi_prd_p : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t cr_spi_prd_d_ph_0 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t cr_spi_prd_d_ph_1 : 8; // @ 31 -- 24 # 0xffffff + }; + } spi_prd_0; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t cr_spi_prd_i : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } spi_prd_1; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t cr_spi_rxd_ignr_p : 5; // @ 4 -- 0 # 0xffffffe0 + uint32_t pad0 : 11; + uint32_t cr_spi_rxd_ignr_s : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad1 : 11; + }; + } spi_rxd_ignr; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t cr_spi_sto_value : 12; // @ 11 -- 0 # 0xfffff000 + uint32_t pad0 : 20; + }; + } spi_sto_value; // @ 0x1c + uint8_t pad1[0x60]; + union { + uint32_t value; + struct { + uint32_t spi_dma_tx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t spi_dma_rx_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tx_fifo_clr : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rx_fifo_clr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t tx_fifo_overflow : 1; // @ 4 -- 4 # 0xffffffef + uint32_t tx_fifo_underflow : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rx_fifo_overflow : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t rx_fifo_underflow : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } spi_fifo_config_0; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t tx_fifo_cnt : 3; // @ 2 -- 0 # 0xfffffff8 + uint32_t pad0 : 5; + uint32_t rx_fifo_cnt : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 5; + uint32_t tx_fifo_th : 2; // @ 17 -- 16 # 0xfffcffff + uint32_t pad2 : 6; + uint32_t rx_fifo_th : 2; // @ 25 -- 24 # 0xfcffffff + uint32_t pad3 : 6; + }; + } spi_fifo_config_1; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t spi_fifo_wdata : 32; // @ 31 -- 0 # 0x0 + }; + } spi_fifo_wdata; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t spi_fifo_rdata : 32; // @ 31 -- 0 # 0x0 + }; + } spi_fifo_rdata; // @ 0x8c + }; +} spi_regs; +#define SPI_BASE 0x4000a200 +#define SPI ((volatile spi_regs*)(SPI_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/timer.h b/src/include/soc/timer.h new file mode 100644 index 0000000..41945c8 --- /dev/null +++ b/src/include/soc/timer.h @@ -0,0 +1,286 @@ +#ifndef TIMER_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t pad0 : 2; + uint32_t cs_1 : 2; // @ 3 -- 2 # 0xfffffff3 + uint32_t RESERVED_4 : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cs_2 : 2; // @ 6 -- 5 # 0xffffff9f + uint32_t RESERVED_7 : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t cs_wdt : 2; // @ 9 -- 8 # 0xfffffcff + uint32_t pad1 : 22; + }; + } TCCR; // @ 0x0 + uint8_t pad0[0xc]; + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR2_0; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR2_1; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR2_2; // @ 0x18 + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR3_0; // @ 0x1c + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR3_1; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t tmr : 32; // @ 31 -- 0 # 0x0 + }; + } TMR3_2; // @ 0x24 + uint8_t pad1[0x4]; + union { + uint32_t value; + struct { + uint32_t tcr : 32; // @ 31 -- 0 # 0x0 + }; + } TCR2; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t tcr3_counter : 32; // @ 31 -- 0 # 0x0 + }; + } TCR3; // @ 0x30 + uint8_t pad2[0x4]; + union { + uint32_t value; + struct { + uint32_t tmsr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tmsr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tmsr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TMSR2; // @ 0x38 + union { + uint32_t value; + struct { + uint32_t tmsr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tmsr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tmsr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TMSR3; // @ 0x3c + uint8_t pad3[0x4]; + union { + uint32_t value; + struct { + uint32_t tier_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tier_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tier_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TIER2; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t tier_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tier_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tier_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TIER3; // @ 0x48 + uint8_t pad4[0x4]; + union { + uint32_t value; + struct { + uint32_t tplvr : 32; // @ 31 -- 0 # 0x0 + }; + } TPLVR2; // @ 0x50 + union { + uint32_t value; + struct { + uint32_t tplvr : 32; // @ 31 -- 0 # 0x0 + }; + } TPLVR3; // @ 0x54 + uint8_t pad5[0x4]; + union { + uint32_t value; + struct { + uint32_t tplcr : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 30; + }; + } TPLCR2; // @ 0x5c + union { + uint32_t value; + struct { + uint32_t tplcr : 2; // @ 1 -- 0 # 0xfffffffc + uint32_t pad0 : 30; + }; + } TPLCR3; // @ 0x60 + union { + uint32_t value; + struct { + uint32_t we : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t wrie : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } WMER; // @ 0x64 + union { + uint32_t value; + struct { + uint32_t wmr : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } WMR; // @ 0x68 + union { + uint32_t value; + struct { + uint32_t wvr : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } WVR; // @ 0x6c + union { + uint32_t value; + struct { + uint32_t wts : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } WSR; // @ 0x70 + uint8_t pad6[0x4]; + union { + uint32_t value; + struct { + uint32_t tclr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tclr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tclr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TICR2; // @ 0x78 + union { + uint32_t value; + struct { + uint32_t tclr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tclr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tclr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TICR3; // @ 0x7c + union { + uint32_t value; + struct { + uint32_t wiclr : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } WICR; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t pad0 : 1; + uint32_t timer2_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t timer3_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad1 : 29; + }; + } TCER; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t pad0 : 1; + uint32_t timer2_mode : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t timer3_mode : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad1 : 29; + }; + } TCMR; // @ 0x88 + uint8_t pad7[0x4]; + union { + uint32_t value; + struct { + uint32_t tilr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tilr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tilr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TILR2; // @ 0x90 + union { + uint32_t value; + struct { + uint32_t tilr_0 : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tilr_1 : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tilr_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 29; + }; + } TILR3; // @ 0x94 + union { + uint32_t value; + struct { + uint32_t wcr : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } WCR; // @ 0x98 + union { + uint32_t value; + struct { + uint32_t wfar : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } WFAR; // @ 0x9c + union { + uint32_t value; + struct { + uint32_t wsar : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } WSAR; // @ 0xa0 + uint8_t pad8[0x4]; + union { + uint32_t value; + struct { + uint32_t tcvwr : 32; // @ 31 -- 0 # 0x0 + }; + } TCVWR2; // @ 0xa8 + union { + uint32_t value; + struct { + uint32_t tcvwr : 32; // @ 31 -- 0 # 0x0 + }; + } TCVWR3; // @ 0xac + uint8_t pad9[0x4]; + union { + uint32_t value; + struct { + uint32_t tcvsyn2 : 32; // @ 31 -- 0 # 0x0 + }; + } TCVSYN2; // @ 0xb4 + union { + uint32_t value; + struct { + uint32_t tcvsyn3 : 32; // @ 31 -- 0 # 0x0 + }; + } TCVSYN3; // @ 0xb8 + union { + uint32_t value; + struct { + uint32_t pad0 : 8; + uint32_t tcdr2 : 8; // @ 15 -- 8 # 0xffff00ff + uint32_t tcdr3 : 8; // @ 23 -- 16 # 0xff00ffff + uint32_t wcdr : 8; // @ 31 -- 24 # 0xffffff + }; + } TCDR; // @ 0xbc + }; +} timer_regs; +#define TIMER_BASE 0x4000a500 +#define TIMER ((volatile timer_regs*)(TIMER_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/tzc_nsec.h b/src/include/soc/tzc_nsec.h new file mode 100644 index 0000000..7f8b623 --- /dev/null +++ b/src/include/soc/tzc_nsec.h @@ -0,0 +1,64 @@ +#ifndef TZC_NSEC_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint8_t pad0[0x40]; + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r0_id0_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tzc_rom0_r1_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tzc_rom1_r0_id0_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t tzc_rom1_r1_id0_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 4; + uint32_t tzc_rom0_r0_id1_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t tzc_rom0_r1_id1_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t tzc_rom1_r0_id1_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t tzc_rom1_r1_id1_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad1 : 4; + uint32_t tzc_rom0_r0_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t tzc_rom0_r1_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t tzc_rom1_r0_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t tzc_rom1_r1_en : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pad2 : 4; + uint32_t tzc_rom0_r0_lock : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t tzc_rom0_r1_lock : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t tzc_rom1_r0_lock : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t tzc_rom1_r1_lock : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t tzc_sboot_done : 4; // @ 31 -- 28 # 0xfffffff + }; + } tzc_rom_ctrl; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r0_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom0_r0_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom0_r0; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r1_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom0_r1_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom0_r1; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t tzc_rom1_r0_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom1_r0_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom1_r0; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t tzc_rom1_r1_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom1_r1_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom1_r1; // @ 0x50 + }; +} tzc_nsec_regs; +#define TZC_NSEC_BASE 0x40006000 +#define TZC_NSEC ((volatile tzc_nsec_regs*)(TZC_NSEC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/tzc_sec.h b/src/include/soc/tzc_sec.h new file mode 100644 index 0000000..8bcaa8e --- /dev/null +++ b/src/include/soc/tzc_sec.h @@ -0,0 +1,64 @@ +#ifndef TZC_SEC_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + uint8_t pad0[0x40]; + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r0_id0_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t tzc_rom0_r1_id0_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tzc_rom1_r0_id0_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t tzc_rom1_r1_id0_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t pad0 : 4; + uint32_t tzc_rom0_r0_id1_en : 1; // @ 8 -- 8 # 0xfffffeff + uint32_t tzc_rom0_r1_id1_en : 1; // @ 9 -- 9 # 0xfffffdff + uint32_t tzc_rom1_r0_id1_en : 1; // @ 10 -- 10 # 0xfffffbff + uint32_t tzc_rom1_r1_id1_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t pad1 : 4; + uint32_t tzc_rom0_r0_en : 1; // @ 16 -- 16 # 0xfffeffff + uint32_t tzc_rom0_r1_en : 1; // @ 17 -- 17 # 0xfffdffff + uint32_t tzc_rom1_r0_en : 1; // @ 18 -- 18 # 0xfffbffff + uint32_t tzc_rom1_r1_en : 1; // @ 19 -- 19 # 0xfff7ffff + uint32_t pad2 : 4; + uint32_t tzc_rom0_r0_lock : 1; // @ 24 -- 24 # 0xfeffffff + uint32_t tzc_rom0_r1_lock : 1; // @ 25 -- 25 # 0xfdffffff + uint32_t tzc_rom1_r0_lock : 1; // @ 26 -- 26 # 0xfbffffff + uint32_t tzc_rom1_r1_lock : 1; // @ 27 -- 27 # 0xf7ffffff + uint32_t tzc_sboot_done : 4; // @ 31 -- 28 # 0xfffffff + }; + } tzc_rom_ctrl; // @ 0x40 + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r0_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom0_r0_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom0_r0; // @ 0x44 + union { + uint32_t value; + struct { + uint32_t tzc_rom0_r1_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom0_r1_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom0_r1; // @ 0x48 + union { + uint32_t value; + struct { + uint32_t tzc_rom1_r0_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom1_r0_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom1_r0; // @ 0x4c + union { + uint32_t value; + struct { + uint32_t tzc_rom1_r1_end : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t tzc_rom1_r1_start : 16; // @ 31 -- 16 # 0xffff + }; + } tzc_rom1_r1; // @ 0x50 + }; +} tzc_sec_regs; +#define TZC_SEC_BASE 0x40005000 +#define TZC_SEC ((volatile tzc_sec_regs*)(TZC_SEC_BASE)) +#endif \ No newline at end of file diff --git a/src/include/soc/uart.h b/src/include/soc/uart.h new file mode 100644 index 0000000..a0bbc9d --- /dev/null +++ b/src/include/soc/uart.h @@ -0,0 +1,194 @@ +#ifndef UART_BASE +typedef union { + uint32_t regs[0x400]; + uint8_t pad[0x1000]; + struct { + union { + uint32_t value; + struct { + uint32_t cr_utx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_utx_cts_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_utx_frm_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t pad0 : 1; + uint32_t cr_utx_prt_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_utx_prt_sel : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_utx_ir_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t cr_utx_ir_inv : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t cr_utx_bit_cnt_d : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t pad1 : 1; + uint32_t cr_utx_bit_cnt_p : 2; // @ 13 -- 12 # 0xffffcfff + uint32_t pad2 : 2; + uint32_t cr_utx_len : 16; // @ 31 -- 16 # 0xffff + }; + } utx_config; // @ 0x0 + union { + uint32_t value; + struct { + uint32_t cr_urx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_urx_rts_sw_mode : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_urx_rts_sw_val : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_urx_abr_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_urx_prt_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_urx_prt_sel : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_urx_ir_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t cr_urx_ir_inv : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t cr_urx_bit_cnt_d : 3; // @ 10 -- 8 # 0xfffff8ff + uint32_t cr_urx_deg_en : 1; // @ 11 -- 11 # 0xfffff7ff + uint32_t cr_urx_deg_cnt : 4; // @ 15 -- 12 # 0xffff0fff + uint32_t cr_urx_len : 16; // @ 31 -- 16 # 0xffff + }; + } urx_config; // @ 0x4 + union { + uint32_t value; + struct { + uint32_t cr_utx_bit_prd : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t cr_urx_bit_prd : 16; // @ 31 -- 16 # 0xffff + }; + } uart_bit_prd; // @ 0x8 + union { + uint32_t value; + struct { + uint32_t cr_uart_bit_inv : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t pad0 : 31; + }; + } data_config; // @ 0xc + union { + uint32_t value; + struct { + uint32_t cr_utx_ir_pos_s : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t cr_utx_ir_pos_p : 16; // @ 31 -- 16 # 0xffff + }; + } utx_ir_position; // @ 0x10 + union { + uint32_t value; + struct { + uint32_t cr_urx_ir_pos_s : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t pad0 : 16; + }; + } urx_ir_position; // @ 0x14 + union { + uint32_t value; + struct { + uint32_t cr_urx_rto_value : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } urx_rto_timer; // @ 0x18 + uint8_t pad0[0x4]; + union { + uint32_t value; + struct { + uint32_t utx_end_int : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t urx_end_int : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t utx_fifo_int : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t urx_fifo_int : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t urx_rto_int : 1; // @ 4 -- 4 # 0xffffffef + uint32_t urx_pce_int : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t utx_fer_int : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t urx_fer_int : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } uart_int_sts; // @ 0x20 + union { + uint32_t value; + struct { + uint32_t cr_utx_end_mask : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_urx_end_mask : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_utx_fifo_mask : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_urx_fifo_mask : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_urx_rto_mask : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_urx_pce_mask : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_utx_fer_mask : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t cr_urx_fer_mask : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } uart_int_mask; // @ 0x24 + union { + uint32_t value; + struct { + uint32_t cr_utx_end_clr : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_urx_end_clr : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t rsvd_2 : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rsvd_3 : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_urx_rto_clr : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_urx_pce_clr : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rsvd_6 : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t rsvd_7 : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } uart_int_clear; // @ 0x28 + union { + uint32_t value; + struct { + uint32_t cr_utx_end_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t cr_urx_end_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t cr_utx_fifo_en : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t cr_urx_fifo_en : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t cr_urx_rto_en : 1; // @ 4 -- 4 # 0xffffffef + uint32_t cr_urx_pce_en : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t cr_utx_fer_en : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t cr_urx_fer_en : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } uart_int_en; // @ 0x2c + union { + uint32_t value; + struct { + uint32_t sts_utx_bus_busy : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t sts_urx_bus_busy : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t pad0 : 30; + }; + } uart_status; // @ 0x30 + union { + uint32_t value; + struct { + uint32_t sts_urx_abr_prd_start : 16; // @ 15 -- 0 # 0xffff0000 + uint32_t sts_urx_abr_prd_0x55 : 16; // @ 31 -- 16 # 0xffff + }; + } sts_urx_abr_prd; // @ 0x34 + uint8_t pad1[0x48]; + union { + uint32_t value; + struct { + uint32_t uart_dma_tx_en : 1; // @ 0 -- 0 # 0xfffffffe + uint32_t uart_dma_rx_en : 1; // @ 1 -- 1 # 0xfffffffd + uint32_t tx_fifo_clr : 1; // @ 2 -- 2 # 0xfffffffb + uint32_t rx_fifo_clr : 1; // @ 3 -- 3 # 0xfffffff7 + uint32_t tx_fifo_overflow : 1; // @ 4 -- 4 # 0xffffffef + uint32_t tx_fifo_underflow : 1; // @ 5 -- 5 # 0xffffffdf + uint32_t rx_fifo_overflow : 1; // @ 6 -- 6 # 0xffffffbf + uint32_t rx_fifo_underflow : 1; // @ 7 -- 7 # 0xffffff7f + uint32_t pad0 : 24; + }; + } uart_fifo_config_0; // @ 0x80 + union { + uint32_t value; + struct { + uint32_t tx_fifo_cnt : 6; // @ 5 -- 0 # 0xffffffc0 + uint32_t pad0 : 2; + uint32_t rx_fifo_cnt : 6; // @ 13 -- 8 # 0xffffc0ff + uint32_t pad1 : 2; + uint32_t tx_fifo_th : 5; // @ 20 -- 16 # 0xffe0ffff + uint32_t pad2 : 3; + uint32_t rx_fifo_th : 5; // @ 28 -- 24 # 0xe0ffffff + uint32_t pad3 : 3; + }; + } uart_fifo_config_1; // @ 0x84 + union { + uint32_t value; + struct { + uint32_t uart_fifo_wdata : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } uart_fifo_wdata; // @ 0x88 + union { + uint32_t value; + struct { + uint32_t uart_fifo_rdata : 8; // @ 7 -- 0 # 0xffffff00 + uint32_t pad0 : 24; + }; + } uart_fifo_rdata; // @ 0x8c + }; +} uart_regs; +#define UART_BASE 0x4000a000 +#define UART ((volatile uart_regs*)(UART_BASE)) +#endif \ No newline at end of file diff --git a/src/include/stdint.h b/src/include/stdint.h index 866d0cb..e9755d5 100644 --- a/src/include/stdint.h +++ b/src/include/stdint.h @@ -7,8 +7,9 @@ typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; typedef signed char int8_t; -typedef short intint16_t; +typedef short int16_t; typedef int int32_t; typedef long long int int64_t; - +//typedef uint8_t bool; +#include #endif \ No newline at end of file diff --git a/src/include/utils.h b/src/include/utils.h new file mode 100644 index 0000000..5e462bd --- /dev/null +++ b/src/include/utils.h @@ -0,0 +1,13 @@ +#ifndef __UTILS_H_ +#define ABS(x) (((x) > 0) ? (x) : (-(x))) +#define MIN(x,y) (((x) > (y)) ? (y) : (x)) +#define MAX(x,y) (((x) < (y)) ? (y) : (x)) +int puts(char *s); +int printf(const char *fmt,...); +void* memset(void *, int, unsigned int); +void* memcpy(void*, const void*, unsigned int); +int memcmp(const void *, const void *, unsigned int); +void BL602_Delay_US(uint32_t cnt); +void BL602_Delay_MS(uint32_t cnt); +unsigned int strlen(const char *__s); +#endif \ No newline at end of file diff --git a/src/include/utils/utils_tlv_bl.h b/src/include/utils/utils_tlv_bl.h new file mode 100644 index 0000000..f6f2380 --- /dev/null +++ b/src/include/utils/utils_tlv_bl.h @@ -0,0 +1,26 @@ +#ifndef __UTILS_TLV_BL_H__ +#define __UTILS_TLV_BL_H__ + +enum CFG_ELEMENT_TYPE { + CFG_ELEMENT_TYPE_UNKNOWN = 0, + CFG_ELEMENT_TYPE_BOOLEAN = 1, + CFG_ELEMENT_TYPE_SINT8 = 2, + CFG_ELEMENT_TYPE_UINT8 = 3, + CFG_ELEMENT_TYPE_SINT16 = 4, + CFG_ELEMENT_TYPE_UINT16 = 5, + CFG_ELEMENT_TYPE_SINT32 = 6, + CFG_ELEMENT_TYPE_UINT32 = 7, + CFG_ELEMENT_TYPE_STRING = 8 +}; + +enum CFG_ELEMENT_TYPE_OPS { + CFG_ELEMENT_TYPE_OPS_SET = 0, + CFG_ELEMENT_TYPE_OPS_GET = 1, + CFG_ELEMENT_TYPE_OPS_RESET = 2, + CFG_ELEMENT_TYPE_OPS_DUMP_DEBUG = 3, + CFG_ELEMENT_TYPE_OPS_UNKNOWN = 4 +}; + +void utils_tlv_bl_unpack_auto(void); + +#endif // __UTILS_TLV_BL_H__ diff --git a/src/svd/intc.svd b/src/svd/intc.svd new file mode 100644 index 0000000..a27c293 --- /dev/null +++ b/src/svd/intc.svd @@ -0,0 +1,65 @@ + + intc + intc. + 0x44910000 + intc + 32 + read-write + + 0 + 0x1000 + registers + + + + irq_status%s + irq_status. + 0x0 + 16 + 2 + 4 + 0-1 + + + irq_raw_status%s + irq_raw_status. + 0x8 + 16 + 2 + 4 + 0-1 + + + irq_unmask_set%s + irq_unmask_set. + 0x10 + 16 + 2 + 4 + 0-1 + + + irq_unmask_clear%s + irq_unmask_clear. + 0x18 + 16 + 2 + 4 + 0-1 + + + irq_polarity%s + irq_polarity. + 0x20 + 16 + 2 + 4 + 0-1 + + + irq_index + irq_index. + 0x40 + + + \ No newline at end of file diff --git a/src/svd/ipc.svd b/src/svd/ipc.svd index 011f109..75bc770 100644 --- a/src/svd/ipc.svd +++ b/src/svd/ipc.svd @@ -12,88 +12,258 @@ - APP2EMB_TRIGGER - APP2EMB_TRIGGER. + app2emb_trigger + app2emb_trigger. 0x0 - - - APP2EMB_TRIGGER - 31 - 0 - - - EMB2APP_RAWSTATUS - EMB2APP_RAWSTATUS. + emb2app_rawstatus + emb2app_rawstatus. 0x4 - - - EMB2APP_RAWSTATUS - 31 - 0 - - - EMB2APP_ACK - EMB2APP_ACK. + emb2app_ack + emb2app_ack. 0x8 - - - EMB2APP_ACK - 31 - 0 - - - EMB2APP_UNMASK_SET - EMB2APP_UNMASK_SET. + emb2app_unmask_set + emb2app_unmask_set. 0xc - - - EMB2APP_UNMASK - 31 - 0 - - - EMB2APP_UNMASK_CLEAR - EMB2APP_UNMASK_CLEAR. + emb2app_unmask_clear + emb2app_unmask_clear. 0x10 + + + emb2app_line_sel_low + emb2app_line_sel_low. + 0x14 - EMB2APP_UNMASK + emb2app15_sel 31 + 30 + + + emb2app14_sel + 29 + 28 + + + emb2app13_sel + 27 + 26 + + + emb2app12_sel + 25 + 24 + + + emb2app11_sel + 23 + 22 + + + emb2app10_sel + 21 + 20 + + + emb2app9_sel + 19 + 18 + + + emb2app8_sel + 17 + 16 + + + emb2app7_sel + 15 + 14 + + + emb2app6_sel + 13 + 12 + + + emb2app5_sel + 11 + 10 + + + emb2app4_sel + 9 + 8 + + + emb2app3_sel + 7 + 6 + + + emb2app2_sel + 5 + 4 + + + emb2app1_sel + 3 + 2 + + + emb2app0_sel + 1 0 - EMB2APP_STATUS - EMB2APP_STATUS. + emb2app_line_sel_high + emb2app_line_sel_high. + 0x18 + + + emb2app_status + emb2app_status. 0x1c - - - EMB2APP_STATUS - 31 - 0 - - - APP_SIGNATURE - APP_SIGNATURE. + app_signature + app_signature. 0x40 + + + emb2app_trigger + emb2app_trigger. + 0x100 + + + app2emb_rawstatus + app2emb_rawstatus. + 0x104 + + + app2emb_ack + app2emb_ack. + 0x108 + + + app2emb_unmask_set + app2emb_unmask_set. + 0x10c + + + app2emb_unmask_clear + app2emb_unmask_clear. + 0x110 + + + app2emb_line_sel_low + app2emb_line_sel_low. + 0x114 - APP_SIGNATURE + app2emb15_sel 31 + 30 + + + app2emb14_sel + 29 + 28 + + + app2emb13_sel + 27 + 26 + + + app2emb12_sel + 25 + 24 + + + app2emb11_sel + 23 + 22 + + + app2emb10_sel + 21 + 20 + + + app2emb9_sel + 19 + 18 + + + app2emb8_sel + 17 + 16 + + + app2emb7_sel + 15 + 14 + + + app2emb6_sel + 13 + 12 + + + app2emb5_sel + 11 + 10 + + + app2emb4_sel + 9 + 8 + + + app2emb3_sel + 7 + 6 + + + app2emb2_sel + 5 + 4 + + + app2emb1_sel + 3 + 2 + + + app2emb0_sel + 1 0 + + app2emb_line_sel_high + app2emb_line_sel_high. + 0x118 + + + app2emb_status + app2emb_status. + 0x11c + + + emb_signature + emb_signature. + 0x140 + \ No newline at end of file diff --git a/src/svd/mac_core.svd b/src/svd/mac_core.svd index d535852..5dc1014 100644 --- a/src/svd/mac_core.svd +++ b/src/svd/mac_core.svd @@ -952,6 +952,33 @@ + + encr_ram_config + encr_ram_config. + 0xd8 + + + max + 31 + 24 + + + nVAP + 23 + 16 + + + end + 15 + 8 + + + start + 7 + 0 + + + RATES RATES. @@ -1284,16 +1311,13 @@ - ABS_TIMER + ABS_TIMER%s ABS_TIMER. 0x128 - - - absTimerValue - 31 - 0 - - + 16 + 10 + 4 + 0-9 MAX_RX_LENGTH @@ -1784,6 +1808,21 @@ COEX_CONTROL. 0x400 + + coexForceWlanPti + 31 + 28 + + + coexForceWlanPtiToggle + 27 + 27 + + + coexForceWlanChanBw + 26 + 26 + coexWlanChanFreq 22 @@ -1794,6 +1833,16 @@ 12 12 + + coexAutoPTIAdjEnable + 5 + 5 + + + coexForceEnable + 4 + 4 + coexEnable 0 @@ -1848,6 +1897,11 @@ + + coex_stat + coex_stat. + 0x408 + DEBUG_HWSM_1 DEBUG_HWSM_1. diff --git a/src/svd/sysctrl.svd b/src/svd/sysctrl.svd index 62a2ed8..f3a944e 100644 --- a/src/svd/sysctrl.svd +++ b/src/svd/sysctrl.svd @@ -23,6 +23,11 @@ + + diag_trigger + diag_trigger. + 0x70 + r074 r074.