1 /*
2 * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 /**************************************************************************
17 * File Name : tls_efuse.c
18 * Author :
19 * Version :
20 * Date :
21 * Description : Use Flash Addr as virtual efuse
22 *
23 * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
24 * All rights reserved.
25 *
26 ***************************************************************************/
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include "wm_debug.h"
31 #include "wm_regs.h"
32 #include "wm_config.h"
33 #include "list.h"
34 #include "wm_internal_flash.h"
35 #include "wm_crypto_hard.h"
36 #include "wm_mem.h"
37 #include "wm_efuse.h"
38
39 #define USE_OTA_FT_PARAM 0
40 #include "wm_flash_map.h"
41
42 #define FT_MAGICNUM_ADDR (FLASH_BASE_ADDR)
43 #define MAGICNUM_LEN (4)
44 #define MAC_ADDR_LEN (8)
45 #define FT_GAIN_LEN (84)
46
47 typedef struct FT_PARAM {
48 unsigned int magic_no;
49 unsigned int checksum;
50 unsigned char wifi_mac_addr[MAC_ADDR_LEN];
51 unsigned char bt_mac_addr[MAC_ADDR_LEN];
52 unsigned int tx_dcoffset;
53 unsigned int rx_dcoffset;
54 unsigned int tx_iq_gain;
55 unsigned int rx_iq_gain;
56 unsigned int tx_iq_phase;
57 unsigned int rx_iq_phase;
58 unsigned char tx_gain[FT_GAIN_LEN];
59 }FT_PARAM_ST;
60
61 static u8 default_mac[6] = {0x00, 0x25, 0x08, 0x09, 0x01, 0x0F};
62
63 FT_PARAM_ST gftParam;
tls_ft_param_init(void)64 int tls_ft_param_init(void)
65 {
66 u32 crcvalue = 0;
67 psCrcContext_t ctx;
68 FT_PARAM_ST *pft = NULL;
69
70 if (gftParam.magic_no == SIGNATURE_WORD) {
71 return TRUE;
72 }
73
74 pft = tls_mem_alloc(sizeof(FT_PARAM_ST));
75 if (pft == NULL) {
76 return FALSE;
77 }
78
79 memset_s(pft, sizeof(pft), 0xFF, sizeof(FT_PARAM_ST));
80 memset_s(&gftParam, sizeof(gftParam), 0xFF, sizeof(FT_PARAM_ST));
81
82 tls_fls_read(FT_MAGICNUM_ADDR, (unsigned char *)pft, sizeof(FT_PARAM_ST));
83 if (pft->magic_no == SIGNATURE_WORD) {
84 tls_crypto_init();
85 tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
86 tls_crypto_crc_update(&ctx, (unsigned char *)pft + 8, sizeof(FT_PARAM_ST) - 8);
87 tls_crypto_crc_final(&ctx, &crcvalue);
88 if (pft->checksum != crcvalue) {
89 tls_mem_free(pft);
90 return FALSE;
91 }
92
93 if (gftParam.magic_no != SIGNATURE_WORD) {
94 memcpy_s(&gftParam, sizeof(gftParam), pft, sizeof(FT_PARAM_ST));
95 }
96 }
97 tls_mem_free(pft);
98
99 /* lock parameter */
100 tls_flash_unlock();
101 return TRUE;
102 }
103
tls_ft_param_get(unsigned int opnum,void * data,unsigned int rdlen)104 int tls_ft_param_get(unsigned int opnum, void *data, unsigned int rdlen)
105 {
106 switch (opnum) {
107 case CMD_WIFI_MAC: /* MAC */
108 if ((gftParam.wifi_mac_addr[0]&0x1)
109 ||(0 == (gftParam.wifi_mac_addr[0]|gftParam.wifi_mac_addr[1]|gftParam.wifi_mac_addr[2]|
110 gftParam.wifi_mac_addr[3]|gftParam.wifi_mac_addr[4]|gftParam.wifi_mac_addr[5]))) {
111 memcpy_s(data, sizeof(data), default_mac, rdlen);
112 } else {
113 memcpy_s(data, sizeof(data), gftParam.wifi_mac_addr, rdlen);
114 }
115 break;
116 case CMD_BT_MAC: /* MAC */
117 {
118 u8 invalid_bt_mac[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
119 u8 invalid_bt_mac1[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
120 if ((memcmp(gftParam.bt_mac_addr, invalid_bt_mac, 6) == 0)|| \
121 (memcmp(gftParam.bt_mac_addr, invalid_bt_mac1, 6) == 0)) {
122 memcpy_s(data, sizeof(data), default_mac, rdlen);
123 *((u8*)data+5) +=1; /* defalut plus 1 */
124 *((u8*)data) |= 0xC0; /* defalut public static type */
125 } else {
126 memcpy_s(data, sizeof(data), gftParam.bt_mac_addr, rdlen);
127 }
128 }
129 break;
130
131 case CMD_TX_DC: /* tx_dcoffset */
132 *(unsigned int *)data = gftParam.tx_dcoffset;
133 break;
134
135 case CMD_RX_DC: /* rx_dcoffset */
136 *(unsigned int *)data = gftParam.rx_dcoffset;
137 break;
138
139 case CMD_TX_IQ_GAIN:
140 *(unsigned int *)data = gftParam.tx_iq_gain;
141 break;
142
143 case CMD_RX_IQ_GAIN:
144 *(unsigned int *)data = gftParam.rx_iq_gain;
145 break;
146
147 case CMD_TX_IQ_PHASE:
148 *(unsigned int *)data = gftParam.tx_iq_phase;
149 break;
150
151 case CMD_RX_IQ_PHASE:
152 *(unsigned int *)data = gftParam.rx_iq_phase;
153 break;
154
155 case CMD_TX_GAIN: /* gain */
156 if (rdlen < FT_GAIN_LEN) {
157 memcpy_s(data, sizeof(data), gftParam.tx_gain, rdlen);
158 } else {
159 memcpy_s(data, sizeof(data), gftParam.tx_gain, FT_GAIN_LEN);
160 }
161 break;
162
163 default:
164 return -1;
165 }
166 return 0;
167 }
168
tls_ft_param_set(unsigned int opnum,void * data,unsigned int len)169 int tls_ft_param_set(unsigned int opnum, void *data, unsigned int len)
170 {
171 psCrcContext_t ctx;
172 unsigned int writelen = 0;
173
174 if (!data || !len) {
175 return -1;
176 }
177 switch (opnum) {
178 case CMD_WIFI_MAC: /* MAC */
179 memcpy_s(gftParam.wifi_mac_addr, sizeof(gftParam.wifi_mac_addr), (unsigned char *)data, len);
180 break;
181
182 case CMD_BT_MAC: /* BT MAC */
183 memcpy_s(gftParam.bt_mac_addr, sizeof(gftParam.bt_mac_addr), (unsigned char *)data, len);
184 break;
185
186 case CMD_TX_DC: /* tx_dcoffset */
187 gftParam.tx_dcoffset = *(unsigned int *)data;
188 break;
189
190 case CMD_RX_DC: /* rx_dcoffset */
191 gftParam.rx_dcoffset = *(unsigned int *)data;
192 break;
193
194 case CMD_TX_IQ_GAIN:
195 gftParam.tx_iq_gain = *(unsigned int *)data;
196 break;
197
198 case CMD_RX_IQ_GAIN:
199 gftParam.rx_iq_gain = *(unsigned int *) data;
200 break;
201
202 case CMD_TX_IQ_PHASE:
203 gftParam.tx_iq_phase = *(unsigned int *)data;
204 break;
205
206 case CMD_RX_IQ_PHASE:
207 gftParam.rx_iq_phase = *(unsigned int *) data;
208 break;
209
210 case CMD_TX_GAIN: /* gain */
211 if (len >= FT_GAIN_LEN) {
212 writelen = FT_GAIN_LEN;
213 } else {
214 writelen = len;
215 }
216 memcpy_s(gftParam.tx_gain, sizeof(gftParam.tx_gain), data, writelen);
217 break;
218
219 default:
220 return -1;
221 }
222
223 tls_crypto_init();
224 tls_crypto_crc_init(&ctx, 0xFFFFFFFF, CRYPTO_CRC_TYPE_32, INPUT_REFLECT | OUTPUT_REFLECT);
225 gftParam.magic_no = SIGNATURE_WORD;
226 tls_crypto_crc_update(&ctx, (unsigned char *)&gftParam + 8, sizeof(gftParam) -8);
227 tls_crypto_crc_final(&ctx, &gftParam.checksum);
228 tls_flash_unlock();
229 tls_fls_write(FT_MAGICNUM_ADDR, (unsigned char *)&gftParam, sizeof(gftParam));
230 tls_flash_lock();
231 return 0;
232 }
233
234 /**********************************************************************************************************
235 * Description: This function is used to get mac addr.
236 *
237 * Arguments : mac mac addr,6 byte
238 *
239 * Returns : TLS_EFUSE_STATUS_OK get success
240 * TLS_EFUSE_STATUS_EIO get failed
241 **********************************************************************************************************/
tls_get_mac_addr(u8 * mac)242 int tls_get_mac_addr(u8 *mac)
243 {
244 return tls_ft_param_get(CMD_WIFI_MAC, mac, 6);
245 }
246
247 /**********************************************************************************************************
248 * Description: This function is used to set mac addr.
249 *
250 * Arguments : mac mac addr,6 byte
251 *
252 * Returns : TLS_EFUSE_STATUS_OK get success
253 * TLS_EFUSE_STATUS_EIO get failed
254 **********************************************************************************************************/
tls_set_mac_addr(u8 * mac)255 int tls_set_mac_addr(u8 *mac)
256 {
257 return tls_ft_param_set(CMD_WIFI_MAC, mac, 6);
258 }
259
260 /**********************************************************************************************************
261 * Description: This function is used to get bluetooth mac addr.
262 *
263 * Arguments : mac mac addr,6 byte
264 *
265 * Returns : TLS_EFUSE_STATUS_OK get success
266 * TLS_EFUSE_STATUS_EIO get failed
267 **********************************************************************************************************/
tls_get_bt_mac_addr(u8 * mac)268 int tls_get_bt_mac_addr(u8 *mac)
269 {
270 return tls_ft_param_get(CMD_BT_MAC, mac, 6);
271 }
272
273 /**********************************************************************************************************
274 * Description: This function is used to set bluetooth mac addr.
275 *
276 * Arguments : mac mac addr,6 byte
277 *
278 * Returns : TLS_EFUSE_STATUS_OK get success
279 * TLS_EFUSE_STATUS_EIO get failed
280 **********************************************************************************************************/
tls_set_bt_mac_addr(u8 * mac)281 int tls_set_bt_mac_addr(u8 *mac)
282 {
283 return tls_ft_param_set(CMD_BT_MAC, mac, 6);
284 }
285
286 /**********************************************************************************************************
287 * Description: This function is used to get tx lod.
288 *
289 * Arguments : *txlo
290 *
291 * Returns : 0 get success
292 * -1 get failed
293 **********************************************************************************************************/
tls_get_tx_lo(u8 * txlo)294 int tls_get_tx_lo(u8 *txlo)
295 {
296 return tls_ft_param_get(CMD_TX_DC, txlo, 4);
297 }
298
299 /**********************************************************************************************************
300 * Description: This function is used to set tx lo.
301 *
302 * Arguments : txlo
303 *
304 * Returns : 0 set success
305 * -1 set failed
306 **********************************************************************************************************/
tls_set_tx_lo(u8 * txlo)307 int tls_set_tx_lo(u8 *txlo)
308 {
309 return tls_ft_param_set(CMD_TX_DC, txlo, 4);
310 }
311
312 /**********************************************************************************************************
313 * Description: This function is used to get tx iq gain.
314 *
315 * Arguments : txGain
316 *
317 * Returns : 0 set success
318 * -1 set failed
319 **********************************************************************************************************/
tls_get_tx_iq_gain(u8 * txGain)320 int tls_get_tx_iq_gain(u8 *txGain)
321 {
322 return tls_ft_param_get(CMD_TX_IQ_GAIN, txGain, 4);
323 }
324
325 /**********************************************************************************************************
326 * Description: This function is used to set tx iq gain.
327 *
328 * Arguments : txGain
329 *
330 * Returns : 0 set success
331 * -1 set failed
332 **********************************************************************************************************/
tls_set_tx_iq_gain(u8 * txGain)333 int tls_set_tx_iq_gain(u8 *txGain)
334 {
335 return tls_ft_param_set(CMD_TX_IQ_GAIN, txGain, 4);
336 }
337
338 /**********************************************************************************************************
339 * Description: This function is used to get rx iq gain.
340 *
341 * Arguments : rxGain
342 *
343 * Returns : 0 set success
344 * -1 set failed
345 **********************************************************************************************************/
tls_get_rx_iq_gain(u8 * rxGain)346 int tls_get_rx_iq_gain(u8 *rxGain)
347 {
348 return tls_ft_param_get(CMD_RX_IQ_GAIN, rxGain, 4);
349 }
350
351 /**********************************************************************************************************
352 * Description: This function is used to set rx iq gain.
353 *
354 * Arguments : rxGain
355 *
356 * Returns : 0 set success
357 * -1 set failed
358 **********************************************************************************************************/
tls_set_rx_iq_gain(u8 * rxGain)359 int tls_set_rx_iq_gain(u8 *rxGain)
360 {
361 return tls_ft_param_set(CMD_RX_IQ_GAIN, rxGain, 4);
362 }
363
364 /**********************************************************************************************************
365 * Description: This function is used to get tx iq phase.
366 *
367 * Arguments : txPhase
368 *
369 * Returns : 0 set success
370 * -1 set failed
371 **********************************************************************************************************/
tls_get_tx_iq_phase(u8 * txPhase)372 int tls_get_tx_iq_phase(u8 *txPhase)
373 {
374 return tls_ft_param_get(CMD_TX_IQ_PHASE, txPhase, 4);
375 }
376
377 /**********************************************************************************************************
378 * Description: This function is used to set tx iq phase.
379 *
380 * Arguments : txPhase
381 *
382 * Returns : 0 set success
383 * -1 set failed
384 **********************************************************************************************************/
tls_set_tx_iq_phase(u8 * txPhase)385 int tls_set_tx_iq_phase(u8 *txPhase)
386 {
387 return tls_ft_param_set(CMD_TX_IQ_PHASE, txPhase, 4);
388 }
389
390 /**********************************************************************************************************
391 * Description: This function is used to get rx iq phase.
392 *
393 * Arguments : rxPhase
394 *
395 * Returns : 0 set success
396 * -1 set failed
397 **********************************************************************************************************/
tls_get_rx_iq_phase(u8 * rxPhase)398 int tls_get_rx_iq_phase(u8 *rxPhase)
399 {
400 return tls_ft_param_get(CMD_RX_IQ_PHASE, rxPhase, 4);
401 }
402
403 /**********************************************************************************************************
404 * Description: This function is used to set tx iq phase.
405 *
406 * Arguments : rxPhase
407 *
408 * Returns : 0 set success
409 * -1 set failed
410 **********************************************************************************************************/
tls_set_rx_iq_phase(u8 * rxPhase)411 int tls_set_rx_iq_phase(u8 *rxPhase)
412 {
413 return tls_ft_param_set(CMD_RX_IQ_PHASE, rxPhase, 4);
414 }
415
tls_freq_err_op(u8 * freqerr,u8 flag)416 int tls_freq_err_op(u8 *freqerr, u8 flag)
417 {
418 int ret = 0;
419 tls_flash_unlock();
420 if (flag) {
421 ret = tls_fls_write(FREQERR_ADDR, freqerr, FREQERR_LEN);
422 } else {
423 ret = tls_fls_read(FREQERR_ADDR, freqerr, FREQERR_LEN);
424 }
425 tls_flash_lock();
426 if (ret == 0) {
427 return TLS_EFUSE_STATUS_OK;
428 } else {
429 return TLS_EFUSE_STATUS_EINVALID;
430 }
431 }
432
tls_rf_cal_finish_op(u8 * calflag,u8 flag)433 int tls_rf_cal_finish_op(u8 *calflag, u8 flag)
434 {
435 int ret = 0;
436 tls_flash_unlock();
437 if (flag) {
438 ret = tls_fls_write(CAL_FLAG_ADDR, calflag, CAL_FLAG_LEN);
439 } else {
440 ret = tls_fls_read(CAL_FLAG_ADDR, calflag, CAL_FLAG_LEN);
441 }
442 tls_flash_lock();
443
444 if (ret == 0) {
445 return TLS_EFUSE_STATUS_OK;
446 } else {
447 return TLS_EFUSE_STATUS_EINVALID;
448 }
449 }
450
451 /**********************************************************************************************************
452 * Description: This function is used to get tx gain.
453 *
454 * Arguments : txgain tx gain
455 *
456 * Returns : 0 get success
457 * -1 get failed
458 **********************************************************************************************************/
tls_get_tx_gain(u8 * txgain)459 int tls_get_tx_gain(u8 *txgain)
460 {
461 return tls_ft_param_get(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
462 }
463
464 /**********************************************************************************************************
465 * Description: This function is used to set tx gain.
466 *
467 * Arguments : txgain tx gain
468 *
469 * Returns : 0 set success
470 * -1 set failed
471 **********************************************************************************************************/
tls_set_tx_gain(u8 * txgain)472 int tls_set_tx_gain(u8 *txgain)
473 {
474 return tls_ft_param_set(CMD_TX_GAIN, txgain, TX_GAIN_LEN);
475 }