blob: 39a5a251482abf8512f98899c3c562c45a0618dc [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/**
2 ****************************************************************************************
3 *
4 * @file rwnx_configparse.c
5 *
6 * Copyright (C) RivieraWaves 2012-2019
7 *
8 ****************************************************************************************
9 */
10#include <linux/firmware.h>
11#include <linux/if_ether.h>
12
13#include "rwnx_defs.h"
14#include "rwnx_cfgfile.h"
15
16/**
17 *
18 */
19static const char *rwnx_find_tag(const u8 *file_data, unsigned int file_size,
20 const char *tag_name, unsigned int tag_len)
21{
22 unsigned int curr, line_start = 0, line_size;
23
24 RWNX_DBG(RWNX_FN_ENTRY_STR);
25
26 /* Walk through all the lines of the configuration file */
27 while (line_start < file_size) {
28 /* Search the end of the current line (or the end of the file) */
29 for (curr = line_start; curr < file_size; curr++)
30 if (file_data[curr] == '\n')
31 break;
32
33 /* Compute the line size */
34 line_size = curr - line_start;
35
36 /* Check if this line contains the expected tag */
37 if ((line_size == (strlen(tag_name) + tag_len)) &&
38 (!strncmp(&file_data[line_start], tag_name, strlen(tag_name))))
39 return &file_data[line_start + strlen(tag_name)];
40
41 /* Move to next line */
42 line_start = curr + 1;
43 }
44
45 /* Tag not found */
46 return NULL;
47}
48
49/**
50 * Parse the Config file used at init time
51 */
52int rwnx_parse_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
53 struct rwnx_conf_file *config)
54{
55 const struct firmware *config_fw;
56 u8 dflt_mac[ETH_ALEN] = { 0, 111, 111, 111, 111, 0 };
57 int ret;
58 const u8 *tag_ptr;
59
60 RWNX_DBG(RWNX_FN_ENTRY_STR);
61
62 ret = request_firmware(&config_fw, filename, rwnx_hw->dev);
63 if (ret) {
64 printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
65 return ret;
66 }
67
68 /* Get MAC Address */
69 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
70 "MAC_ADDR=", strlen("00:00:00:00:00:00"));
71 if (tag_ptr != NULL) {
72 u8 *addr = config->mac_addr;
73 if (sscanf(tag_ptr,
74 "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
75 addr + 0, addr + 1, addr + 2,
76 addr + 3, addr + 4, addr + 5) != ETH_ALEN)
77 memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
78 } else
79 memcpy(config->mac_addr, dflt_mac, ETH_ALEN);
80
81 RWNX_DBG("MAC Address is:\n%pM\n", config->mac_addr);
82
83 /* Release the configuration file */
84 release_firmware(config_fw);
85
86 return 0;
87}
88
89/**
90 * Parse the Config file used at init time
91 */
92int rwnx_parse_phy_configfile(struct rwnx_hw *rwnx_hw, const char *filename,
93 struct rwnx_phy_conf_file *config, int path)
94{
95 const struct firmware *config_fw;
96 int ret;
97 const u8 *tag_ptr;
98
99 RWNX_DBG(RWNX_FN_ENTRY_STR);
100
101 ret = request_firmware(&config_fw, filename, rwnx_hw->dev);
102 if (ret) {
103 printk(KERN_CRIT "%s: Failed to get %s (%d)\n", __func__, filename, ret);
104 return ret;
105 }
106
107 /* Get Trident path mapping */
108 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
109 "TRD_PATH_MAPPING=", strlen("00"));
110 if (tag_ptr != NULL) {
111 u8 val;
112 if (sscanf(tag_ptr, "%hhx", &val) == 1)
113 config->trd.path_mapping = val;
114 else
115 config->trd.path_mapping = path;
116 } else
117 config->trd.path_mapping = path;
118
119 RWNX_DBG("Trident path mapping is: %d\n", config->trd.path_mapping);
120
121 /* Get DC offset compensation */
122 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
123 "TX_DC_OFF_COMP=", strlen("00000000"));
124 if (tag_ptr != NULL) {
125 if (sscanf(tag_ptr, "%08x", &config->trd.tx_dc_off_comp) != 1)
126 config->trd.tx_dc_off_comp = 0;
127 } else
128 config->trd.tx_dc_off_comp = 0;
129
130 RWNX_DBG("TX DC offset compensation is: %08X\n", config->trd.tx_dc_off_comp);
131
132 /* Get Karst TX IQ compensation value for path0 on 2.4GHz */
133 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
134 "KARST_TX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
135 if (tag_ptr != NULL) {
136 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[0]) != 1)
137 config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
138 } else
139 config->karst.tx_iq_comp_2_4G[0] = 0x01000000;
140
141 RWNX_DBG("Karst TX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[0]);
142
143 /* Get Karst TX IQ compensation value for path1 on 2.4GHz */
144 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
145 "KARST_TX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
146 if (tag_ptr != NULL) {
147 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_2_4G[1]) != 1)
148 config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
149 } else
150 config->karst.tx_iq_comp_2_4G[1] = 0x01000000;
151
152 RWNX_DBG("Karst TX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.tx_iq_comp_2_4G[1]);
153
154 /* Get Karst RX IQ compensation value for path0 on 2.4GHz */
155 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
156 "KARST_RX_IQ_COMP_2_4G_PATH_0=", strlen("00000000"));
157 if (tag_ptr != NULL) {
158 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[0]) != 1)
159 config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
160 } else
161 config->karst.rx_iq_comp_2_4G[0] = 0x01000000;
162
163 RWNX_DBG("Karst RX IQ compensation for path 0 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[0]);
164
165 /* Get Karst RX IQ compensation value for path1 on 2.4GHz */
166 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
167 "KARST_RX_IQ_COMP_2_4G_PATH_1=", strlen("00000000"));
168 if (tag_ptr != NULL) {
169 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_2_4G[1]) != 1)
170 config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
171 } else
172 config->karst.rx_iq_comp_2_4G[1] = 0x01000000;
173
174 RWNX_DBG("Karst RX IQ compensation for path 1 on 2.4GHz is: %08X\n", config->karst.rx_iq_comp_2_4G[1]);
175
176 /* Get Karst TX IQ compensation value for path0 on 5GHz */
177 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
178 "KARST_TX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
179 if (tag_ptr != NULL) {
180 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[0]) != 1)
181 config->karst.tx_iq_comp_5G[0] = 0x01000000;
182 } else
183 config->karst.tx_iq_comp_5G[0] = 0x01000000;
184
185 RWNX_DBG("Karst TX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[0]);
186
187 /* Get Karst TX IQ compensation value for path1 on 5GHz */
188 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
189 "KARST_TX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
190 if (tag_ptr != NULL) {
191 if (sscanf(tag_ptr, "%08x", &config->karst.tx_iq_comp_5G[1]) != 1)
192 config->karst.tx_iq_comp_5G[1] = 0x01000000;
193 } else
194 config->karst.tx_iq_comp_5G[1] = 0x01000000;
195
196 RWNX_DBG("Karst TX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.tx_iq_comp_5G[1]);
197
198 /* Get Karst RX IQ compensation value for path0 on 5GHz */
199 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
200 "KARST_RX_IQ_COMP_5G_PATH_0=", strlen("00000000"));
201 if (tag_ptr != NULL) {
202 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[0]) != 1)
203 config->karst.rx_iq_comp_5G[0] = 0x01000000;
204 } else
205 config->karst.rx_iq_comp_5G[0] = 0x01000000;
206
207 RWNX_DBG("Karst RX IQ compensation for path 0 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[0]);
208
209 /* Get Karst RX IQ compensation value for path1 on 5GHz */
210 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
211 "KARST_RX_IQ_COMP_5G_PATH_1=", strlen("00000000"));
212 if (tag_ptr != NULL) {
213 if (sscanf(tag_ptr, "%08x", &config->karst.rx_iq_comp_5G[1]) != 1)
214 config->karst.rx_iq_comp_5G[1] = 0x01000000;
215 } else
216 config->karst.rx_iq_comp_5G[1] = 0x01000000;
217
218 RWNX_DBG("Karst RX IQ compensation for path 1 on 5GHz is: %08X\n", config->karst.rx_iq_comp_5G[1]);
219
220 /* Get Karst default path */
221 tag_ptr = rwnx_find_tag(config_fw->data, config_fw->size,
222 "KARST_DEFAULT_PATH=", strlen("00"));
223 if (tag_ptr != NULL) {
224 u8 val;
225 if (sscanf(tag_ptr, "%hhx", &val) == 1)
226 config->karst.path_used = val;
227 else
228 config->karst.path_used = path;
229 } else
230 config->karst.path_used = path;
231
232 RWNX_DBG("Karst default path is: %d\n", config->karst.path_used);
233
234 /* Release the configuration file */
235 release_firmware(config_fw);
236
237 return 0;
238}
239