project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
238 lines
8.7 KiB
C
238 lines
8.7 KiB
C
/**
|
|
****************************************************************************************
|
|
*
|
|
* @file rwnx_configparse.c
|
|
*
|
|
* Copyright (C) RivieraWaves 2012-2019
|
|
*
|
|
****************************************************************************************
|
|
*/
|
|
#include <linux/firmware.h>
|
|
#include <linux/if_ether.h>
|
|
|
|
#include "rwnx_defs.h"
|
|
#include "rwnx_cfgfile.h"
|
|
|
|
/**
|
|
*
|
|
*/
|
|
static const char *rwnx_find_tag(const u8 *file_data, unsigned int file_size,
|
|
const char *tag_name, unsigned int tag_len)
|
|
{
|
|
unsigned int curr, line_start = 0, line_size;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
/* Walk through all the lines of the configuration file */
|
|
while (line_start < file_size) {
|
|
/* Search the end of the current line (or the end of the file) */
|
|
for (curr = line_start; curr < file_size; curr++)
|
|
if (file_data[curr] == '\n')
|
|
break;
|
|
|
|
/* Compute the line size */
|
|
line_size = curr - line_start;
|
|
|
|
/* Check if this line contains the expected tag */
|
|
if ((line_size == (strlen(tag_name) + tag_len)) &&
|
|
(!strncmp(&file_data[line_start], tag_name, strlen(tag_name))))
|
|
return (&file_data[line_start + strlen(tag_name)]);
|
|
|
|
/* Move to next line */
|
|
line_start = curr + 1;
|
|
}
|
|
|
|
/* Tag not found */
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Parse the Config file used at init time
|
|
*/
|
|
int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
|
struct rwnx_conf_file *config)
|
|
{
|
|
const struct firmware *config_fw;
|
|
u8 dflt_mac[ETH_ALEN] = { 0, 111, 111, 111, 111, 0 };
|
|
int ret;
|
|
const u8 *tag_ptr;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
if ((ret = request_firmware(&config_fw, filename, rwnx_hw->dev))) {
|
|
printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
|
|
return ret;
|
|
}
|
|
|
|
/* Get MAC Address */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"MAC_ADDR=", strlen("00:00:00:00:00:00"));
|
|
if (tag_ptr != NULL) {
|
|
u8 *addr = config->mac_addr;
|
|
if (sscanf(tag_ptr,
|
|
"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
|
addr + 0, addr + 1, addr + 2,
|
|
addr + 3, addr + 4, addr + 5) != ETH_ALEN)
|
|
memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
|
|
} else
|
|
memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
|
|
|
|
RWNX_DBG("MAC Address is:\n%pM\n", config->mac_addr);
|
|
|
|
/* Release the configuration file */
|
|
release_firmware(config_fw);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Parse the Config file used at init time
|
|
*/
|
|
int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
|
|
struct rwnx_phy_conf_file *config, int path)
|
|
{
|
|
const struct firmware *config_fw;
|
|
int ret;
|
|
const u8 *tag_ptr;
|
|
|
|
RWNX_DBG(RWNX_FN_ENTRY_STR);
|
|
|
|
if ((ret = request_firmware(&config_fw, filename, rwnx_hw->dev))) {
|
|
printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
|
|
return ret;
|
|
}
|
|
|
|
/* Get Trident path mapping */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"TRD_PATH_MAPPING=", strlen("00"));
|
|
if (tag_ptr != NULL) {
|
|
u8 val;
|
|
if (sscanf(tag_ptr, "%hhx", &val) == 1)
|
|
config->trd.path_mapping = val;
|
|
else
|
|
config->trd.path_mapping = path;
|
|
} else
|
|
config->trd.path_mapping = path;
|
|
|
|
RWNX_DBG("Trident path mapping is: %d\n", config->trd.path_mapping);
|
|
|
|
/* Get DC offset compensation */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"TX_DC_OFF_COMP=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1)
|
|
config->trd.tx_dc_off_comp = 0;
|
|
} else
|
|
config->trd.tx_dc_off_comp = 0;
|
|
|
|
RWNX_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp);
|
|
|
|
/* Get Karst TX IQ compensation value for path0 on 2.4GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1)
|
|
config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
|
|
} else
|
|
config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]);
|
|
|
|
/* Get Karst TX IQ compensation value for path1 on 2.4GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1)
|
|
config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
|
|
} else
|
|
config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]);
|
|
|
|
/* Get Karst RX IQ compensation value for path0 on 2.4GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1)
|
|
config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
|
|
} else
|
|
config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]);
|
|
|
|
/* Get Karst RX IQ compensation value for path1 on 2.4GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1)
|
|
config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
|
|
} else
|
|
config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]);
|
|
|
|
/* Get Karst TX IQ compensation value for path0 on 5GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1)
|
|
config->karst.tx_iq_comp_5G[0] = 0x01000000;
|
|
} else
|
|
config->karst.tx_iq_comp_5G[0] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]);
|
|
|
|
/* Get Karst TX IQ compensation value for path1 on 5GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1)
|
|
config->karst.tx_iq_comp_5G[1] = 0x01000000;
|
|
} else
|
|
config->karst.tx_iq_comp_5G[1] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]);
|
|
|
|
/* Get Karst RX IQ compensation value for path0 on 5GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1)
|
|
config->karst.rx_iq_comp_5G[0] = 0x01000000;
|
|
} else
|
|
config->karst.rx_iq_comp_5G[0] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]);
|
|
|
|
/* Get Karst RX IQ compensation value for path1 on 5GHz */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
|
|
if (tag_ptr != NULL) {
|
|
if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1)
|
|
config->karst.rx_iq_comp_5G[1] = 0x01000000;
|
|
} else
|
|
config->karst.rx_iq_comp_5G[1] = 0x01000000;
|
|
|
|
RWNX_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]);
|
|
|
|
/* Get Karst default path */
|
|
tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
|
|
"KARST_DEFAULT_PATH=", strlen("00"));
|
|
if (tag_ptr != NULL) {
|
|
u8 val;
|
|
if (sscanf(tag_ptr, "%hhx", &val) == 1)
|
|
config->karst.path_used = val;
|
|
else
|
|
config->karst.path_used = path;
|
|
} else
|
|
config->karst.path_used = path;
|
|
|
|
RWNX_DBG("Karst default path is: %d\n", config->karst.path_used);
|
|
|
|
/* Release the configuration file */
|
|
release_firmware(config_fw);
|
|
|
|
return 0;
|
|
}
|
|
|