• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }