Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

680 linhas
15 KiB

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