2 ****************************************************************************************
4 * @file ecrnx_configparse.c
6 * Copyright (C) ESWIN 2015-2020
8 ****************************************************************************************
10 #include <linux/firmware.h>
11 #include <linux/if_ether.h>
13 #include "ecrnx_defs.h"
14 #include "ecrnx_cfgfile.h"
15 #include "ecrnx_debug.h"
16 #include "ecrnx_debugfs_func.h"
21 static const char *ecrnx_find_tag(const u8 *file_data, unsigned int file_size,
22 const char *tag_name, unsigned int tag_len)
24 unsigned int curr, line_start = 0, line_size;
26 ECRNX_DBG(ECRNX_FN_ENTRY_STR);
28 /* Walk through all the lines of the configuration file */
29 while (line_start < file_size) {
30 /* Search the end of the current line (or the end of the file) */
31 for (curr = line_start; curr < file_size; curr++)
32 if (file_data[curr] == '\n')
35 /* Compute the line size */
36 line_size = curr - line_start;
38 /* Check if this line contains the expected tag */
39 if ((line_size == (strlen(tag_name) + tag_len)) &&
40 (!strncmp(&file_data[line_start], tag_name, strlen(tag_name))))
41 return (&file_data[line_start + strlen(tag_name)]);
43 /* Move to next line */
44 line_start = curr + 1;
52 * Parse the Config file used at init time
54 int ecrnx_parse_configfile(struct ecrnx_hw *ecrnx_hw, const char *filename)
56 const struct firmware *config_fw;
57 u8 dflt_mac[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x5f };
60 bool mac_flag = false, dbg_level_flag = false, fw_log_lv_flag = false, fw_log_type_flag = false;
62 ECRNX_DBG(ECRNX_FN_ENTRY_STR);
63 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
64 ret = firmware_request_nowarn(&config_fw, filename, ecrnx_hw->dev); //avoid the files not exit error
66 ret = request_firmware(&config_fw, filename, ecrnx_hw->dev);
71 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size, "MAC_ADDR=", strlen("00:00:00:00:00:00"));
72 if (tag_ptr != NULL) {
73 u8 *addr = ecrnx_hw->conf_param.mac_addr;
74 if (sscanf(tag_ptr, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
75 addr + 0, addr + 1, addr + 2,
76 addr + 3, addr + 4, addr + 5) == ETH_ALEN){
81 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size, "DRIVER_LOG_LEVEL=", strlen("0"));
83 if(sscanf(tag_ptr, "%hhx", &ecrnx_hw->conf_param.host_driver_log_level) == 1){
84 ecrnx_dbg_level = ecrnx_hw->conf_param.host_driver_log_level;
85 dbg_level_flag = true;
89 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size, "FW_LOG_LEVEL=", strlen("0"));
91 if(sscanf(tag_ptr, "%hhx", &ecrnx_hw->conf_param.fw_log_level) == 1){
92 fw_log_lv_flag = true;
96 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size, "FW_LOG_TYPE=", strlen("0"));
98 if(sscanf(tag_ptr, "%hhx", &ecrnx_hw->conf_param.fw_log_type) == 1){
99 fw_log_type_flag = true;
103 /* Release the configuration file */
104 release_firmware(config_fw);
108 memcpy(ecrnx_hw->conf_param.mac_addr, dflt_mac, ETH_ALEN);
112 ecrnx_hw->conf_param.host_driver_log_level = ecrnx_dbg_level;
116 ecrnx_hw->conf_param.fw_log_level = log_ctl.level;
119 if(!fw_log_type_flag){
120 ecrnx_hw->conf_param.fw_log_type = log_ctl.dir;
123 ECRNX_PRINT("MAC Address is:%pM\n", ecrnx_hw->conf_param.mac_addr);
124 ECRNX_PRINT("host driver log level is:%d \n", ecrnx_hw->conf_param.host_driver_log_level);
125 ECRNX_PRINT("firmware log level is:%d \n", ecrnx_hw->conf_param.fw_log_level);
127 if(0 == ecrnx_hw->conf_param.fw_log_type){
128 ECRNX_PRINT("firmware log level type:%d (print to chip's uart) \n", ecrnx_hw->conf_param.fw_log_type);
129 }else if(1 == ecrnx_hw->conf_param.fw_log_type){
130 ECRNX_PRINT("firmware log level type:%d (print to host debugfs) \n", ecrnx_hw->conf_param.fw_log_type);
131 }else if(2 == ecrnx_hw->conf_param.fw_log_type){
132 ECRNX_PRINT("firmware log level type:%d (print to host kernel) \n", ecrnx_hw->conf_param.fw_log_type);
134 ECRNX_ERR("firmware log level type error;\n");
140 * Parse the Config file used at init time
142 int ecrnx_parse_phy_configfile(struct ecrnx_hw *ecrnx_hw, const char *filename,
143 struct ecrnx_phy_conf_file *config, int path)
145 const struct firmware *config_fw;
149 ECRNX_DBG(ECRNX_FN_ENTRY_STR);
151 if ((ret = request_firmware(&config_fw, filename, ecrnx_hw->dev))) {
152 ECRNX_ERR(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
156 /* Get Trident path mapping */
157 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
158 "TRD_PATH_MAPPING=", strlen("00"));
159 if (tag_ptr != NULL) {
161 if (sscanf(tag_ptr, "%hhx", &val) == 1)
162 config->trd.path_mapping = val;
164 config->trd.path_mapping = path;
166 config->trd.path_mapping = path;
168 ECRNX_DBG("Trident path mapping is: %d\n", config->trd.path_mapping);
170 /* Get DC offset compensation */
171 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
172 "TX_DC_OFF_COMP=", strlen("00000000"));
173 if (tag_ptr != NULL) {
174 if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1)
175 config->trd.tx_dc_off_comp = 0;
177 config->trd.tx_dc_off_comp = 0;
179 ECRNX_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp);
181 /* Get Karst TX IQ compensation value for path0 on 2.4GHz */
182 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
183 "KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
184 if (tag_ptr != NULL) {
185 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1)
186 config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
188 config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
190 ECRNX_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]);
192 /* Get Karst TX IQ compensation value for path1 on 2.4GHz */
193 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
194 "KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
195 if (tag_ptr != NULL) {
196 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1)
197 config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
199 config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
201 ECRNX_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]);
203 /* Get Karst RX IQ compensation value for path0 on 2.4GHz */
204 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
205 "KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
206 if (tag_ptr != NULL) {
207 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1)
208 config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
210 config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
212 ECRNX_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]);
214 /* Get Karst RX IQ compensation value for path1 on 2.4GHz */
215 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
216 "KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
217 if (tag_ptr != NULL) {
218 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1)
219 config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
221 config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
223 ECRNX_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]);
225 /* Get Karst TX IQ compensation value for path0 on 5GHz */
226 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
227 "KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
228 if (tag_ptr != NULL) {
229 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1)
230 config->karst.tx_iq_comp_5G[0] = 0x01000000;
232 config->karst.tx_iq_comp_5G[0] = 0x01000000;
234 ECRNX_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]);
236 /* Get Karst TX IQ compensation value for path1 on 5GHz */
237 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
238 "KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
239 if (tag_ptr != NULL) {
240 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1)
241 config->karst.tx_iq_comp_5G[1] = 0x01000000;
243 config->karst.tx_iq_comp_5G[1] = 0x01000000;
245 ECRNX_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]);
247 /* Get Karst RX IQ compensation value for path0 on 5GHz */
248 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
249 "KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
250 if (tag_ptr != NULL) {
251 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1)
252 config->karst.rx_iq_comp_5G[0] = 0x01000000;
254 config->karst.rx_iq_comp_5G[0] = 0x01000000;
256 ECRNX_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]);
258 /* Get Karst RX IQ compensation value for path1 on 5GHz */
259 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
260 "KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
261 if (tag_ptr != NULL) {
262 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1)
263 config->karst.rx_iq_comp_5G[1] = 0x01000000;
265 config->karst.rx_iq_comp_5G[1] = 0x01000000;
267 ECRNX_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]);
269 /* Get Karst default path */
270 tag_ptr = ecrnx_find_tag(config_fw->data, config_fw->size,
271 "KARST_DEFAULT_PATH=", strlen("00"));
272 if (tag_ptr != NULL) {
274 if (sscanf(tag_ptr, "%hhx", &val) == 1)
275 config->karst.path_used = val;
277 config->karst.path_used = path;
279 config->karst.path_used = path;
281 ECRNX_DBG("Karst default path is: %d\n", config->karst.path_used);
283 /* Release the configuration file */
284 release_firmware(config_fw);