xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/hal_ld_file.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #define _HAL_LD_FILE_C_
16 #include "hal_headers.h"
17 #include "hal_ld_file.h"
18 
19 static int
_hal_parse_phyreg(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)20 _hal_parse_phyreg(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
21 {
22 	struct rtw_para_info_t *para_info = (struct rtw_para_info_t *)para_info_t;
23 	u32 *pdest_buf = para_info->para_data;
24 	char	*sz_line, *ptmp;
25 	u32 dest_buf_idx = 0;
26 	u32	u4bregoffset, u4bregvalue, u4bmove;
27 
28 	ptmp = (char *)psrc_buf;
29 
30 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL; sz_line = hal_getLinefrombuffer(ptmp)) {
31 		if (!hal_is_comment_string(sz_line)) {
32 			/* Get 1st hex value as register offset. */
33 			if (hal_get_hexvalue_fromstring(sz_line, &u4bregoffset, &u4bmove)) {
34 
35 				pdest_buf[dest_buf_idx] = u4bregoffset;
36 				dest_buf_idx++;
37 
38 				if (u4bregoffset == 0xffff) {
39 					/* Ending. */
40 					pdest_buf[dest_buf_idx] = 0xffff;
41 					PHL_INFO(" dest_buf_len: %d \n", dest_buf_idx);
42 					break;
43 				}
44 				/* Get 2nd hex value as register value. */
45 				sz_line += u4bmove;
46 				if (hal_get_hexvalue_fromstring(sz_line, &u4bregvalue, &u4bmove)) {
47 					/* PHL_INFO("[BB-ADDR]%03lX=%08lX\n", u4bregoffset, u4bregvalue); */
48 					pdest_buf[dest_buf_idx] = u4bregvalue;
49 					dest_buf_idx++;
50 				}
51 			}
52 		}
53 	}
54 #if 0
55 	{ /*debug dump buf*/
56 		u32 i = 0;
57 		for (i = 0; i <= dest_buf_idx; i+=2)
58 			PHL_INFO("[BB-ADDR] 0x%x :[0x%x]\n", pdest_buf[i], pdest_buf[i+1]);
59 	}
60 #endif
61 	return dest_buf_idx;
62 }
63 
phypg_combvalue_fromstring(char * sz_line)64 static u32 phypg_combvalue_fromstring(		char *sz_line)
65 {
66 	u32	u4bmove;
67 	u32 combvalue = 0;
68 	u8	integer = 0, fraction = 0;
69 	u8 txgi_pdbm = 4;
70 
71 	if (hal_get_fractionvalue_fromstring(sz_line, &integer, &fraction, &u4bmove))
72 		sz_line += u4bmove;
73 	else
74 		goto exit;
75 
76 	combvalue |= ((integer * txgi_pdbm) + (fraction * txgi_pdbm / 100));
77 
78 	if (hal_get_fractionvalue_fromstring(sz_line, &integer, &fraction, &u4bmove))
79 		sz_line += u4bmove;
80 	else
81 		goto exit;
82 
83 	combvalue <<= 8;
84 	combvalue |= ((integer * txgi_pdbm) + (fraction * txgi_pdbm / 100));
85 
86 	if (hal_get_fractionvalue_fromstring(sz_line, &integer, &fraction, &u4bmove))
87 		sz_line += u4bmove;
88 	else
89 		goto exit;
90 
91 	combvalue <<= 8;
92 	combvalue |= ((integer * txgi_pdbm) + (fraction * txgi_pdbm / 100));
93 
94 	if (hal_get_fractionvalue_fromstring(sz_line, &integer, &fraction, &u4bmove))
95 		sz_line += u4bmove;
96 	else
97 		goto exit;
98 
99 	combvalue <<= 8;
100 	combvalue |= ((integer * txgi_pdbm) + (fraction * txgi_pdbm / 100));
101 
102 	/*PHL_DBG("[combvalue 4] 0x%x , hex = %x\n", combvalue , integer);*/
103 exit:
104 	return combvalue;
105 }
106 
107 static int
_hal_parse_txpwr_by_rate(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)108 _hal_parse_txpwr_by_rate(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
109 {
110 	struct rtw_para_info_t *para_info = (struct rtw_para_info_t *)para_info_t;
111 	u32 *pdest_buf = para_info->para_data;
112 	char	*sz_line, *ptmp;
113 	u8	band = 0;
114 	u8 phy_reg_pg_version = 0;
115 	u8 phy_reg_pg_value_type = 0;
116 	u32 pwrhexval = 0;
117 	u32 line_idx = 0;
118 	u32 buf_idx = 0;
119 	bool firstline = true;
120 
121 	ptmp = (char*)psrc_buf;
122 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL; sz_line = hal_getLinefrombuffer(ptmp)) {
123 		if (hal_is_allspace_tab(sz_line, sizeof(*sz_line)))
124 			continue;
125 
126 		if (!hal_is_comment_string(sz_line)) {
127 			if (firstline) {
128 				if (_os_strncmp(sz_line, "#[v2]", 5) == 0
129 					|| _os_strncmp(sz_line, "#[v3]", 5) == 0) {
130 					phy_reg_pg_version = sz_line[3] - '0'; /* store pg version*/
131 					PHL_INFO("phy_reg_pg_version %d\n", phy_reg_pg_version);
132 				} else {
133 					PHL_ERR("The format in PHY_REG_PG are invalid %s\n", sz_line);
134 					goto exit;
135 				}
136 				if (_os_strncmp(sz_line + 5, "[Exact]#", 8) == 0) {
137 					phy_reg_pg_value_type = 1; /* store PHY_REG_PG_EXACT_VALUE*/
138 					firstline = false;
139 					PHL_INFO("REG_PG_EXACT_VALUE\n");
140 					continue;
141 				} else {
142 					PHL_ERR("The values in PHY_REG_PG are invalid %s\n", sz_line);
143 					goto exit;
144 				}
145 			}
146 			if (_os_strncmp(sz_line , "#[2.4G]#", 8) == 0) {
147 					band = 0;
148 					continue;
149 			}
150 			if (_os_strncmp(sz_line , "#[5G]#", 6) == 0) {
151 					band = 1;
152 					continue;
153 			}
154 			if ((_os_strncmp(sz_line , "#[START]#", 9) == 0) || (_os_strncmp(sz_line , "#[END]#", 9) == 0) ) {
155 					continue;
156 			}
157 			if (_os_strncmp(sz_line , "[Nss1]", 6) == 0) {
158 				line_idx = 0;
159 				pwrhexval = 0;
160 
161 				pdest_buf[buf_idx++] = band;
162 				pdest_buf[buf_idx++] = PHYPG_RF1Tx;
163 				line_idx += 6;
164 				PHL_INFO("[Line]%s , line_idx %d \n", sz_line, line_idx);
165 
166 				while (sz_line[line_idx] == ' ' || sz_line[line_idx] == '\0' || sz_line[line_idx] == '\t')
167 					++line_idx;
168 
169 				sz_line += line_idx;
170 				if (_os_strncmp(sz_line , "11M_1M", 6) == 0) {
171 					pdest_buf[buf_idx++] = CCK_11M_1M;
172 					sz_line += 6;
173 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
174 					pwrhexval = phypg_combvalue_fromstring(sz_line);
175 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
176 					pdest_buf[buf_idx++] = pwrhexval;
177 				} else if (_os_strncmp(sz_line , "18M_6M", 6) == 0) {
178 					pdest_buf[buf_idx++] = OFDM_18M_6M;
179 					sz_line += 6;
180 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
181 					pwrhexval = phypg_combvalue_fromstring(sz_line);
182 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
183 					pdest_buf[buf_idx++] = pwrhexval;
184 				} else if (_os_strncmp(sz_line , "54M_24M", 7) == 0) {
185 					pdest_buf[buf_idx++] = OFDM_54M_24M;
186 					sz_line += 7;
187 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
188 					pwrhexval = phypg_combvalue_fromstring(sz_line);
189 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
190 					pdest_buf[buf_idx++] = pwrhexval;
191 				} else if (_os_strncmp(sz_line , "MCS3_0", 6) == 0) {
192 					pdest_buf[buf_idx++] = HE1SS_MCS3_0;
193 					sz_line += 6;
194 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
195 					pwrhexval = phypg_combvalue_fromstring(sz_line);
196 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
197 					pdest_buf[buf_idx++] = pwrhexval;
198 				} else if (_os_strncmp(sz_line , "MCS7_4", 6) == 0) {
199 					pdest_buf[buf_idx++] = HE1SS_MCS7_4;
200 					sz_line += 6;
201 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
202 					pwrhexval = phypg_combvalue_fromstring(sz_line);
203 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
204 					pdest_buf[buf_idx++] = pwrhexval;
205 				} else if (_os_strncmp(sz_line , "MCS11_8", 6) == 0) {
206 					pdest_buf[buf_idx++] = HE1SS_MCS11_8;
207 					sz_line += 7;
208 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
209 					pwrhexval = phypg_combvalue_fromstring(sz_line);
210 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
211 					pdest_buf[buf_idx++] = pwrhexval;
212 				} else if (_os_strncmp(sz_line , "DCM4_0", 6) == 0) {
213 					pdest_buf[buf_idx++] = HE1SS_DCM4_0;
214 					sz_line += 6;
215 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
216 					pwrhexval = phypg_combvalue_fromstring(sz_line);
217 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
218 					pdest_buf[buf_idx++] = pwrhexval;
219 				}
220 			} else if (_os_strncmp(sz_line , "[Nss2]", 6) == 0) {
221 				line_idx = 0;
222 				pwrhexval = 0;
223 
224 				pdest_buf[buf_idx++] = band;
225 				pdest_buf[buf_idx++] = PHYPG_RF2Tx;
226 				PHL_INFO("[Line]%s , line_idx %d \n", sz_line, line_idx);
227 
228 				line_idx += 6;
229 				while (sz_line[line_idx] == ' ' || sz_line[line_idx] == '\0' || sz_line[line_idx] == '\t')
230 					++line_idx;
231 
232 				sz_line += line_idx;
233 				if (_os_strncmp(sz_line , "MCS3_0", 6) == 0) {
234 					pdest_buf[buf_idx++] = HE2SS_MCS3_0;
235 					sz_line += 6;
236 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
237 					pwrhexval = phypg_combvalue_fromstring(sz_line);
238 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
239 					pdest_buf[buf_idx++] = pwrhexval;
240 				} else if (_os_strncmp(sz_line , "MCS7_4", 6) == 0) {
241 					pdest_buf[buf_idx++] = HE2SS_MCS7_4;
242 					sz_line += 6;
243 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
244 					pwrhexval = phypg_combvalue_fromstring(sz_line);
245 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
246 					pdest_buf[buf_idx++] = pwrhexval;
247 				} else if (_os_strncmp(sz_line , "MCS11_8", 6) == 0) {
248 					pdest_buf[buf_idx++] = HE2SS_MCS11_8;
249 					sz_line += 7;
250 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
251 					pwrhexval = phypg_combvalue_fromstring(sz_line);
252 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
253 					pdest_buf[buf_idx++] = pwrhexval;
254 				} else if (_os_strncmp(sz_line , "DCM4_0", 6) == 0) {
255 					pdest_buf[buf_idx++] = HE2SS_DCM4_0;
256 					sz_line += 6;
257 					PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
258 					pwrhexval = phypg_combvalue_fromstring(sz_line);
259 					PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
260 					pdest_buf[buf_idx++] = pwrhexval;
261 				}
262 			} else if (_os_strncmp(sz_line , "[Offset]", 8) == 0) {
263 				line_idx = 0;
264 				pwrhexval = 0;
265 
266 				pdest_buf[buf_idx++] = band;
267 				pdest_buf[buf_idx++] = PHYPG_OFFSET;
268 				PHL_INFO("[Line]%s , line_idx %d \n", sz_line, line_idx);
269 
270 				line_idx += 8;
271 				while (sz_line[line_idx] == ' ' || sz_line[line_idx] == '\t' || sz_line[line_idx] == '\0')
272 					++line_idx;
273 
274 				sz_line += line_idx;
275 				if (band == 0) {
276 					if (_os_strncmp(sz_line , "AllRate1", 8) == 0) {
277 						pdest_buf[buf_idx++] = Legacy_AllRate;
278 						sz_line += 8;
279 						PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
280 						pwrhexval = phypg_combvalue_fromstring(sz_line);
281 						PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
282 						pdest_buf[buf_idx++] = pwrhexval;
283 					}
284 					else if (_os_strncmp(sz_line , "AllRate2", 8) == 0) {
285 						pdest_buf[buf_idx++] = HE_AllRate;
286 						sz_line += 8;
287 						PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
288 						pwrhexval = phypg_combvalue_fromstring(sz_line);
289 						PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
290 						pdest_buf[buf_idx++] = pwrhexval;
291 					}
292 				}
293 				if (band == 1) {
294 					if (_os_strncmp(sz_line , "AllRate1", 8) == 0) {
295 						pdest_buf[buf_idx++] = Legacy_AllRate; /* 5G band all rate only OFDM upper */
296 						sz_line += 8;
297 						PHL_INFO("[Line]%s, line_idx %d \n", sz_line, line_idx);
298 						pwrhexval = phypg_combvalue_fromstring(sz_line);
299 						PHL_INFO("combine Value Get Pwr hex Val = %x\n", pwrhexval);
300 						pdest_buf[buf_idx++] = pwrhexval;
301 					}
302 				}
303 			}
304 		}
305 	}
306 	return buf_idx;
307 exit:
308 #if 0 /*dbg dump*/
309 	{
310 		u32 i = 0 ;
311 		char *strbuf , *pextra;
312 		strbuf = _os_mem_alloc(drv_priv, buf_idx  * sizeof(u32));
313 		pextra = strbuf;
314 
315 		sprintf(strbuf, "\n");
316 		pextra = strbuf + _os_strlen(strbuf);
317 		for (i = 0; i <= buf_idx; i ++) {
318 			pextra += sprintf(pextra, " %x \t", pdest_buf[i]);
319 			if ( ((i+1)%4 == 0) && (i != 0))
320 				pextra += sprintf(pextra, "\n");
321 		}
322 		printk( "%s \n" , strbuf);
323 		_os_mem_free(drv_priv, strbuf, buf_idx  * sizeof(u32));
324 	}
325 #endif
326 	return 0;
327 }
328 
329 static int
_hal_parse_radio(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)330 _hal_parse_radio(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
331 {
332 	struct rtw_para_info_t *para_info = (struct rtw_para_info_t *)para_info_t;
333 	u32 *pdest_buf = para_info->para_data;
334 	char	*sz_line, *ptmp;
335 	u32 dest_buf_idx = 0;
336 	u32 u4bregoffset, u4bregvalue, u4bmove;
337 
338 	ptmp = (char *)psrc_buf;
339 
340 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL; sz_line = hal_getLinefrombuffer(ptmp)) {
341 		if (!hal_is_comment_string(sz_line)) {
342 			/* Get 1st hex value as register offset. */
343 			if (hal_get_hexvalue_fromstring(sz_line, &u4bregoffset, &u4bmove)) {
344 
345 				pdest_buf[dest_buf_idx] = u4bregoffset;
346 				dest_buf_idx++;
347 
348 				if (u4bregoffset == 0xffff) {
349 					/* Ending. */
350 					pdest_buf[dest_buf_idx] = 0xffff;
351 					PHL_INFO(" dest_buf_len: %d \n", dest_buf_idx);
352 					break;
353 				}
354 				/* Get 2nd hex value as register value. */
355 				sz_line += u4bmove;
356 				if (hal_get_hexvalue_fromstring(sz_line, &u4bregvalue, &u4bmove)) {
357 					/*PHL_INFO("[RF-ADDR]%03lx=%08lx\n", u4bregoffset, u4bregvalue);*/
358 					pdest_buf[dest_buf_idx] = u4bregvalue;
359 					dest_buf_idx++;
360 				}
361 			}
362 		}
363 	}
364 #if 0
365 	{ /*debug dump buf*/
366 		u32 i = 0;
367 		for (i = 0; i <= dest_buf_idx; i+=2)
368 			PHL_INFO("[Radio-ADDR] 0x%x :[0x%x]\n", pdest_buf[i], pdest_buf[i+1]);
369 	}
370 #endif
371 	return dest_buf_idx;
372 }
373 
374 static int
hal_phy_find_ext_regd_num(struct rtw_para_pwrlmt_info_t * para_info,char * regd_name)375 hal_phy_find_ext_regd_num(struct rtw_para_pwrlmt_info_t *para_info,
376 			char *regd_name)
377 {
378 	int i = 0;
379 
380 	for (i = 0; i <= para_info->ext_regd_arridx ; i++) {
381 		if (_os_strcmp(regd_name, para_info->ext_regd_name[i]) == 0) {
382 			return i;
383 		}
384 	}
385 	return -1;
386 }
387 
388 static void
_hal_add_ext_reg_codemap(void * d,struct rtw_para_pwrlmt_info_t * para_info,const char * country,u16 domain,const char * regd_name,u32 nlen)389 _hal_add_ext_reg_codemap(void *d,
390 			struct rtw_para_pwrlmt_info_t *para_info,
391 			const char *country,
392 			u16 		domain,
393 			const char *regd_name,
394 			u32 		nlen)
395 {
396 	struct _hal_file_regd_ext *pregd_codemap;
397 	struct _hal_file_regd_ext *ent;
398 
399 	if (!regd_name || !nlen) {
400 		PHL_ERR("regd_name || nlen Null\n");
401 		goto exit;
402 	}
403 
404 	pregd_codemap = (struct _hal_file_regd_ext *)para_info->ext_reg_codemap;
405 	ent = &pregd_codemap[para_info->ext_reg_map_num];
406 
407 	if (regd_name && _os_strlen((u8*)regd_name) < 10) {
408 
409 		if (hal_phy_find_ext_regd_num(para_info, (char *)regd_name) == -1) {
410 			u8 idx = (u8)(para_info->ext_regd_arridx + 1);
411 
412 			if (idx < regd_name_max_size) {
413 				_os_strcpy(para_info->ext_regd_name[idx], regd_name);
414 				para_info->ext_regd_arridx++;
415 				PHL_INFO("extrea reg [%d] = [%s]\n",
416 					idx, para_info->ext_regd_name[idx]);
417 			} else {
418 				PHL_ERR("extrea reg [%d] over size\n", idx);
419 				goto exit;
420 			}
421 		}
422 
423 		_os_mem_cpy(d, ent->reg_name, (void*)regd_name, nlen);
424 		PHL_INFO("store reg_name = [%s]\n", ent->reg_name);
425 	} else {
426 		PHL_ERR("reg_name = [%s]\n", ent->reg_name);
427 		goto exit;
428 	}
429 
430 	if (domain != 0)
431 		ent->domain = domain;
432 	else
433 		ent->domain = 0xffff;
434 	PHL_INFO("Store DomainCode = [0x%x]\n", ent->domain);
435 
436 	if (country) {
437 		_os_mem_cpy(d, ent->country, (void*)country, 2);
438 		PHL_INFO("Store country = [%c%c]\n", ent->country[0], ent->country[1]);
439 	} else
440 		_os_mem_set(d, ent->country, '\0', 2);
441 
442 	para_info->ext_reg_map_num++;
443 exit:
444 	return;
445 }
446 
447 /*
448 * @@Ver=2.0
449 * or
450 * @@DomainCode=0x28, Regulation=C6
451 * or
452 * @@CountryCode=GB, Regulation=C7
453 */
454 static u8
parse_reg_exc_config(void * drv_priv,char * sz_line,struct rtw_para_pwrlmt_info_t * para_info)455 parse_reg_exc_config(void *drv_priv,
456 		char *sz_line ,
457 		struct rtw_para_pwrlmt_info_t *para_info)
458 {
459 #define VER_PREFIX "Ver="
460 #define DOMAIN_PREFIX "DomainCode=0x"
461 #define COUNTRY_PREFIX "CountryCode="
462 #define REG_PREFIX "Regulation="
463 
464 	const u8 ver_prefix_len = (u8)_os_strlen((u8*)VER_PREFIX);
465 	const u8 domain_prefix_len = (u8)_os_strlen((u8*)DOMAIN_PREFIX);
466 	const u8 country_prefix_len = (u8)_os_strlen((u8*)COUNTRY_PREFIX);
467 	const u8 reg_prefix_len = (u8)_os_strlen((u8*)REG_PREFIX);
468 	u32 i, i_val_s, i_val_e;
469 	u32 j;
470 	u16 domain = 0;
471 	char *country = NULL;
472 	u8 parse_reg = 0;
473 
474 	if (sz_line[0] != '@' || sz_line[1] != '@')
475 		return false;
476 
477 	i = 2;
478 	if (_os_strncmp(sz_line + i, VER_PREFIX, ver_prefix_len) == 0)
479 		; /* nothing to do */
480 	else if (_os_strncmp(sz_line + i, DOMAIN_PREFIX, domain_prefix_len) == 0) {
481 		/* get string after domain prefix to ',' */
482 		i += domain_prefix_len;
483 		i_val_s = i;
484 		while (sz_line[i] != ',') {
485 			if (sz_line[i] == '\0')
486 				return false;
487 			i++;
488 		}
489 		i_val_e = i;
490 
491 		/* check if all hex */
492 		for (j = i_val_s; j < i_val_e; j++)
493 			if (hal_ishexdigit(sz_line[j]) == false)
494 				return false;
495 
496 		/* get value from hex string */
497 		if (_os_sscanf(sz_line + i_val_s, "%hx", &domain) != 1)
498 			return false;
499 
500 		parse_reg = 1;
501 	} else if (_os_strncmp(sz_line + i, COUNTRY_PREFIX, country_prefix_len) == 0) {
502 		/* get string after country prefix to ',' */
503 		i += country_prefix_len;
504 		i_val_s = i;
505 		while (sz_line[i] != ',') {
506 			if (sz_line[i] == '\0')
507 				return false;
508 			i++;
509 		}
510 		i_val_e = i;
511 
512 		if (i_val_e - i_val_s != 2)
513 			return false;
514 
515 		/* check if all alpha */
516 		for (j = i_val_s; j < i_val_e; j++)
517 			if (hal_is_alpha(sz_line[j]) == false)
518 				return false;
519 
520 		country = sz_line + i_val_s;
521 
522 		parse_reg = 1;
523 
524 	} else
525 		return false;
526 
527 	if (parse_reg) {
528 		/* move to 'R' */
529 		while (sz_line[i] != 'R') {
530 			if (sz_line[i] == '\0')
531 				return false;
532 			i++;
533 		}
534 
535 		/* check if matching regulation prefix */
536 		if (_os_strncmp(sz_line + i, REG_PREFIX, reg_prefix_len) != 0)
537 			return false;
538 
539 		/* get string after regulation prefix ending with space */
540 		i += reg_prefix_len;
541 		i_val_s = i;
542 		while (sz_line[i] != ' ' && sz_line[i] != '\t' && sz_line[i] != '\0')
543 			i++;
544 
545 		if (i == i_val_s)
546 			return false;
547 
548 		_hal_add_ext_reg_codemap(drv_priv, para_info,
549 					country, domain,
550 					sz_line + i_val_s, i - i_val_s);
551 	}
552 
553 	return true;
554 }
555 
hal_phy_store_tx_power_limit(void * drv_priv,u8 * sregulation,u8 * sband,u8 * sbandwidth,u8 * sratesection,u8 * sbf,u8 * sntx,u8 * schannel,u8 * spwrlimit,u8 * spshape_idx,void * pstc_txpwr_lmt,struct rtw_para_pwrlmt_info_t * para_info)556 static void hal_phy_store_tx_power_limit		(void *drv_priv,
557 		u8				*sregulation,
558 		u8				*sband,
559 		u8				*sbandwidth,
560 		u8				*sratesection,
561 		u8				*sbf,
562 		u8				*sntx,
563 		u8				*schannel,
564 		u8				*spwrlimit,
565 		u8				*spshape_idx,
566 		void *pstc_txpwr_lmt,
567 		struct rtw_para_pwrlmt_info_t *para_info)
568 {
569 	u8 band = 0, bandwidth = 0, ratesec = 0, channel = 0;
570 	u8 ntx_idx = 0 , bf = 0 , pshape_idx = 0;
571 	int regulation = -1;
572 	s8 powerlimit = 0;
573 
574 	struct hal_txpwr_lmt_t *array_tc_8852a_txpwr_lmt = (struct hal_txpwr_lmt_t *)pstc_txpwr_lmt;
575 
576 	if (hal_get_u1bint_fromstr_indec((char *)schannel, &channel) == false
577 		|| hal_get_s1bint_fromstr_indec((char *)spwrlimit, &powerlimit) == false) {
578 		PHL_INFO("Illegal index of power limit table [ch %s][val %s]\n",
579 			 (char *)schannel, (char *)spwrlimit);
580 		return;
581 	}
582 
583 	if (spshape_idx != NULL) {
584 		if (hal_get_u1bint_fromstr_indec((char *)spshape_idx, &pshape_idx) == false) {
585 			PHL_INFO("Illegal index of pshape idx [val %s]\n", (char *)spshape_idx);
586 			return;
587 		}
588 	}
589 
590 	if (_os_strncmp((char *)sratesection, (const char *)"CCK", 3) == 0)
591 		ratesec = _PW_LMT_RS_CCK;
592 	else if (_os_strncmp((char *)sratesection, (const char *)"OFDM", 4) == 0)
593 		ratesec = _PW_LMT_RS_OFDM;
594 	else if (_os_strncmp((char *)sratesection, (const char *)"HT", 2) == 0)
595 		ratesec = _PW_LMT_RS_HT;
596 	else if (_os_strncmp((char *)sratesection, (const char *)"VHT", 3) == 0)
597 		ratesec = _PW_LMT_RS_VHT;
598 	else if (_os_strncmp((char *)sratesection, (const char *)"HE", 2) == 0)
599 		ratesec = _PW_LMT_RS_HE;
600 	else {
601 		PHL_INFO("Wrong rate section:%s\n", (char *)sratesection);
602 		return;
603 	}
604 
605 	if (_os_strncmp((char *)sntx, (const char *)"1T", 2) == 0)
606 		ntx_idx = _PW_LMT_PH_1T;
607 	else if (_os_strncmp((char *)sntx, (const char *)"2T", 2) == 0)
608 		ntx_idx = _PW_LMT_PH_2T;
609 	else if (_os_strncmp((char *)sntx, (const char *)"3T", 2) == 0)
610 		ntx_idx = _PW_LMT_PH_3T;
611 	else if (_os_strncmp((char *)sntx, (const char *)"4T", 2) == 0)
612 		ntx_idx = _PW_LMT_PH_4T;
613 	else {
614 		PHL_INFO("Wrong tx num:%s\n", (char *)sntx);
615 		return;
616 	}
617 
618 	if (_os_strncmp((char *)sbandwidth, (const char *)"20M", 3) == 0)
619 		bandwidth = _PW_LMT_BW_20M;
620 	else if (_os_strncmp((char *)sbandwidth, (const char *)"40M", 3) == 0)
621 		bandwidth = _PW_LMT_BW_40M;
622 	else if (_os_strncmp((char *)sbandwidth, (const char *)"80M", 3) == 0)
623 		bandwidth = _PW_LMT_BW_80M;
624 	else if (_os_strncmp((char *)sbandwidth, (const char *)"160M", 4) == 0)
625 		bandwidth = _PW_LMT_BW_160M;
626 	else {
627 		PHL_INFO("unknown bandwidth: %s\n", (char *)sbandwidth);
628 		return;
629 	}
630 
631 	if (_os_strncmp((char *)sband, (const char *)"2.4G", 4) == 0)
632 		band = _PW_LMT_BAND_2_4G;
633 	else if (_os_strncmp((char *)sband, (const char *)"5G", 2) == 0)
634 		band = _PW_LMT_BAND_5G;
635 	else {
636 		PHL_INFO("unknown band: %s\n", (char *)sband);
637 		return;
638 	}
639 
640 	if (_os_strncmp((char *)sbf, (const char *)"Non-BF", 6) == 0 || _os_strncmp((char *)sbf, (const char *)"NA", 2) == 0)
641 		bf = _PW_LMT_NONBF;
642 	else if (_os_strncmp((char *)sbf, (const char *)"BF", 2) == 0)
643 		bf = _PW_LMT_BF;
644 	else {
645 		PHL_INFO("unknown BF: %s\n", (char *)sbf);
646 		return;
647 	}
648 
649 	regulation = rtw_hal_rf_get_predefined_pw_lmt_regu_type_from_str((char *)sregulation);
650 	if (regulation == -1) {
651 		int regd_num = hal_phy_find_ext_regd_num(para_info, (char *)sregulation);
652 
653 		if (regd_num != -1) {
654 			regulation = (u8)regd_num;
655 			PHL_INFO("new regulation num: %d\n", regulation);
656 		} else {
657 		PHL_INFO("unknown regulation: %s\n", (char *)sregulation);
658 		return;
659 	}
660 	}
661 
662 	array_tc_8852a_txpwr_lmt->band = band;
663 	array_tc_8852a_txpwr_lmt->bw = bandwidth;
664 	array_tc_8852a_txpwr_lmt->ch = channel;
665 	array_tc_8852a_txpwr_lmt->rs = ratesec;
666 	array_tc_8852a_txpwr_lmt->ntx = ntx_idx;
667 	array_tc_8852a_txpwr_lmt->bf = bf;
668 	array_tc_8852a_txpwr_lmt->val = powerlimit;
669 	array_tc_8852a_txpwr_lmt->reg = (u8)regulation;
670 	array_tc_8852a_txpwr_lmt->tx_shap_idx = pshape_idx;
671 
672 	PHL_DBG("Store of power limit table [regulation %d][band %d][bw %d]"\
673 		"[rate section %d][ntx %d][BF %d][chnl %d][val %d] [sphape_idx %d]\n",
674 		array_tc_8852a_txpwr_lmt->reg, array_tc_8852a_txpwr_lmt->band,
675 		array_tc_8852a_txpwr_lmt->bw , array_tc_8852a_txpwr_lmt->rs,
676 		array_tc_8852a_txpwr_lmt->ntx, array_tc_8852a_txpwr_lmt->bf,
677 		array_tc_8852a_txpwr_lmt->ch, array_tc_8852a_txpwr_lmt->val,
678 		array_tc_8852a_txpwr_lmt->tx_shap_idx);
679 
680 }
681 
682 
683 static int
_hal_parse_txpwrlmt(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)684 _hal_parse_txpwrlmt(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
685 {
686 #define LD_STAGE_EXC_MAPPING	0
687 #define LD_STAGE_TAB_DEFINE		1
688 #define LD_STAGE_TAB_START		2
689 #define LD_STAGE_COLUMN_DEFINE	3
690 #define LD_STAGE_COLUMN_REG		4
691 #define LD_STAGE_CH_ROW			5
692 #define LD_STAGE_PSHAPE_NUM		6
693 
694 	struct rtw_para_pwrlmt_info_t *para_info = (struct rtw_para_pwrlmt_info_t *)para_info_t;
695 	u32 *pdest_buf = para_info->para_data;
696 	char **regulation = NULL;
697 	char **pshape = NULL;
698 	char	*sz_line = NULL, *ptmp = NULL;
699 	char band[10], bandwidth[10], ratesection[10], ntx[10], colnumbuf[10], bf_type[10];
700 	u8	colnum = 0;
701 	u8	loadingstage = LD_STAGE_EXC_MAPPING;
702 	u32 struct_idx = 0;
703 	u32	i = 0, forcnt = 0;
704 	PHAL_TXPWR_LMT_T array_tc_8852a_txpwr_lmt;
705 
706 	if (pdest_buf == NULL || psrc_buf == NULL) {
707 		PHL_INFO("%s, fail !!! NULL buf !!!\n", __func__);
708 		return 0;
709 	}
710 
711 	array_tc_8852a_txpwr_lmt = (PHAL_TXPWR_LMT_T)pdest_buf;
712 
713 	ptmp = (char *)psrc_buf;
714 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL; sz_line = hal_getLinefrombuffer(ptmp)) {
715 line_start:
716 		if (hal_is_allspace_tab(sz_line, sizeof(*sz_line)))
717 			continue;
718 
719 		if (hal_is_comment_string(sz_line))
720 			continue;
721 
722 		if (loadingstage == LD_STAGE_EXC_MAPPING) {
723 			if (sz_line[0] == '#' || sz_line[1] == '#') {
724 				loadingstage = LD_STAGE_TAB_DEFINE;
725 			} else {
726 				if (parse_reg_exc_config(drv_priv, sz_line, para_info) == false) {
727 					PHL_ERR("Fail to parse regulation exception ruls!\n");
728 					goto exit;
729 				}
730 			continue;
731 			}
732 		}
733 
734 		if (loadingstage == LD_STAGE_TAB_DEFINE) {
735 			/* read "## 2.4G, 20M, 1T, CCK" */
736 			if (sz_line[0] != '#' || sz_line[1] != '#')
737 				continue;
738 
739 			/* skip the space */
740 			i = 2;
741 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
742 				++i;
743 
744 			sz_line[--i] = ' '; /* return the space in front of the regulation info */
745 
746 			/* Parse the label of the table */
747 			_os_mem_set(drv_priv, (void *) band, 0, 10);
748 			_os_mem_set(drv_priv, (void *) bandwidth, 0, 10);
749 			_os_mem_set(drv_priv, (void *) ntx, 0, 10);
750 			_os_mem_set(drv_priv, (void *) ratesection, 0, 10);
751 			_os_mem_set(drv_priv, (void *) bf_type, 0, 10);
752 
753 			if (!hal_parse_fiedstring(sz_line, &i, band, ' ', ',')) {
754 				PHL_ERR("Fail to parse band!\n");
755 				struct_idx = 0;
756 				goto exit;
757 			}
758 			if (!hal_parse_fiedstring(sz_line, &i, bandwidth, ' ', ',')) {
759 				PHL_ERR("Fail to parse bandwidth!\n");
760 				struct_idx = 0;
761 				goto exit;
762 			}
763 			if (!hal_parse_fiedstring(sz_line, &i, ntx, ' ', ',')) {
764 				PHL_ERR("Fail to parse ntx!\n");
765 				struct_idx = 0;
766 				goto exit;
767 			}
768 			if (!hal_parse_fiedstring(sz_line, &i, ratesection, ' ', ',')) {
769 				PHL_ERR("Fail to parse rate!\n");
770 				struct_idx = 0;
771 				goto exit;
772 			}
773 			if (!hal_parse_fiedstring(sz_line, &i, bf_type, ' ', '/')) {
774 				PHL_ERR("Fail to parse BF!\n");
775 				struct_idx = 0;
776 				goto exit;
777 			}
778 
779 			loadingstage = LD_STAGE_TAB_START;
780 		} else if (loadingstage == LD_STAGE_TAB_START) {
781 			/* read "## START" */
782 			if (sz_line[0] != '#' || sz_line[1] != '#')
783 				continue;
784 
785 			/* skip the space */
786 			i = 2;
787 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
788 				++i;
789 
790 			if (_os_strncmp((char *)(sz_line + i), (const char *)"START", 5)) {
791 				PHL_ERR("Missing \"##	START\" label\n");
792 				struct_idx = 0;
793 				goto exit;
794 			}
795 			loadingstage = LD_STAGE_COLUMN_DEFINE;
796 		} else if (loadingstage == LD_STAGE_COLUMN_DEFINE) {
797 			/* read "## #5# " */
798 			if (sz_line[0] != '#' || sz_line[1] != '#')
799 
800 			/* skip the space */
801 			i = 2;
802 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
803 				++i;
804 
805 			_os_mem_set(drv_priv, (void *) colnumbuf, 0, 10);
806 			if (!hal_parse_fiedstring(sz_line, &i, colnumbuf, '#', '#')) {
807 				PHL_ERR("Fail to parse column number!\n");
808 				struct_idx = 0;
809 				goto exit;
810 			}
811 			if (!hal_get_u1bint_fromstr_indec(colnumbuf, &colnum)) {
812 				PHL_ERR("Column number \"%s\" is not unsigned decimal\n", colnumbuf);
813 				struct_idx = 0;
814 				goto exit;
815 			}
816 			if (colnum == 0) {
817 				PHL_ERR("Column number is 0\n");
818 				struct_idx = 0;
819 				goto exit;
820 			}
821 			PHL_INFO("[%s][%s][%s][%s][%s] column num:%d\n",
822 				band, bandwidth, ratesection, ntx, bf_type, colnum);
823 
824 			regulation = (char **)_os_mem_alloc(drv_priv, sizeof(char *) * colnum);
825 			if (!regulation) {
826 				PHL_ERR("Regulation alloc fail\n");
827 				struct_idx = 0;
828 				goto exit;
829 			}
830 			pshape = (char **)_os_mem_alloc(drv_priv, sizeof(char *) * colnum);
831 			if (!pshape) {
832 				PHL_ERR("Regulation alloc fail\n");
833 				struct_idx = 0;
834 				goto exit;
835 			}
836 			loadingstage = LD_STAGE_COLUMN_REG;
837 		} else if (loadingstage == LD_STAGE_COLUMN_REG) {
838 			/* read "##		FCC ETSI	MKK IC	KCC" */
839 			if (sz_line[0] != '#' || sz_line[1] != '#')
840 				continue;
841 
842 			/* skip the space */
843 			i = 2;
844 			for (forcnt = 0; forcnt < colnum; ++forcnt) {
845 				u32 i_ns;
846 
847 				/* skip the space */
848 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
849 					i++;
850 				i_ns = i;
851 
852 				while (sz_line[i] != ' ' && sz_line[i] != '\t' && sz_line[i] != '\0')
853 					i++;
854 
855 				regulation[forcnt] = (char *)_os_mem_alloc(drv_priv, i - i_ns + 1);
856 				if (!regulation[forcnt]) {
857 					PHL_ERR("Regulation alloc fail\n");
858 					struct_idx = 0;
859 					goto exit;
860 				}
861 
862 				_os_mem_cpy(drv_priv, regulation[forcnt], sz_line + i_ns, i - i_ns);
863 				regulation[forcnt][i - i_ns] = '\0';
864 			}
865 
866 			if (1) {
867 				PHL_INFO("column name:");
868 				for (forcnt = 0; forcnt < colnum; ++forcnt)
869 					PHL_INFO(" %s", regulation[forcnt]);
870 				PHL_INFO("\n");
871 			}
872 
873 			loadingstage = LD_STAGE_PSHAPE_NUM;
874 		}else if (loadingstage == LD_STAGE_PSHAPE_NUM) {
875 
876 			if (sz_line[0] == '#' || sz_line[1] == '#')
877 				continue;
878 
879 			if ((sz_line[0] != 'p' && sz_line[0] != 'P') ||
880 				(sz_line[1] != 's' && sz_line[1] != 'S')) {
881 				PHL_INFO("No PShape prefix: '%c','%c'(%d,%d), continue to CH ROW\n",
882 					sz_line[0], sz_line[1], sz_line[0], sz_line[1]);
883 				loadingstage = LD_STAGE_CH_ROW;
884 				goto line_start;
885 			}
886 			PHL_INFO("1.sz_line[0 1] %c %c", sz_line[0], sz_line[1]);
887 			i = 6;/* move to the  location behind 'e' */
888 
889 			for (forcnt = 0; forcnt < colnum; ++forcnt) {
890 				u32	i_ns;
891 
892 				/* skip the space */
893 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
894 					i++;
895 				i_ns = i;
896 				PHL_INFO("1.sz_line[%d] %c\n", i ,sz_line[i]);
897 				while (sz_line[i] != ' ' && sz_line[i] != '\t' && sz_line[i] != '\0')
898 					i++;
899 
900 				pshape[forcnt] = (char *)_os_mem_alloc(drv_priv, i - i_ns + 1);
901 				if (!pshape[forcnt]) {
902 					PHL_ERR("Regulation alloc fail, pshape [%d]\n", forcnt);
903 					goto exit;
904 				}
905 				PHL_INFO("2.pshape [%d] = %s\n", forcnt, pshape[forcnt]);
906 
907 				_os_mem_cpy(drv_priv, pshape[forcnt], sz_line + i_ns, i - i_ns);
908 				pshape[forcnt][i - i_ns] = '\0';
909 				PHL_INFO(" forcnt %d shape idx: %s:", forcnt, pshape[forcnt]);
910 			}
911 
912 			if (1) {
913 				PHL_INFO("pshape idx:");
914 				for (forcnt = 0; forcnt < colnum; ++forcnt)
915 					PHL_INFO(" %s", pshape[forcnt]);
916 				PHL_INFO("\n");
917 			}
918 
919 			loadingstage = LD_STAGE_CH_ROW;
920 		} else if (loadingstage == LD_STAGE_CH_ROW) {
921 			char	channel[10] = {0}, powerlimit[10] = {0};
922 			u8	cnt = 0;
923 
924 			/* the table ends */
925 			if (sz_line[0] == '#' && sz_line[1] == '#') {
926 				i = 2;
927 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
928 					++i;
929 
930 				if (_os_strncmp((char *)(sz_line + i), (const char *)"END", 3) == 0) {
931 					loadingstage = LD_STAGE_TAB_DEFINE;
932 					if (regulation) {
933 						for (forcnt = 0; forcnt < colnum; ++forcnt) {
934 							if (regulation[forcnt]) {
935 								_os_mem_free(drv_priv,
936 									(u8 *)regulation[forcnt],
937 									_os_strlen((u8 *)regulation[forcnt]) + 1);
938 								regulation[forcnt] = NULL;
939 							}
940 						}
941 						_os_mem_free(drv_priv, (u8 *)regulation, sizeof(char *) * colnum);
942 						regulation = NULL;
943 					}
944 					if (pshape) {
945 						for (forcnt = 0; forcnt < colnum; ++forcnt) {
946 							if (pshape[forcnt]) {
947 								_os_mem_free(drv_priv,
948 									(u8 *)pshape[forcnt],
949 									_os_strlen((u8 *)pshape[forcnt]) + 1);
950 								pshape[forcnt] = NULL;
951 							}
952 						}
953 						_os_mem_free(drv_priv, (u8 *)pshape, sizeof(char *) * colnum);
954 						pshape = NULL;
955 					}
956 					colnum = 0;
957 					continue;
958 				} else {
959 					PHL_ERR("Missing \"##	END\" label\n");
960 					struct_idx = 0;
961 					goto exit;
962 				}
963 			}
964 
965 			if ((sz_line[0] != 'c' && sz_line[0] != 'C') ||
966 				(sz_line[1] != 'h' && sz_line[1] != 'H')) {
967 				PHL_ERR("Wrong channel prefix: '%c','%c'(%d,%d)\n",
968 					sz_line[0], sz_line[1], sz_line[0], sz_line[1]);
969 				continue;
970 			}
971 			i = 2;/* move to the  location behind 'h' */
972 
973 			/* load the channel number */
974 			cnt = 0;
975 			while (sz_line[i] >= '0' && sz_line[i] <= '9') {
976 				channel[cnt] = sz_line[i];
977 				++cnt;
978 				++i;
979 			}
980 			PHL_INFO("chnl %s!\n", channel);
981 
982 			for (forcnt = 0; forcnt < colnum; ++forcnt) {
983 				/* skip the space between channel number and the power limit value */
984 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
985 					++i;
986 
987 				/* load the power limit value */
988 				_os_mem_set(drv_priv, (void *) powerlimit, 0, 10);
989 
990 				if (sz_line[i] == 'W' && sz_line[i + 1] == 'W') {
991 					/*
992 					* case "WW" assign special ww value
993 					* means to get minimal limit in other regulations at same channel
994 					*/
995 					s8 ww_value = -63;
996 					_os_snprintf(powerlimit, 10, "%d", ww_value);
997 					i += 2;
998 
999 				} else if (sz_line[i] == 'N' && sz_line[i + 1] == 'A') {
1000 					/*
1001 					* case "NA" assign max txgi value
1002 					* means no limitation
1003 					*/
1004 					_os_snprintf(powerlimit, 10, "%d", 63);
1005 					i += 2;
1006 
1007 				} else if ((sz_line[i] >= '0' && sz_line[i] <= '9') || sz_line[i] == '.'
1008 					|| sz_line[i] == '+' || sz_line[i] == '-') {
1009 					/* case of dBm value */
1010 					u8 integer = 0, fraction = 0, negative = 0;
1011 					u32 u4bmove;
1012 					s8 lmt = 0;
1013 
1014 					if (sz_line[i] == '+' || sz_line[i] == '-') {
1015 						if (sz_line[i] == '-')
1016 							negative = 1;
1017 						i++;
1018 					}
1019 
1020 					if (hal_get_fractionvalue_fromstring(&sz_line[i], &integer, &fraction, &u4bmove))
1021 						i += u4bmove;
1022 					else {
1023 						PHL_ERR("Limit \"%s\" is not valid decimal\n", &sz_line[i]);
1024 						struct_idx = 0;
1025 						goto exit;
1026 					}
1027 
1028 					/* transform to string of value in unit of txgi */
1029 					lmt = (integer * 4) + ((u16)fraction * 4 / 100);
1030 					if (negative)
1031 						lmt = -lmt;
1032 					_os_snprintf(powerlimit, 10, "%d", lmt);
1033 
1034 					} else {
1035 						PHL_ERR("Wrong limit expression \"%c%c\"(%d, %d)\n"
1036 							, sz_line[i], sz_line[i + 1], sz_line[i], sz_line[i + 1]);
1037 						struct_idx = 0;
1038 						goto exit;
1039 					}
1040 
1041 					/* store the power limit value */
1042 					hal_phy_store_tx_power_limit(drv_priv, (u8 *)regulation[forcnt],
1043 						(u8 *)band, (u8 *)bandwidth, (u8 *)ratesection,
1044 						(u8 *)bf_type, (u8 *)ntx, (u8 *)channel,
1045 						(u8 *)powerlimit, (u8 *)pshape[forcnt],
1046 						(void*)&array_tc_8852a_txpwr_lmt[struct_idx], para_info);
1047 
1048 					struct_idx++;
1049 					}
1050 				}
1051 	}
1052 exit:
1053 	if (regulation) {
1054 		for (forcnt = 0; forcnt < colnum; ++forcnt) {
1055 			if (regulation[forcnt]) {
1056 				_os_mem_free(drv_priv,
1057 					(u8 *)regulation[forcnt],
1058 					_os_strlen((u8 *)regulation[forcnt]) + 1);
1059 				regulation[forcnt] = NULL;
1060 			}
1061 		}
1062 		_os_mem_free(drv_priv, (u8 *)regulation, sizeof(char *) * colnum);
1063 		regulation = NULL;
1064 	}
1065 	if (pshape) {
1066 		for (forcnt = 0; forcnt < colnum; ++forcnt) {
1067 			if (pshape[forcnt]) {
1068 				_os_mem_free(drv_priv,
1069 					(u8 *)pshape[forcnt],
1070 					_os_strlen((u8 *)pshape[forcnt]) + 1);
1071 				pshape[forcnt] = NULL;
1072 			}
1073 		}
1074 		_os_mem_free(drv_priv, (u8 *)pshape, sizeof(char *) * colnum);
1075 		pshape = NULL;
1076 	}
1077 
1078 	return struct_idx;
1079 }
1080 
1081 
hal_phy_store_tx_power_limit_ru(void * drv_priv,u8 * sregulation,u8 * sband,u8 * sbandwidth,u8 * sratesection,u8 * sntx,u8 * schannel,u8 * spwrlimit,u8 * spshape_idx,void * pstc_txpwr_lmt_ru,struct rtw_para_pwrlmt_info_t * para_info)1082 static void hal_phy_store_tx_power_limit_ru		(void *drv_priv,
1083 		u8				*sregulation,
1084 		u8				*sband,
1085 		u8				*sbandwidth,
1086 		u8				*sratesection,
1087 		u8				*sntx,
1088 		u8				*schannel,
1089 		u8				*spwrlimit,
1090 		u8				*spshape_idx,
1091 		void *pstc_txpwr_lmt_ru,
1092 		struct rtw_para_pwrlmt_info_t *para_info)
1093 {
1094 	u8 band = 0, bandwidth = 0, ratesec = 0, channel = 0;
1095 	u8 ntx_idx = 0 , pshape_idx = 0;
1096 	int regulation = -1;
1097 	s8 powerlimit = 0;
1098 
1099 	struct hal_txpwr_lmt_ru_t *array_tc_8852a_txpwr_lmt_ru = (struct hal_txpwr_lmt_ru_t *)pstc_txpwr_lmt_ru;
1100 
1101 	if (hal_get_u1bint_fromstr_indec((char *)schannel, &channel) == false
1102 		|| hal_get_s1bint_fromstr_indec((char *)spwrlimit, &powerlimit) == false) {
1103 		PHL_INFO("Illegal index of power limit table [ch %s][val %s]\n",
1104 			 (char *)schannel, (char *)spwrlimit);
1105 		return;
1106 	}
1107 
1108 	if (spshape_idx != NULL) {
1109 		if (hal_get_u1bint_fromstr_indec((char *)spshape_idx, &pshape_idx) == false) {
1110 			PHL_INFO("Illegal index of pshape idx [val %s]\n", (char *)spshape_idx);
1111 			return;
1112 		}
1113 	}
1114 
1115 	if (_os_strncmp((char *)sband, (const char *)"2.4G", 4) == 0)
1116 		band = _PW_LMT_BAND_2_4G;
1117 	else if (_os_strncmp((char *)sband, (const char *)"5G", 2) == 0)
1118 		band = _PW_LMT_BAND_5G;
1119 	else {
1120 		PHL_INFO("unknown band: %s\n", (char *)sband);
1121 		return;
1122 	}
1123 
1124 	if (_os_strncmp((char *)sbandwidth, (const char *)"RU26", 4) == 0)
1125 		bandwidth = _PW_LMT_RU_BW_RU26;
1126 	else if (_os_strncmp((char *)sbandwidth, (const char *)"RU52", 4) == 0)
1127 		bandwidth = _PW_LMT_RU_BW_RU52;
1128 	else if (_os_strncmp((char *)sbandwidth, (const char *)"RU106", 5) == 0)
1129 		bandwidth = _PW_LMT_RU_BW_RU106;
1130 	else {
1131 		PHL_INFO("unknown RU bandwidth: %s\n", (char *)sbandwidth);
1132 		return;
1133 	}
1134 
1135 	if (_os_strncmp((char *)sntx, (const char *)"1T", 2) == 0)
1136 		ntx_idx = _PW_LMT_PH_1T;
1137 	else if (_os_strncmp((char *)sntx, (const char *)"2T", 2) == 0)
1138 		ntx_idx = _PW_LMT_PH_2T;
1139 	else if (_os_strncmp((char *)sntx, (const char *)"3T", 2) == 0)
1140 		ntx_idx = _PW_LMT_PH_3T;
1141 	else if (_os_strncmp((char *)sntx, (const char *)"4T", 2) == 0)
1142 		ntx_idx = _PW_LMT_PH_4T;
1143 	else {
1144 		PHL_INFO("Wrong tx num:%s\n", (char *)sntx);
1145 		return;
1146 	}
1147 
1148 	if (_os_strncmp((char *)sratesection, (const char *)"HE", 2) == 0)
1149 		ratesec = _PW_LMT_RS_HE;
1150 	else {
1151 		PHL_INFO("Wrong RU rate section:%s\n", (char *)sratesection);
1152 		return;
1153 	}
1154 
1155 	regulation = rtw_hal_rf_get_predefined_pw_lmt_regu_type_from_str((char *)sregulation);
1156 	if (regulation == -1) {
1157 		int regd_num = hal_phy_find_ext_regd_num(para_info, (char *)sregulation);
1158 
1159 		if (regd_num != -1) {
1160 			regulation = (u8)regd_num;
1161 			PHL_INFO("new regulation num: %d\n", regulation);
1162 		} else {
1163 		PHL_INFO("unknown regulation: %s\n", (char *)sregulation);
1164 		return;
1165 	}
1166 
1167 	}
1168 
1169 	array_tc_8852a_txpwr_lmt_ru->band = band;
1170 	array_tc_8852a_txpwr_lmt_ru->rubw = bandwidth;
1171 	array_tc_8852a_txpwr_lmt_ru->ntx = ntx_idx;
1172 	array_tc_8852a_txpwr_lmt_ru->rs = ratesec;
1173 	array_tc_8852a_txpwr_lmt_ru->reg = (u8)regulation;
1174 	array_tc_8852a_txpwr_lmt_ru->ch = channel;
1175 	array_tc_8852a_txpwr_lmt_ru->val = powerlimit;
1176 	array_tc_8852a_txpwr_lmt_ru->tx_shap_idx = pshape_idx;
1177 
1178 	PHL_INFO("Store of power limit RU table [band %d][bw %d][ntx %d]"\
1179 			"[rate section %d][regulation %d][chnl %d][val %d]  [sphape_idx %d]\n",
1180 		array_tc_8852a_txpwr_lmt_ru->band , array_tc_8852a_txpwr_lmt_ru->rubw,
1181 		array_tc_8852a_txpwr_lmt_ru->ntx, array_tc_8852a_txpwr_lmt_ru->rs,
1182 		array_tc_8852a_txpwr_lmt_ru->reg, array_tc_8852a_txpwr_lmt_ru->ch,
1183 		array_tc_8852a_txpwr_lmt_ru->val, array_tc_8852a_txpwr_lmt_ru->tx_shap_idx);
1184 }
1185 
1186 
1187 static int
_hal_parse_txpwrlmt_ru(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)1188 _hal_parse_txpwrlmt_ru(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
1189 {
1190 #define LD_STAGE_EXC_MAPPING	0
1191 #define LD_STAGE_TAB_DEFINE		1
1192 #define LD_STAGE_TAB_START		2
1193 #define LD_STAGE_COLUMN_DEFINE	3
1194 #define LD_STAGE_COLUMN_REG		4
1195 #define LD_STAGE_CH_ROW			5
1196 #define LD_STAGE_PSHAPE_NUM		6
1197 
1198 	struct rtw_para_pwrlmt_info_t *para_info = (struct rtw_para_pwrlmt_info_t *)para_info_t;
1199 	u32 *pdest_buf = para_info->para_data;
1200 	char **regulation = NULL;
1201 	char **pshape = NULL;
1202 	char	*sz_line = NULL, *ptmp = NULL;
1203 	char band[10], bandwidth[10], ratesection[10], ntx[10], col_num_buf[10];
1204 	u8	col_num = 0;
1205 	u8	loadingstage = LD_STAGE_EXC_MAPPING;
1206 	u32 struct_idx = 0;
1207 	u32	i = 0, for_cnt = 0;
1208 	pHal_Txpwr_lmt_Ru_t array_tc_txpwr_lmt_ru;
1209 
1210 	if (pdest_buf == NULL || psrc_buf == NULL) {
1211 		PHL_INFO("%s, fail !!! NULL buf !!!\n", __func__);
1212 		return 0;
1213 	}
1214 
1215 	array_tc_txpwr_lmt_ru = (pHal_Txpwr_lmt_Ru_t)pdest_buf;
1216 
1217 	ptmp = (char *)psrc_buf;
1218 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL; sz_line = hal_getLinefrombuffer(ptmp)) {
1219 line_start:
1220 		if (hal_is_allspace_tab(sz_line, sizeof(*sz_line)))
1221 			continue;
1222 
1223 		if (hal_is_comment_string(sz_line))
1224 			continue;
1225 
1226 		if (loadingstage == LD_STAGE_EXC_MAPPING) {
1227 				if (sz_line[0] == '#' || sz_line[1] == '#') {
1228 					loadingstage = LD_STAGE_TAB_DEFINE;
1229 			} else {
1230 				if (parse_reg_exc_config(drv_priv, sz_line, para_info) == false) {
1231 					PHL_ERR("Fail to parse regulation exception ruls!\n");
1232 					goto exit;
1233 				}
1234 				continue;
1235 			}
1236 		}
1237 
1238 		if (loadingstage == LD_STAGE_TAB_DEFINE) {
1239 			/* read "## 2.4G, RU26, 1T, HE //" */
1240 			if (sz_line[0] != '#' || sz_line[1] != '#')
1241 				continue;
1242 
1243 			/* skip the space */
1244 			i = 2;
1245 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
1246 				++i;
1247 
1248 			sz_line[--i] = ' '; /* return the space in front of the regulation info */
1249 
1250 			/* Parse the label of the table */
1251 			_os_mem_set(drv_priv, (void *) band, 0, 10);
1252 			_os_mem_set(drv_priv, (void *) bandwidth, 0, 10);
1253 			_os_mem_set(drv_priv, (void *) ntx, 0, 10);
1254 			_os_mem_set(drv_priv, (void *) ratesection, 0, 10);
1255 
1256 			if (!hal_parse_fiedstring(sz_line, &i, band, ' ', ',')) {
1257 				PHL_ERR("Fail to parse band!\n");
1258 				struct_idx = 0;
1259 				goto exit;
1260 			}
1261 			if (!hal_parse_fiedstring(sz_line, &i, bandwidth, ' ', ',')) {
1262 				PHL_ERR("Fail to parse bandwidth!\n");
1263 				struct_idx = 0;
1264 				goto exit;
1265 			}
1266 			if (!hal_parse_fiedstring(sz_line, &i, ntx, ' ', ',')) {
1267 				PHL_ERR("Fail to parse ntx!\n");
1268 				struct_idx = 0;
1269 				goto exit;
1270 			}
1271 			if (!hal_parse_fiedstring(sz_line, &i, ratesection, ' ', ' ')) {
1272 				PHL_ERR("Fail to parse rate!\n");
1273 				struct_idx = 0;
1274 				goto exit;
1275 			}
1276 
1277 			loadingstage = LD_STAGE_TAB_START;
1278 		} else if (loadingstage == LD_STAGE_TAB_START) {
1279 			/* read "## START" */
1280 			if (sz_line[0] != '#' || sz_line[1] != '#')
1281 				continue;
1282 
1283 			/* skip the space */
1284 			i = 2;
1285 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
1286 				++i;
1287 
1288 			if (_os_strncmp((char *)(sz_line + i), (const char *)"START", 5)) {
1289 				PHL_ERR("Missing \"##	START\" label\n");
1290 				struct_idx = 0;
1291 				goto exit;
1292 			}
1293 			loadingstage = LD_STAGE_COLUMN_DEFINE;
1294 		} else if (loadingstage == LD_STAGE_COLUMN_DEFINE) {
1295 			/* read "## #5# " */
1296 			if (sz_line[0] != '#' || sz_line[1] != '#')
1297 
1298 			/* skip the space */
1299 			i = 2;
1300 			while (sz_line[i] == ' ' || sz_line[i] == '\t')
1301 				++i;
1302 
1303 			_os_mem_set(drv_priv, (void *) col_num_buf, 0, 10);
1304 			if (!hal_parse_fiedstring(sz_line, &i, col_num_buf, '#', '#')) {
1305 				PHL_ERR("Fail to parse column number!\n");
1306 				struct_idx = 0;
1307 				goto exit;
1308 			}
1309 			if (!hal_get_u1bint_fromstr_indec(col_num_buf, &col_num)) {
1310 				PHL_ERR("Column number \"%s\" is not unsigned decimal\n", col_num_buf);
1311 				struct_idx = 0;
1312 				goto exit;
1313 			}
1314 			if (col_num == 0) {
1315 				PHL_ERR("Column number is 0\n");
1316 				struct_idx = 0;
1317 				goto exit;
1318 			}
1319 			PHL_INFO("[%s][%s][%s][%s] column num:%d\n",
1320 					band, bandwidth, ratesection, ntx, col_num);
1321 
1322 			regulation = (char **)_os_mem_alloc(drv_priv, sizeof(char *) * col_num);
1323 			if (!regulation) {
1324 				PHL_ERR("Regulation alloc fail\n");
1325 				struct_idx = 0;
1326 				goto exit;
1327 			}
1328 			pshape = (char **)_os_mem_alloc(drv_priv, sizeof(char *) * col_num);
1329 			if (!pshape) {
1330 				PHL_ERR("Regulation alloc fail\n");
1331 				struct_idx = 0;
1332 				goto exit;
1333 			}
1334 			loadingstage = LD_STAGE_COLUMN_REG;
1335 		}else if (loadingstage == LD_STAGE_COLUMN_REG) {
1336 			/* read "##		FCC ETSI	MKK IC	KCC" */
1337 			if (sz_line[0] != '#' || sz_line[1] != '#')
1338 				continue;
1339 
1340 			/* skip the space */
1341 			i = 2;
1342 			for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1343 				u32 i_ns;
1344 
1345 				/* skip the space */
1346 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
1347 					i++;
1348 				i_ns = i;
1349 
1350 				while (sz_line[i] != ' ' && sz_line[i] != '\t' && sz_line[i] != '\0')
1351 					i++;
1352 
1353 				regulation[for_cnt] = (char *)_os_mem_alloc(drv_priv, i - i_ns + 1);
1354 				if (!regulation[for_cnt]) {
1355 					PHL_ERR("Regulation alloc fail\n");
1356 					struct_idx = 0;
1357 					goto exit;
1358 				}
1359 
1360 				_os_mem_cpy(drv_priv, regulation[for_cnt], sz_line + i_ns, i - i_ns);
1361 				regulation[for_cnt][i - i_ns] = '\0';
1362 			}
1363 
1364 			if (1) {
1365 				PHL_INFO("column name:");
1366 				for (for_cnt = 0; for_cnt < col_num; ++for_cnt)
1367 					PHL_INFO(" %s", regulation[for_cnt]);
1368 				PHL_INFO("\n");
1369 			}
1370 				loadingstage = LD_STAGE_PSHAPE_NUM;
1371 		}else if (loadingstage == LD_STAGE_PSHAPE_NUM) {
1372 
1373 			if (sz_line[0] == '#' || sz_line[1] == '#')
1374 				continue;
1375 
1376 			if ((sz_line[0] != 'p' && sz_line[0] != 'P') ||
1377 				(sz_line[1] != 's' && sz_line[1] != 'S')) {
1378 				PHL_INFO("No PShape prefix: '%c','%c'(%d,%d), continue to CH ROW\n",
1379 					sz_line[0], sz_line[1], sz_line[0], sz_line[1]);
1380 				loadingstage = LD_STAGE_CH_ROW;
1381 				goto line_start;
1382 			}
1383 			PHL_INFO("1.sz_line[0 1] %c %c", sz_line[0], sz_line[1]);
1384 			i = 6;/* move to the  location behind 'e' */
1385 
1386 			for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1387 				u32	i_ns;
1388 
1389 				/* skip the space */
1390 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
1391 					i++;
1392 				i_ns = i;
1393 				PHL_INFO("1.sz_line[%d] %c\n", i ,sz_line[i]);
1394 				while (sz_line[i] != ' ' && sz_line[i] != '\t' && sz_line[i] != '\0')
1395 					i++;
1396 
1397 				pshape[for_cnt] = (char *)_os_mem_alloc(drv_priv, i - i_ns + 1);
1398 				if (!pshape[for_cnt]) {
1399 					PHL_ERR("Regulation alloc fail, pshape [%d]\n", for_cnt);
1400 					goto exit;
1401 				}
1402 				PHL_INFO("2.pshape [%d] = %s\n", for_cnt, pshape[for_cnt]);
1403 
1404 				_os_mem_cpy(drv_priv, pshape[for_cnt], sz_line + i_ns, i - i_ns);
1405 				pshape[for_cnt][i - i_ns] = '\0';
1406 				PHL_INFO(" forcnt %d shape idx: %s:", for_cnt, pshape[for_cnt]);
1407 			}
1408 
1409 			if (1) {
1410 				PHL_INFO("pshape idx:");
1411 				for (for_cnt = 0; for_cnt < col_num; ++for_cnt)
1412 					PHL_INFO(" %s", pshape[for_cnt]);
1413 				PHL_INFO("\n");
1414 			}
1415 
1416 			loadingstage = LD_STAGE_CH_ROW;
1417 		} else if (loadingstage == LD_STAGE_CH_ROW) {
1418 			char	channel[10] = {0}, powerlimit[10] = {0};
1419 			u8	cnt = 0;
1420 
1421 			/* the table ends */
1422 			if (sz_line[0] == '#' && sz_line[1] == '#') {
1423 				i = 2;
1424 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
1425 					++i;
1426 
1427 				if (_os_strncmp((char *)(sz_line + i), (const char *)"END", 3) == 0) {
1428 					loadingstage = LD_STAGE_TAB_DEFINE;
1429 					if (regulation) {
1430 						for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1431 							if (regulation[for_cnt]) {
1432 								_os_mem_free(drv_priv,
1433 									(u8 *)regulation[for_cnt],
1434 									_os_strlen((u8 *)regulation[for_cnt]) + 1);
1435 								regulation[for_cnt] = NULL;
1436 							}
1437 						}
1438 						_os_mem_free(drv_priv, (u8 *)regulation, sizeof(char *) * col_num);
1439 						regulation = NULL;
1440 					}
1441 					if (pshape) {
1442 						for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1443 							if (pshape[for_cnt]) {
1444 								_os_mem_free(drv_priv,
1445 									(u8 *)pshape[for_cnt],
1446 									_os_strlen((u8 *)pshape[for_cnt]) + 1);
1447 								pshape[for_cnt] = NULL;
1448 							}
1449 						}
1450 						_os_mem_free(drv_priv, (u8 *)pshape, sizeof(char *) * col_num);
1451 						pshape = NULL;
1452 					}
1453 					col_num = 0;
1454 					continue;
1455 				} else {
1456 					PHL_ERR("Missing \"##	END\" label\n");
1457 					struct_idx = 0;
1458 					goto exit;
1459 				}
1460 			}
1461 
1462 			if ((sz_line[0] != 'c' && sz_line[0] != 'C') ||
1463 				(sz_line[1] != 'h' && sz_line[1] != 'H')) {
1464 				PHL_ERR("Wrong channel prefix: '%c','%c'(%d,%d)\n",
1465 					sz_line[0], sz_line[1], sz_line[0], sz_line[1]);
1466 				continue;
1467 			}
1468 			i = 2;/* move to the  location behind 'h' */
1469 
1470 			/* load the channel number */
1471 			cnt = 0;
1472 			while (sz_line[i] >= '0' && sz_line[i] <= '9') {
1473 				channel[cnt] = sz_line[i];
1474 				++cnt;
1475 				++i;
1476 			}
1477 			PHL_INFO("chnl %s!\n", channel);
1478 
1479 			for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1480 				/* skip the space between channel number and the power limit value */
1481 				while (sz_line[i] == ' ' || sz_line[i] == '\t')
1482 					++i;
1483 
1484 				/* load the power limit value */
1485 				_os_mem_set(drv_priv, (void *) powerlimit, 0, 10);
1486 
1487 				if (sz_line[i] == 'W' && sz_line[i + 1] == 'W') {
1488 					/*
1489 					* case "WW" assign special ww value
1490 					* means to get minimal limit in other regulations at same channel
1491 					*/
1492 					s8 ww_value = -63;//phy_txpwr_ww_lmt_value(Adapter);
1493 
1494 					_os_snprintf(powerlimit, 10, "%d", ww_value);
1495 					i += 2;
1496 
1497 				} else if (sz_line[i] == 'N' && sz_line[i + 1] == 'A') {
1498 					/*
1499 					* case "NA" assign max txgi value
1500 					* means no limitation
1501 					*/
1502 					_os_snprintf(powerlimit, 10, "%d", 127);
1503 					i += 2;
1504 
1505 				} else if ((sz_line[i] >= '0' && sz_line[i] <= '9') || sz_line[i] == '.'
1506 					|| sz_line[i] == '+' || sz_line[i] == '-') {
1507 					/* case of dBm value */
1508 					u8 integer = 0, fraction = 0, negative = 0;
1509 					u32 u4bmove;
1510 					s8 lmt = 0;
1511 
1512 					if (sz_line[i] == '+' || sz_line[i] == '-') {
1513 						if (sz_line[i] == '-')
1514 							negative = 1;
1515 						i++;
1516 					}
1517 
1518 					if (hal_get_fractionvalue_fromstring(&sz_line[i], &integer, &fraction, &u4bmove))
1519 						i += u4bmove;
1520 					else {
1521 						PHL_ERR("Limit \"%s\" is not valid decimal\n", &sz_line[i]);
1522 						struct_idx = 0;
1523 						goto exit;
1524 					}
1525 					/* transform to string of value in unit of txgi */
1526 					lmt = (integer * 4) + ((u16)fraction * 4 / 100);
1527 					if (negative)
1528 						lmt = -lmt;
1529 					_os_snprintf(powerlimit, 10, "%d", lmt);
1530 
1531 					} else {
1532 						PHL_ERR("Wrong limit expression \"%c%c\"(%d, %d)\n"
1533 							, sz_line[i], sz_line[i + 1], sz_line[i], sz_line[i + 1]);
1534 						struct_idx = 0;
1535 						goto exit;
1536 					}
1537 
1538 					/* store the power limit value */
1539 					hal_phy_store_tx_power_limit_ru(drv_priv,
1540 									(u8 *)regulation[for_cnt], (u8 *)band,
1541 									(u8 *)bandwidth, (u8 *)ratesection,
1542 									(u8 *)ntx, (u8 *)channel, (u8 *)powerlimit,
1543 									(u8 *)pshape[for_cnt],
1544 									(void*)&array_tc_txpwr_lmt_ru[struct_idx],
1545 									para_info);
1546 					PHL_DBG("array_tc_txpwr_lmt_ru[%d] \n", struct_idx);
1547 					struct_idx++;
1548 					}
1549 				}
1550 	}
1551 exit:
1552 	if (regulation) {
1553 		for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1554 			if (regulation[for_cnt]) {
1555 				_os_mem_free(drv_priv,
1556 					(u8 *)regulation[for_cnt],
1557 					_os_strlen((u8 *)regulation[for_cnt]) + 1);
1558 				regulation[for_cnt] = NULL;
1559 			}
1560 		}
1561 		_os_mem_free(drv_priv, (u8 *)regulation, sizeof(char *) * col_num);
1562 		regulation = NULL;
1563 	}
1564 	if (pshape) {
1565 		for (for_cnt = 0; for_cnt < col_num; ++for_cnt) {
1566 			if (pshape[for_cnt]) {
1567 				_os_mem_free(drv_priv,
1568 					(u8 *)pshape[for_cnt],
1569 					_os_strlen((u8 *)pshape[for_cnt]) + 1);
1570 				pshape[for_cnt] = NULL;
1571 			}
1572 		}
1573 		_os_mem_free(drv_priv, (u8 *)pshape, sizeof(char *) * col_num);
1574 		pshape = NULL;
1575 	}
1576 
1577 	return struct_idx;
1578 }
1579 
hal_phy_store_tx_power_track(void * drv_priv,char * band,char * path,char * sign,char * channel,char * rate,char * data,void * txpwr_track_table)1580 static void hal_phy_store_tx_power_track(
1581 		void *drv_priv,
1582 		char *band,
1583 		char *path,
1584 		char *sign,
1585 		char *channel,
1586 		char *rate,
1587 		char *data,
1588 		void *txpwr_track_table)
1589 {
1590 #define STR_EQUAL_5G(_band, _path, _sign, _rate, _chnl) \
1591 	((_os_strcmp(band, _band) == 0) && (_os_strcmp(path, _path) == 0) && (_os_strcmp(sign, _sign) == 0) &&\
1592 	 (_os_strcmp(rate, _rate) == 0) && (_os_strcmp(channel, _chnl) == 0)\
1593 	)
1594 #define STR_EQUAL_2G(_band, _path, _sign, _rate) \
1595 	((_os_strcmp(band, _band) == 0) && (_os_strcmp(path, _path) == 0) && (_os_strcmp(sign, _sign) == 0) &&\
1596 	 (_os_strcmp(rate, _rate) == 0)\
1597 	)
1598 
1599 #define STORE_SWING_TABLE(_array, _iteratedIdx) \
1600 	do {	\
1601 	for (token = (char *)_os_strsep(&data, delim); token != (char *)NULL; token = (char *)_os_strsep(&data, delim)) {\
1602 		_os_sscanf(token, "%d", &idx);\
1603 		_array[_iteratedIdx++] = (s8)idx;\
1604 	} } while (0)\
1605 
1606 	struct hal_txpwr_track_t *prfcalibrateInfo = (struct hal_txpwr_track_t *)txpwr_track_table;
1607 
1608 	u32	j = 0;
1609 	char	*token;
1610 	char	delim[] = ",";
1611 	u32	idx = 0;
1612 
1613 	PHL_INFO("===>initDeltaSwingIndexTables():"\
1614 		"Band: %s;\nPath: %s;\nSign: %s;\nChannel: %s;\nRate: %s;\n, Data: %s;\n",
1615 	band, path, sign, channel, rate, data);
1616 
1617 	if (STR_EQUAL_2G("2G", "A", "+", "CCK"))
1618 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2g_cck_a_p, j);
1619 	else if (STR_EQUAL_2G("2G", "A", "-", "CCK"))
1620 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2g_cck_a_n, j);
1621 	else if (STR_EQUAL_2G("2G", "B", "+", "CCK"))
1622 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2g_cck_b_p, j);
1623 	else if (STR_EQUAL_2G("2G", "B", "-", "CCK"))
1624 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2g_cck_b_n, j);
1625 	else if (STR_EQUAL_2G("2G", "A", "+", "ALL"))
1626 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2ga_p, j);
1627 	else if (STR_EQUAL_2G("2G", "A", "-", "ALL"))
1628 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2ga_n, j);
1629 	else if (STR_EQUAL_2G("2G", "B", "+", "ALL"))
1630 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2gb_p, j);
1631 	else if (STR_EQUAL_2G("2G", "B", "-", "ALL"))
1632 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_2gb_n, j);
1633 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "0"))
1634 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_p[0], j);
1635 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "0"))
1636 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_n[0], j);
1637 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "0"))
1638 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_p[0], j);
1639 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "0"))
1640 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_n[0], j);
1641 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "1"))
1642 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_p[1], j);
1643 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "1"))
1644 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_n[1], j);
1645 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "1"))
1646 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_p[1], j);
1647 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "1"))
1648 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_n[1], j);
1649 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "2"))
1650 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_p[2], j);
1651 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "2"))
1652 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_n[2], j);
1653 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "2"))
1654 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_p[2], j);
1655 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "2"))
1656 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_n[2], j);
1657 	else if (STR_EQUAL_5G("5G", "A", "+", "ALL", "3"))
1658 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_p[3], j);
1659 	else if (STR_EQUAL_5G("5G", "A", "-", "ALL", "3"))
1660 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5ga_n[3], j);
1661 	else if (STR_EQUAL_5G("5G", "B", "+", "ALL", "3"))
1662 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_p[3], j);
1663 	else if (STR_EQUAL_5G("5G", "B", "-", "ALL", "3"))
1664 		STORE_SWING_TABLE(prfcalibrateInfo->delta_swing_table_idx_5gb_n[3], j);
1665 	else
1666 		PHL_INFO("===>initDeltaSwingIndexTables(): The input is invalid!!\n");
1667 }
1668 
1669 static int
_hal_parse_txpwrtrack(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen)1670 _hal_parse_txpwrtrack(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen)
1671 {
1672 	struct rtw_para_info_t *para_info = (struct rtw_para_info_t *)para_info_t;
1673 	u32 *pdest_buf = para_info->para_data;
1674 	char *sz_line = NULL, *ptmp = NULL;
1675 	u32	i = 0;
1676 	struct hal_txpwr_track_t *txpwr_track;
1677 
1678 	if (pdest_buf == NULL || psrc_buf == NULL) {
1679 		PHL_INFO("%s, fail !!! NULL buf !!!\n", __func__);
1680 		return 0;
1681 	}
1682 	/* Assing destination buffer to be Txpwr_track table format*/
1683 	txpwr_track = (struct hal_txpwr_track_t *)pdest_buf;
1684 
1685 	ptmp = (char *)psrc_buf;
1686 	for (sz_line = hal_getLinefrombuffer(ptmp); sz_line != NULL;
1687 								sz_line = hal_getLinefrombuffer(ptmp))
1688 	{
1689 		if (!hal_is_comment_string(sz_line)) {
1690 			char band[5] = "", path[5] = "", sign[5]  = "";
1691 			char chnl[5] = "", rate[10] = "";
1692 			char data[300] = ""; /* 100 is too small */
1693 
1694 			if (_os_strlen((u8 *)sz_line) < 10 || sz_line[0] != '[')
1695 				continue;
1696 
1697 			_os_strncpy(band, sz_line + 1, 2);
1698 			_os_strncpy(path, sz_line + 5, 1);
1699 			_os_strncpy(sign, sz_line + 8, 1);
1700 
1701 			i = 10; /* sz_line+10 */
1702 			if (!hal_parse_fiedstring(sz_line, &i, rate, '[', ']')) {
1703 				PHL_ERR("Fail to parse rate!\n");
1704 			}
1705 			if (!hal_parse_fiedstring(sz_line, &i, chnl, '[', ']')) {
1706 				if (!_os_strcmp("5G",band))
1707 					PHL_ERR("Fail to parse channel group!\n");
1708 			}
1709 			while (i < _os_strlen((u8 *)sz_line) && '{' != sz_line[i])
1710 				i++;
1711 			if (!hal_parse_fiedstring(sz_line, &i, data, '{', '}')) {
1712 				PHL_ERR("Fail to parse data!\n");
1713 			}
1714 			hal_phy_store_tx_power_track(drv_priv,
1715 						band, path, sign,
1716 						chnl, rate, data,
1717 						(void*)txpwr_track);
1718 		}
1719 	}
1720 	return 1;
1721 }
1722 
1723 void
_hal_dl_para_file(struct rtw_phl_com_t * phl_com,void * para_info_t,char * ic_name,int (* parser_fun)(void * drv_priv,void * para_info_t,u8 * psrc_buf,u32 buflen),const char * file_name)1724 _hal_dl_para_file(struct rtw_phl_com_t *phl_com,
1725 	void *para_info_t, char *ic_name,
1726 	int (*parser_fun)(void *drv_priv, void *para_info_t, u8 *psrc_buf, u32 buflen),
1727 	const char *file_name)
1728 {
1729 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
1730 
1731 	void *drv = phl_com->drv_priv;
1732 	char hal_phy_folder[MAX_PATH_LEN] = {0};
1733 	char para_file_name[MAX_PATH_LEN] = {0};
1734 	char *sp, *ext = NULL;
1735 	u8 i, dot_pos;
1736 	u32 para_size = 0, postfix_size = 0;
1737 	u8 *para_buf = NULL;
1738 	struct rtw_para_info_t *para_info = (struct rtw_para_info_t *)para_info_t;
1739 
1740 	if (para_info->para_src == RTW_PARA_SRC_INTNAL) {
1741 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "%s.parser_fun=NULL \n", file_name);
1742 		return;
1743 	}
1744 
1745 	if (!parser_fun || (!para_info->para_data)) {
1746 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "%s.parser_fun=NULL \n", file_name);
1747 		para_info->para_src = RTW_PARA_SRC_INTNAL;
1748 		return;
1749 	}
1750 
1751 	if ((para_info->para_data_len != 0) && (para_info->para_src == RTW_PARA_SRC_EXTNAL)) {
1752 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "%s. para_data_len != 0 !!!\n", file_name);
1753 		return;
1754 	}
1755 
1756 	para_buf = _os_mem_alloc(drv, MAX_HWCONFIG_FILE_CONTENT);
1757 	if (!para_buf) {
1758 		PHL_TRACE(COMP_PHL_DBG, _PHL_DEBUG_, "para_buf=NULL \n");
1759 		para_info->para_src = RTW_PARA_SRC_INTNAL;
1760 		return;
1761 	}
1762 
1763 
1764 	if (para_info->para_src == RTW_PARA_SRC_EXTNAL_BUF) {
1765 		if (para_info->ext_para_file_buf != 0) {
1766 			/* Parsing file content */
1767 			para_info->para_data_len =
1768 				parser_fun(drv, para_info,
1769 					   para_info->ext_para_file_buf,
1770 					   para_info->ext_para_file_buf_len);
1771 
1772 			if (para_info->para_data_len) {
1773 				PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
1774 					"%s:: Download file ok.\n", __FUNCTION__);
1775 			} else {
1776 				PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
1777 					"%s:: Failed to parser %s \n",
1778 					__FUNCTION__, file_name);
1779 				para_info->para_src = RTW_PARA_SRC_INTNAL;
1780 			}
1781 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s:: Download file ok.\n", file_name);
1782 		} else {
1783 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s:: Error reading file.\n", file_name);
1784 
1785 			para_info->para_src = RTW_PARA_SRC_INTNAL;
1786 			para_info->para_data_len = 0;
1787 		}
1788 	} else if (para_info->para_src == RTW_PARA_SRC_EXTNAL) {
1789 		_os_snprintf(para_info->para_path, MAX_PATH_LEN, "%s%s%s%s",
1790 			     hal_phy_folder ,ic_name, _os_path_sep, file_name);
1791 
1792 		/* Determine parameter folder path */
1793 		if (para_info->hal_phy_folder != NULL) {
1794 			_os_snprintf(hal_phy_folder, MAX_PATH_LEN, "%s",
1795 						 para_info->hal_phy_folder);
1796 		} else {
1797 			_os_snprintf(hal_phy_folder, MAX_PATH_LEN, "%s%s%s",
1798 					     HAL_FILE_CONFIG_PATH , ic_name, _os_path_sep);
1799 		}
1800 
1801 		/* Determine parameter file name */
1802 		_os_strncpy(para_file_name, file_name, _os_strlen((u8 *)file_name)+1);
1803 
1804 		/* Add postfix into original file name if it is specified by user */
1805 		postfix_size = _os_strlen((u8 *)para_info->postfix);
1806 
1807 		if (postfix_size != 0) {
1808 			/* find the position of latest dot char in file name */
1809 			sp = para_file_name;
1810 			for (i = 0, dot_pos = 0; i < _os_strlen((u8 *)file_name); i++) {
1811 				if (sp[i] == '.')
1812 					dot_pos = i;
1813 			}
1814 
1815 			/* Get file extension name from original file name string */
1816 			ext = (char *)file_name + dot_pos;
1817 
1818 			/* Attach postfix, extension name and null terminator */
1819 			_os_strncpy(sp + dot_pos, para_info->postfix, postfix_size);
1820 			_os_strncpy(sp + dot_pos + postfix_size, ext, _os_strlen((u8 *)ext));
1821 			*(sp + dot_pos + postfix_size + _os_strlen((u8 *)ext)) = '\0';
1822 		}
1823 
1824 		/* Generate final parameter file full path */
1825 		_os_snprintf(para_info->para_path, MAX_PATH_LEN, "%s%s",
1826 				 hal_phy_folder, para_file_name);
1827 
1828 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s:: %s\n",__FUNCTION__,
1829 			  para_info->para_path);
1830 
1831 		para_size = _os_read_file(para_info->para_path, para_buf,
1832 					  MAX_HWCONFIG_FILE_CONTENT);
1833 	} else if (para_info->para_src == RTW_PARA_SRC_CUSTOM) {
1834 		_os_mem_cpy(drv, para_buf, para_info->para_data, para_info->para_data_len);
1835 		_os_mem_set(drv, para_info->para_data, 0, para_info->para_data_len);
1836 		para_size = para_info->para_data_len;
1837 		para_info->para_data_len = 0;
1838 	}
1839 
1840 	if (para_size != 0) {
1841 		/* Parsing file content */
1842 		para_info->para_data_len = parser_fun(drv, para_info, para_buf,
1843 						      para_size);
1844 
1845 		if (para_info->para_data_len) {
1846 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
1847 				  "%s:: Download file ok.\n", __FUNCTION__);
1848 		} else {
1849 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
1850 			"%s::Failed to parser %s \n",
1851 			__FUNCTION__, file_name);
1852 			para_info->para_src = RTW_PARA_SRC_INTNAL;
1853 		}
1854 	} else {
1855 		PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "%s:: Error reading file.\n",
1856 			  file_name);
1857 
1858 		para_info->para_src = RTW_PARA_SRC_INTNAL;
1859 		para_info->para_data_len = 0;
1860 	}
1861 	_os_mem_free(drv, para_buf, MAX_HWCONFIG_FILE_CONTENT);
1862 #endif
1863 }
1864 
1865 enum rtw_hal_status
_phl_pwrlmt_para_alloc(struct rtw_phl_com_t * phl_com,struct rtw_para_pwrlmt_info_t * para_info)1866 _phl_pwrlmt_para_alloc(struct rtw_phl_com_t* phl_com,
1867 				struct rtw_para_pwrlmt_info_t *para_info)
1868 {
1869 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
1870 	if (para_info->para_src == RTW_PARA_SRC_EXTNAL) {
1871 		u32 file_buf_sz = MAX_HWCONFIG_FILE_CONTENT;
1872 		u32 buf_sz = MAX_LINES_HWCONFIG_TXT;
1873 		void *drv = phl_com->drv_priv;
1874 		u8 para_regd_str_arridx;
1875 		const char * const *_para_regd_str = rtw_hal_rf_get_predefined_pw_lmt_regu_type_str_array(&para_regd_str_arridx);
1876 		u8 i = 0;
1877 
1878 		for (i = 0; i < para_regd_str_arridx ; i++) {
1879 			_os_strcpy(para_info->ext_regd_name[i] , _para_regd_str[i]);
1880 			PHL_INFO(" prepare ext_regd_name[%d] = %s",
1881 					i , para_info->ext_regd_name[i]);
1882 		}
1883 		para_info->ext_regd_arridx = para_regd_str_arridx;
1884 
1885 		para_info->para_data = _os_mem_alloc(drv, file_buf_sz * sizeof(u32));
1886 		if (!para_info->para_data) {
1887 			PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
1888 				"%s::para_data allocmem fail\n",__FUNCTION__);
1889 			return RTW_HAL_STATUS_FAILURE;
1890 		}
1891 
1892 		para_info->ext_reg_codemap = _os_mem_alloc(drv, buf_sz * sizeof(u8));
1893 		if (!para_info->ext_reg_codemap) {
1894 			if (para_info->para_data)
1895 				_os_mem_free(drv, para_info->para_data, file_buf_sz * sizeof(u32));
1896 			para_info->para_data = NULL;
1897 			PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
1898 				"%s::ext_reg_codemap allocmem fail\n",__FUNCTION__);
1899 			return RTW_HAL_STATUS_FAILURE;
1900 		}
1901 		return RTW_HAL_STATUS_SUCCESS;
1902 	} else
1903 		return RTW_HAL_STATUS_FAILURE;
1904 #else
1905 	return RTW_HAL_STATUS_FAILURE;
1906 #endif
1907 }
1908 
1909 enum rtw_hal_status
phl_load_file_data_alloc(struct rtw_phl_com_t * phl_com,struct rtw_para_info_t * para_info)1910 phl_load_file_data_alloc(struct rtw_phl_com_t* phl_com, struct rtw_para_info_t *para_info)
1911 {
1912 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
1913 	u32 buf_sz = MAX_HWCONFIG_FILE_CONTENT;
1914 	void *drv = phl_com->drv_priv;
1915 
1916 	if (para_info->para_src == RTW_PARA_SRC_EXTNAL) {
1917 		if (para_info->para_data_len == 0) {
1918 			para_info->para_data = _os_mem_alloc(drv, buf_sz * sizeof(u32));
1919 	}
1920 	if (!para_info->para_data) {
1921 			PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
1922 				"%s:: allocmem fail\n",__FUNCTION__);
1923 			return RTW_HAL_STATUS_FAILURE;
1924 		}
1925 		return RTW_HAL_STATUS_SUCCESS;
1926 	} else
1927 		return RTW_HAL_STATUS_FAILURE;
1928 #else
1929 	return RTW_HAL_STATUS_FAILURE;
1930 #endif
1931 }
1932 
1933 void
rtw_hal_dl_all_para_file(struct rtw_phl_com_t * phl_com,char * ic_name,void * hal)1934 rtw_hal_dl_all_para_file(struct rtw_phl_com_t *phl_com,
1935 							char *ic_name, void *hal)
1936 {
1937 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
1938 	struct hal_info_t *hal_info = hal;
1939 	struct phy_sw_cap_t *phy_sw_cap = NULL;
1940 	u8 idx=0;
1941 	u8 max_phy_num = 1;
1942 
1943 	if (hal_info->hal_com->dbcc_en == true)
1944 		max_phy_num = 2;
1945 
1946 	for (idx=0; idx < max_phy_num; idx++) {/*Temp modiy for 1 BB phy Reg file */
1947 
1948 		phy_sw_cap = &phl_com->phy_sw_cap[idx];
1949 		if (phl_load_file_data_alloc(phl_com,
1950 					&phy_sw_cap->bb_phy_reg_info) == RTW_HAL_STATUS_SUCCESS)
1951 			_hal_dl_para_file(phl_com,
1952 					&phy_sw_cap->bb_phy_reg_info,
1953 					ic_name,
1954 					_hal_parse_phyreg,
1955 					"PHY_REG.txt");
1956 
1957 		if (phl_load_file_data_alloc(phl_com,
1958 					&phy_sw_cap->bb_phy_reg_gain_info) == RTW_HAL_STATUS_SUCCESS)
1959 			_hal_dl_para_file(phl_com,
1960 					&phy_sw_cap->bb_phy_reg_gain_info,
1961 					ic_name,
1962 					_hal_parse_phyreg,
1963 					"PHY_REG_GAIN.txt");
1964 
1965 		if (phl_load_file_data_alloc(phl_com,
1966 					&phy_sw_cap->rf_radio_a_info) == RTW_HAL_STATUS_SUCCESS)
1967 			_hal_dl_para_file(phl_com,
1968 					&phy_sw_cap->rf_radio_a_info,
1969 					ic_name,
1970 					_hal_parse_radio,
1971 					"RadioA.txt");
1972 
1973 		if (phl_load_file_data_alloc(phl_com,
1974 					&phy_sw_cap->rf_radio_b_info) == RTW_HAL_STATUS_SUCCESS)
1975 			_hal_dl_para_file(phl_com,
1976 					&phy_sw_cap->rf_radio_b_info,
1977 					ic_name,
1978 					_hal_parse_radio,
1979 					"RadioB.txt");
1980 
1981 		if (phl_load_file_data_alloc(phl_com,
1982 				&phy_sw_cap->rf_txpwr_byrate_info) == RTW_HAL_STATUS_SUCCESS)
1983 			_hal_dl_para_file(phl_com,
1984 					&phy_sw_cap->rf_txpwr_byrate_info,
1985 					ic_name,
1986 					_hal_parse_txpwr_by_rate,
1987 					"TXPWR_ByRate.txt");
1988 
1989 		if (phl_load_file_data_alloc(phl_com,
1990 				&phy_sw_cap->rf_txpwrtrack_info) == RTW_HAL_STATUS_SUCCESS)
1991 			_hal_dl_para_file(phl_com,
1992 					&phy_sw_cap->rf_txpwrtrack_info,
1993 					ic_name,
1994 					_hal_parse_txpwrtrack,
1995 					"TXPWR_TrackTSSI.txt");
1996 
1997 		if (_phl_pwrlmt_para_alloc(phl_com,
1998 				&phy_sw_cap->rf_txpwrlmt_info) == RTW_HAL_STATUS_SUCCESS)
1999 			_hal_dl_para_file(phl_com,
2000 					&phy_sw_cap->rf_txpwrlmt_info,
2001 					ic_name,
2002 					_hal_parse_txpwrlmt,
2003 					"TXPWR_LMT.txt");
2004 
2005 		if (_phl_pwrlmt_para_alloc(phl_com,
2006 				&phy_sw_cap->rf_txpwrlmt_ru_info) == RTW_HAL_STATUS_SUCCESS)
2007 			_hal_dl_para_file(phl_com,
2008 					&phy_sw_cap->rf_txpwrlmt_ru_info,
2009 					ic_name,
2010 					_hal_parse_txpwrlmt_ru,
2011 					"TXPWR_LMT_RU.txt");
2012 	}
2013 #endif
2014 }
2015 
rtw_hal_ld_fw_symbol(struct rtw_phl_com_t * phl_com,struct rtw_hal_com_t * hal_com,const char * name,u8 ** buf,u32 * buf_size)2016 u8 rtw_hal_ld_fw_symbol(struct rtw_phl_com_t *phl_com,
2017 	struct rtw_hal_com_t *hal_com, const char *name, u8 **buf, u32 *buf_size)
2018 {
2019 	struct rtw_fw_info_t *fw_info = &phl_com->fw_info;
2020 	char path[256] = {0};
2021 	char *ic_name = NULL;
2022 	char *intf = NULL;
2023 	void *d = phlcom_to_drvpriv(phl_com);
2024 
2025 	switch (phl_com->hci_type) {
2026 	case RTW_HCI_PCIE:
2027 		intf = "e";
2028 		break;
2029 	case RTW_HCI_USB:
2030 		intf = "u";
2031 		break;
2032 	case RTW_HCI_SDIO:
2033 		intf = "s";
2034 		break;
2035 	default:
2036 		PHL_WARN("%s unknown hci type %u \n", __func__, phl_com->hci_type);
2037 		return (u8)RTW_HAL_STATUS_FAILURE;
2038 	}
2039 
2040 	switch (hal_com->chip_id) {
2041 	case CHIP_WIFI6_8852A:
2042 		ic_name = "rtl8852a";
2043 		break;
2044 	case CHIP_WIFI6_8852B:
2045 		ic_name = "rtl8852b";
2046 		break;
2047 	default:
2048 		PHL_WARN("%s unknown chip id %u \n", __func__, hal_com->chip_id);
2049 		return (u8)RTW_HAL_STATUS_FAILURE;
2050 	}
2051 
2052 	if (name == NULL || buf_size == NULL)
2053 		return (u8)RTW_HAL_STATUS_FAILURE;
2054 
2055 	if (!fw_info->sym_buf) {
2056 
2057 		fw_info->sym_buf = _os_mem_alloc(d, RTW_MAX_FW_SIZE);
2058 		if (!fw_info->sym_buf) {
2059 			PHL_WARN("%s : buf for fw symbol allocate fail!!\n", __func__);
2060 			return (u8)RTW_HAL_STATUS_FAILURE;
2061 		}
2062 	}
2063 	_os_snprintf(path, MAX_PATH_LEN, "%s%s%s%s%s", FW_FILE_CONFIG_PATH,
2064 		     ic_name, intf, _os_path_sep, name);
2065 
2066 	PHL_INFO("%s : %s\n", __func__, path);
2067 
2068 	fw_info->sym_buf_size = _os_read_file(path, fw_info->sym_buf,
2069 		RTW_MAX_FW_SIZE);
2070 	/* reading fw file failed */
2071 	if (0 == fw_info->sym_buf_size)
2072 		return (u8)RTW_HAL_STATUS_FAILURE;
2073 
2074 	*buf = fw_info->sym_buf;
2075 	*buf_size = fw_info->sym_buf_size;
2076 
2077 	return (u8)RTW_HAL_STATUS_SUCCESS;
2078 }
2079 
rtw_hal_efuse_shadow_file_load(void * hal,char * ic_name,bool is_limit)2080 u8 rtw_hal_efuse_shadow_file_load(void *hal, char *ic_name, bool is_limit)
2081 {
2082 	u8 status = true;
2083 #ifdef CONFIG_EFUSE_CONFIG_FILE
2084 	struct rtw_hal_com_t *hal_com = (struct rtw_hal_com_t *)hal;
2085 	struct hal_info_t *hal_info = (struct hal_info_t *)hal_com->hal_priv;
2086 	char *hal_phy_folder = HAL_FILE_CONFIG_PATH;
2087 	char file_path[256];
2088 
2089 	_os_snprintf(file_path, MAX_PATH_LEN, "%s%s%s%s",
2090 			hal_phy_folder , ic_name, _os_path_sep, "efuse.map");
2091 	PHL_INFO("%s::open map path: %s\n", __FUNCTION__, file_path);
2092 
2093 	status = rtw_hal_efuse_file_map_load(hal_info, file_path, is_limit);
2094 	if (status == RTW_HAL_STATUS_FAILURE) {
2095 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_,
2096 				"%s:: %s FAIL\n", __FUNCTION__, file_path);
2097 		status = false;
2098 		goto exit;
2099 	}
2100 
2101 	_os_snprintf(file_path, MAX_PATH_LEN, "%s%s%s%s",
2102 			hal_phy_folder , ic_name, _os_path_sep, "efuse.mask");
2103 	PHL_INFO("%s::open mask path: %s\n", __FUNCTION__, file_path);
2104 
2105 	status = rtw_hal_efuse_file_mask_load(hal_info, file_path, is_limit);
2106 	if (status == RTW_HAL_STATUS_FAILURE) {
2107 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_,
2108 				"%s:: %s FAIL\n", __FUNCTION__, file_path);
2109 		status = false;
2110 		goto exit;
2111 	}
2112 exit:
2113 #endif
2114 	return status;
2115 }
2116 
2117