1 /**
2  *
3  * \file
4  *
5  * \brief This module contains NMC1500 ASIC specific internal APIs.
6  *
7  * Copyright (c) 2016-2017 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
27  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
29  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
30  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  *
38  * \asf_license_stop
39  *
40  */
41 
42 #include "common/include/nm_common.h"
43 #include "driver/source/nmbus.h"
44 #include "bsp/include/nm_bsp.h"
45 #include "driver/source/nmasic.h"
46 #include "driver/include/m2m_types.h"
47 
48 #define NMI_GLB_RESET_0				(NMI_PERIPH_REG_BASE + 0x400)
49 #define NMI_INTR_REG_BASE			(NMI_PERIPH_REG_BASE + 0xa00)
50 #define NMI_PIN_MUX_0				(NMI_PERIPH_REG_BASE + 0x408)
51 #define NMI_INTR_ENABLE				(NMI_INTR_REG_BASE)
52 #define GET_UINT32(X,Y)				(X[0+Y] + ((uint32)X[1+Y]<<8) + ((uint32)X[2+Y]<<16) +((uint32)X[3+Y]<<24))
53 
54 /*SPI and I2C only*/
55 #define CORT_HOST_COMM				(0x10)
56 #define HOST_CORT_COMM				(0x0b)
57 #define WAKE_CLK_REG				(0x1)
58 #define CLOCKS_EN_REG				(0xf)
59 
60 
61 
62 #define TIMEOUT						(0xfffffffful)
63 #define WAKUP_TRAILS_TIMEOUT		(4)
64 
chip_apply_conf(uint32 u32Conf)65 sint8 chip_apply_conf(uint32 u32Conf)
66 {
67 	sint8 ret = M2M_SUCCESS;
68 	uint32 val32 = u32Conf;
69 
70 #if (defined __ENABLE_PMU__) || (defined CONF_WINC_INT_PMU)
71 	val32 |= rHAVE_USE_PMU_BIT;
72 #endif
73 #ifdef __ENABLE_SLEEP_CLK_SRC_RTC__
74 	val32 |= rHAVE_SLEEP_CLK_SRC_RTC_BIT;
75 #elif defined __ENABLE_SLEEP_CLK_SRC_XO__
76 	val32 |= rHAVE_SLEEP_CLK_SRC_XO_BIT;
77 #endif
78 #ifdef __ENABLE_EXT_PA_INV_TX_RX__
79 	val32 |= rHAVE_EXT_PA_INV_TX_RX;
80 #endif
81 #ifdef __ENABLE_LEGACY_RF_SETTINGS__
82 	val32 |= rHAVE_LEGACY_RF_SETTINGS;
83 #endif
84 #ifdef __DISABLE_FIRMWARE_LOGS__
85 	val32 |= rHAVE_LOGS_DISABLED_BIT;
86 #endif
87 
88 	val32 |= rHAVE_RESERVED1_BIT;
89 	do  {
90 		nm_write_reg(rNMI_GP_REG_1, val32);
91 		if(val32 != 0) {
92 			uint32 reg = 0;
93 			ret = nm_read_reg_with_ret(rNMI_GP_REG_1, &reg);
94 			if(ret == M2M_SUCCESS) {
95 				if(reg == val32)
96 					break;
97 			}
98 		} else {
99 			break;
100 		}
101 	} while(1);
102 
103 	return M2M_SUCCESS;
104 }
chip_idle(void)105 void chip_idle(void)
106 {
107 	uint32 reg = 0;
108 	nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
109 	if(reg & NBIT1)
110 	{
111 		reg &=~ NBIT1;
112 		nm_write_reg(WAKE_CLK_REG, reg);
113 	}
114 }
115 
enable_interrupts(void)116 sint8 enable_interrupts(void)
117 {
118 	uint32 reg = 0;
119 	sint8 ret = M2M_SUCCESS;
120 	/**
121 	interrupt pin mux select
122 	**/
123 	ret = nm_read_reg_with_ret(NMI_PIN_MUX_0, &reg);
124 	if (M2M_SUCCESS != ret) goto ERR1;
125 
126 	reg |= ((uint32) 1 << 8);
127 	ret = nm_write_reg(NMI_PIN_MUX_0, reg);
128 	if (M2M_SUCCESS != ret) goto ERR1;
129 
130 	/**
131 	interrupt enable
132 	**/
133 	ret = nm_read_reg_with_ret(NMI_INTR_ENABLE, &reg);
134 	if (M2M_SUCCESS != ret) goto ERR1;
135 
136 	reg |= ((uint32) 1 << 16);
137 	ret = nm_write_reg(NMI_INTR_ENABLE, reg);
138 	if (M2M_SUCCESS != ret) goto ERR1;
139 ERR1:
140 	return ret;
141 }
142 
cpu_start(void)143 sint8 cpu_start(void) {
144 	uint32 reg = 0;
145 	sint8 ret;
146 
147 	/**
148 	reset regs
149 	*/
150 	ret = nm_write_reg(BOOTROM_REG,0);
151 	ret += nm_write_reg(NMI_STATE_REG,0);
152 	ret += nm_write_reg(NMI_REV_REG,0);
153 	/**
154 	Go...
155 	**/
156 	ret += nm_read_reg_with_ret(0x1118, &reg);
157 	reg |= (1 << 0);
158 	ret += nm_write_reg(0x1118, reg);
159 	ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
160 	if ((reg & (1ul << 10)) == (1ul << 10)) {
161 		reg &= ~(1ul << 10);
162 		ret += nm_write_reg(NMI_GLB_RESET_0, reg);
163 	}
164 	reg |= (1ul << 10);
165 	ret += nm_write_reg(NMI_GLB_RESET_0, reg);
166 	nm_bsp_sleep(1);
167 	return ret;
168 }
169 
nmi_get_chipid(void)170 uint32 nmi_get_chipid(void)
171 {
172 	static uint32 chipid = 0;
173 
174 	if (chipid == 0) {
175 		uint32 rfrevid;
176 
177 		if((nm_read_reg_with_ret(0x1000, &chipid)) != M2M_SUCCESS) {
178 			chipid = 0;
179 			return 0;
180 		}
181 		//if((ret = nm_read_reg_with_ret(0x11fc, &revid)) != M2M_SUCCESS) {
182 		//	return 0;
183 		//}
184 		if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
185 			chipid = 0;
186 			return 0;
187 		}
188 
189 		if (chipid == 0x1002a0)  {
190 			if (rfrevid == 0x1) { /* 1002A0 */
191 			} else /* if (rfrevid == 0x2) */ { /* 1002A1 */
192 				chipid = 0x1002a1;
193 			}
194 		} else if(chipid == 0x1002b0) {
195 			if(rfrevid == 3) { /* 1002B0 */
196 			} else if(rfrevid == 4) { /* 1002B1 */
197 				chipid = 0x1002b1;
198 			} else /* if(rfrevid == 5) */ { /* 1002B2 */
199 				chipid = 0x1002b2;
200 			}
201 		}else if(chipid == 0x1000F0) {
202 			if((nm_read_reg_with_ret(0x3B0000, &chipid)) != M2M_SUCCESS) {
203 			chipid = 0;
204 			return 0;
205 			}
206 		}else {
207 
208 		}
209 //#define PROBE_FLASH
210 #ifdef PROBE_FLASH
211 		if(chipid) {
212 			UWORD32 flashid;
213 
214 			flashid = probe_spi_flash();
215 			if(flashid == 0x1230ef) {
216 				chipid &= ~(0x0f0000);
217 				chipid |= 0x050000;
218 			}
219 			if(flashid == 0xc21320c2) {
220 				chipid &= ~(0x0f0000);
221 				chipid |= 0x050000;
222 			}
223 		}
224 #else
225 		/*M2M is by default have SPI flash*/
226 		chipid &= ~(0x0f0000);
227 		chipid |= 0x050000;
228 #endif /* PROBE_FLASH */
229 	}
230 	return chipid;
231 }
232 
nmi_get_rfrevid(void)233 uint32 nmi_get_rfrevid(void)
234 {
235     uint32 rfrevid;
236     if((nm_read_reg_with_ret(0x13f4, &rfrevid)) != M2M_SUCCESS) {
237         rfrevid = 0;
238         return 0;
239     }
240     return rfrevid;
241 }
242 
restore_pmu_settings_after_global_reset(void)243 void restore_pmu_settings_after_global_reset(void)
244 {
245 	/*
246 	* Must restore PMU register value after
247 	* global reset if PMU toggle is done at
248 	* least once since the last hard reset.
249 	*/
250 	if(REV(nmi_get_chipid()) >= REV_2B0) {
251 		nm_write_reg(0x1e48, 0xb78469ce);
252 	}
253 }
254 
nmi_update_pll(void)255 void nmi_update_pll(void)
256 {
257 	uint32 pll;
258 
259 	pll = nm_read_reg(0x1428);
260 	pll &= ~0x1ul;
261 	nm_write_reg(0x1428, pll);
262 	pll |= 0x1ul;
263 	nm_write_reg(0x1428, pll);
264 
265 }
nmi_set_sys_clk_src_to_xo(void)266 void nmi_set_sys_clk_src_to_xo(void)
267 {
268 	uint32 val32;
269 
270 	/* Switch system clock source to XO. This will take effect after nmi_update_pll(). */
271 	val32 = nm_read_reg(0x141c);
272 	val32 |= (1 << 2);
273 	nm_write_reg(0x141c, val32);
274 
275 	/* Do PLL update */
276 	nmi_update_pll();
277 }
chip_sleep(void)278 sint8 chip_sleep(void)
279 {
280 	uint32 reg;
281 	sint8 ret = M2M_SUCCESS;
282 
283 	while(1)
284 	{
285 		ret = nm_read_reg_with_ret(CORT_HOST_COMM,&reg);
286 		if(ret != M2M_SUCCESS) goto ERR1;
287 		if((reg & NBIT0) == 0) break;
288 	}
289 
290 	/* Clear bit 1 */
291 	ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
292 	if(ret != M2M_SUCCESS)goto ERR1;
293 	if(reg & NBIT1)
294 	{
295 		reg &=~NBIT1;
296 		ret = nm_write_reg(WAKE_CLK_REG, reg);
297 		if(ret != M2M_SUCCESS)goto ERR1;
298 	}
299 
300 	ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
301 	if(ret != M2M_SUCCESS)goto ERR1;
302 	if(reg & NBIT0)
303 	{
304 		reg &= ~NBIT0;
305 		ret = nm_write_reg(HOST_CORT_COMM, reg);
306 		if(ret != M2M_SUCCESS)goto ERR1;
307 	}
308 
309 ERR1:
310 	return ret;
311 }
chip_wake(void)312 sint8 chip_wake(void)
313 {
314 	sint8 ret = M2M_SUCCESS;
315 	uint32 reg = 0, clk_status_reg = 0,trials = 0;
316 
317 	ret = nm_read_reg_with_ret(HOST_CORT_COMM, &reg);
318 	if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
319 
320 	if(!(reg & NBIT0))
321 	{
322 		/*USE bit 0 to indicate host wakeup*/
323 		ret = nm_write_reg(HOST_CORT_COMM, reg|NBIT0);
324 		if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
325 	}
326 
327 	ret = nm_read_reg_with_ret(WAKE_CLK_REG, &reg);
328 	if(ret != M2M_SUCCESS)goto _WAKE_EXIT;
329 	/* Set bit 1 */
330 	if(!(reg & NBIT1))
331 	{
332 		ret = nm_write_reg(WAKE_CLK_REG, reg | NBIT1);
333 		if(ret != M2M_SUCCESS) goto _WAKE_EXIT;
334 	}
335 
336 	do
337 	{
338 		ret = nm_read_reg_with_ret(CLOCKS_EN_REG, &clk_status_reg);
339 		if(ret != M2M_SUCCESS) {
340 			M2M_ERR("Bus error (5).%d %lx\n",ret,clk_status_reg);
341 			goto _WAKE_EXIT;
342 		}
343 		if(clk_status_reg & NBIT2) {
344 			break;
345 		}
346 		nm_bsp_sleep(2);
347 		trials++;
348 		if(trials > WAKUP_TRAILS_TIMEOUT)
349 		{
350 			M2M_ERR("Failed to wakup the chip\n");
351 			ret = M2M_ERR_TIME_OUT;
352 			goto _WAKE_EXIT;
353 		}
354 	}while(1);
355 
356 	/*workaround sometimes spi fail to read clock regs after reading/writing clockless registers*/
357 	nm_bus_reset();
358 
359 _WAKE_EXIT:
360 	return ret;
361 }
cpu_halt(void)362 sint8 cpu_halt(void)
363 {
364 	sint8 ret;
365 	uint32 reg = 0;
366 	ret = nm_read_reg_with_ret(0x1118, &reg);
367 	reg |= (1 << 0);
368 	ret += nm_write_reg(0x1118, reg);
369 	ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
370 	if ((reg & (1ul << 10)) == (1ul << 10)) {
371 		reg &= ~(1ul << 10);
372 		ret += nm_write_reg(NMI_GLB_RESET_0, reg);
373 		ret += nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
374 	}
375 	return ret;
376 }
chip_reset_and_cpu_halt(void)377 sint8 chip_reset_and_cpu_halt(void)
378 {
379 	sint8 ret = M2M_SUCCESS;
380 
381 	/*Wakeup needed only for I2C interface*/
382 	ret = chip_wake();
383 	if(ret != M2M_SUCCESS) goto ERR1;
384 	/*Reset and CPU halt need for no wait board only*/
385 	ret = chip_reset();
386 	if(ret != M2M_SUCCESS) goto ERR1;
387 	ret = cpu_halt();
388 	if(ret != M2M_SUCCESS) goto ERR1;
389 ERR1:
390 	return ret;
391 }
chip_reset(void)392 sint8 chip_reset(void)
393 {
394 	sint8 ret = M2M_SUCCESS;
395 	ret = nm_write_reg(NMI_GLB_RESET_0, 0);
396 	nm_bsp_sleep(50);
397 	return ret;
398 }
399 
wait_for_bootrom(uint8 arg)400 sint8 wait_for_bootrom(uint8 arg)
401 {
402 	sint8 ret = M2M_SUCCESS;
403 	uint32 reg = 0, cnt = 0;
404 	uint32 u32GpReg1 = 0;
405 	uint32 u32DriverVerInfo = M2M_MAKE_VERSION_INFO(M2M_RELEASE_VERSION_MAJOR_NO,\
406 				M2M_RELEASE_VERSION_MINOR_NO, M2M_RELEASE_VERSION_PATCH_NO,\
407 				M2M_RELEASE_VERSION_MAJOR_NO, M2M_RELEASE_VERSION_MINOR_NO,\
408 				M2M_RELEASE_VERSION_PATCH_NO);
409 
410 
411 	reg = 0;
412 	while(1) {
413 		reg = nm_read_reg(0x1014);	/* wait for efuse loading done */
414 		if (reg & 0x80000000) {
415 			break;
416 		}
417 		nm_bsp_sleep(1); /* TODO: Why bus error if this delay is not here. */
418 	}
419 	reg = nm_read_reg(M2M_WAIT_FOR_HOST_REG);
420 	reg &= 0x1;
421 
422 	/* check if waiting for the host will be skipped or not */
423 	if(reg == 0)
424 	{
425 		reg = 0;
426 		while(reg != M2M_FINISH_BOOT_ROM)
427 		{
428 			nm_bsp_sleep(1);
429 			reg = nm_read_reg(BOOTROM_REG);
430 
431 			if(++cnt > TIMEOUT)
432 			{
433 				M2M_DBG("failed to load firmware from flash.\n");
434 				ret = M2M_ERR_INIT;
435 				goto ERR2;
436 			}
437 		}
438 	}
439 
440 	if(M2M_WIFI_MODE_ATE_HIGH == arg) {
441 		nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
442 		nm_write_reg(NMI_STATE_REG, NBIT20);
443 	}else if(M2M_WIFI_MODE_ATE_LOW == arg) {
444 		nm_write_reg(NMI_REV_REG, M2M_ATE_FW_START_VALUE);
445 		nm_write_reg(NMI_STATE_REG, 0);
446 	}else if(M2M_WIFI_MODE_ETHERNET == arg){
447 		u32GpReg1 = rHAVE_ETHERNET_MODE_BIT;
448 		nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
449 	} else {
450 		/*bypass this step*/
451 		nm_write_reg(NMI_STATE_REG, u32DriverVerInfo);
452 	}
453 
454 	if(REV(nmi_get_chipid()) >= REV_3A0){
455 		chip_apply_conf(u32GpReg1 | rHAVE_USE_PMU_BIT);
456 	} else {
457 		chip_apply_conf(u32GpReg1);
458 	}
459 	M2M_INFO("DriverVerInfo: 0x%08lx\n",u32DriverVerInfo);
460 
461 	nm_write_reg(BOOTROM_REG,M2M_START_FIRMWARE);
462 
463 #ifdef __ROM_TEST__
464 	rom_test();
465 #endif /* __ROM_TEST__ */
466 
467 ERR2:
468 	return ret;
469 }
470 
wait_for_firmware_start(uint8 arg)471 sint8 wait_for_firmware_start(uint8 arg)
472 {
473 	sint8 ret = M2M_SUCCESS;
474 	uint32 reg = 0, cnt = 0;
475 	uint32 u32Timeout = TIMEOUT;
476 	volatile uint32 regAddress = NMI_STATE_REG;
477 	volatile uint32 checkValue = M2M_FINISH_INIT_STATE;
478 
479 	if((M2M_WIFI_MODE_ATE_HIGH == arg)||(M2M_WIFI_MODE_ATE_LOW == arg)) {
480 		regAddress = NMI_REV_REG;
481 		checkValue = M2M_ATE_FW_IS_UP_VALUE;
482 	} else {
483 		/*bypass this step*/
484 	}
485 
486 
487 	while (checkValue != reg)
488 	{
489 		nm_bsp_sleep(2); /* TODO: Why bus error if this delay is not here. */
490 		M2M_DBG("%x %x %x\n",(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x108c),(unsigned int)nm_read_reg(0x14A0));
491 		reg = nm_read_reg(regAddress);
492 		if(++cnt >= u32Timeout)
493 		{
494 			M2M_DBG("Time out for wait firmware Run\n");
495 			ret = M2M_ERR_INIT;
496 			goto ERR;
497 		}
498 	}
499 	if(M2M_FINISH_INIT_STATE == checkValue)
500 	{
501 		nm_write_reg(NMI_STATE_REG, 0);
502 	}
503 ERR:
504 	return ret;
505 }
506 
chip_deinit(void)507 sint8 chip_deinit(void)
508 {
509 	uint32 reg = 0;
510 	sint8 ret;
511 
512 	/**
513 	stop the firmware, need a re-download
514 	**/
515 	ret = nm_read_reg_with_ret(NMI_GLB_RESET_0, &reg);
516 	if (ret != M2M_SUCCESS) {
517 		M2M_ERR("failed to de-initialize\n");
518 		goto ERR1;
519 	}
520 	reg &= ~(1 << 10);
521 	ret = nm_write_reg(NMI_GLB_RESET_0, reg);
522 	if (ret != M2M_SUCCESS) {
523 		M2M_ERR("failed to de-initialize\n");
524 		goto ERR1;
525 	}
526 
527 ERR1:
528 	return ret;
529 }
530 
531 #ifdef CONF_PERIPH
532 
set_gpio_dir(uint8 gpio,uint8 dir)533 sint8 set_gpio_dir(uint8 gpio, uint8 dir)
534 {
535 	uint32 val32;
536 	sint8 ret;
537 
538 	ret = nm_read_reg_with_ret(0x20108, &val32);
539 	if(ret != M2M_SUCCESS) goto _EXIT;
540 
541 	if(dir) {
542 		val32 |= (1ul << gpio);
543 	} else {
544 		val32 &= ~(1ul << gpio);
545 	}
546 
547 	ret = nm_write_reg(0x20108, val32);
548 
549 _EXIT:
550 	return ret;
551 }
set_gpio_val(uint8 gpio,uint8 val)552 sint8 set_gpio_val(uint8 gpio, uint8 val)
553 {
554 	uint32 val32;
555 	sint8 ret;
556 
557 	ret = nm_read_reg_with_ret(0x20100, &val32);
558 	if(ret != M2M_SUCCESS) goto _EXIT;
559 
560 	if(val) {
561 		val32 |= (1ul << gpio);
562 	} else {
563 		val32 &= ~(1ul << gpio);
564 	}
565 
566 	ret = nm_write_reg(0x20100, val32);
567 
568 _EXIT:
569 	return ret;
570 }
571 
get_gpio_val(uint8 gpio,uint8 * val)572 sint8 get_gpio_val(uint8 gpio, uint8* val)
573 {
574 	uint32 val32;
575 	sint8 ret;
576 
577 	ret = nm_read_reg_with_ret(0x20104, &val32);
578 	if(ret != M2M_SUCCESS) goto _EXIT;
579 
580 	*val = (uint8)((val32 >> gpio) & 0x01);
581 
582 _EXIT:
583 	return ret;
584 }
585 
pullup_ctrl(uint32 pinmask,uint8 enable)586 sint8 pullup_ctrl(uint32 pinmask, uint8 enable)
587 {
588 	sint8 s8Ret;
589 	uint32 val32;
590 	s8Ret = nm_read_reg_with_ret(0x142c, &val32);
591 	if(s8Ret != M2M_SUCCESS) {
592 		M2M_ERR("[pullup_ctrl]: failed to read\n");
593 		goto _EXIT;
594 	}
595 	if(enable) {
596 		val32 &= ~pinmask;
597 		} else {
598 		val32 |= pinmask;
599 	}
600 	s8Ret = nm_write_reg(0x142c, val32);
601 	if(s8Ret  != M2M_SUCCESS) {
602 		M2M_ERR("[pullup_ctrl]: failed to write\n");
603 		goto _EXIT;
604 	}
605 _EXIT:
606 	return s8Ret;
607 }
608 #endif /* CONF_PERIPH */
609 
nmi_get_otp_mac_address(uint8 * pu8MacAddr,uint8 * pu8IsValid)610 sint8 nmi_get_otp_mac_address(uint8 *pu8MacAddr,  uint8 * pu8IsValid)
611 {
612 	sint8 ret;
613 	uint32	u32RegValue;
614 	uint8	mac[6];
615 	tstrGpRegs strgp = {0};
616 
617 	ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
618 	if(ret != M2M_SUCCESS) goto _EXIT_ERR;
619 
620 	ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
621 	if(ret != M2M_SUCCESS) goto _EXIT_ERR;
622 	u32RegValue = strgp.u32Mac_efuse_mib;
623 
624 	if(!EFUSED_MAC(u32RegValue)) {
625 		M2M_DBG("Default MAC\n");
626 		m2m_memset(pu8MacAddr, 0, 6);
627 		goto _EXIT_ERR;
628 	}
629 
630 	M2M_DBG("OTP MAC\n");
631 	u32RegValue >>=16;
632 	ret = nm_read_block(u32RegValue|0x30000, mac, 6);
633 	m2m_memcpy(pu8MacAddr,mac,6);
634 	if(pu8IsValid) *pu8IsValid = 1;
635 	return ret;
636 
637 _EXIT_ERR:
638 	if(pu8IsValid) *pu8IsValid = 0;
639 	return ret;
640 }
641 
nmi_get_mac_address(uint8 * pu8MacAddr)642 sint8 nmi_get_mac_address(uint8 *pu8MacAddr)
643 {
644 	sint8 ret;
645 	uint32	u32RegValue;
646 	uint8	mac[6];
647 	tstrGpRegs strgp = {0};
648 
649 	ret = nm_read_reg_with_ret(rNMI_GP_REG_2, &u32RegValue);
650 	if(ret != M2M_SUCCESS) goto _EXIT_ERR;
651 
652 	ret = nm_read_block(u32RegValue|0x30000,(uint8*)&strgp,sizeof(tstrGpRegs));
653 	if(ret != M2M_SUCCESS) goto _EXIT_ERR;
654 	u32RegValue = strgp.u32Mac_efuse_mib;
655 
656 	u32RegValue &=0x0000ffff;
657 	ret = nm_read_block(u32RegValue|0x30000, mac, 6);
658 	m2m_memcpy(pu8MacAddr, mac, 6);
659 
660 	return ret;
661 
662 _EXIT_ERR:
663 	return ret;
664 }
665