phy_init.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  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. #include <stddef.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <stdbool.h>
  18. #include "rom/ets_sys.h"
  19. #include "soc/dport_reg.h"
  20. #include "esp_err.h"
  21. #include "esp_phy_init.h"
  22. #include "esp_system.h"
  23. #include "phy.h"
  24. #include "esp_log.h"
  25. #include "nvs.h"
  26. #include "sdkconfig.h"
  27. #include "phy_init_data.h"
  28. static const char* TAG = "phy_init";
  29. esp_err_t esp_phy_init(const esp_phy_init_data_t* init_data,
  30. esp_phy_calibration_mode_t mode, esp_phy_calibration_data_t* calibration_data)
  31. {
  32. assert(init_data);
  33. assert(calibration_data);
  34. // Initialize PHY pointer table
  35. phy_get_romfunc_addr();
  36. REG_SET_BIT(DPORT_WIFI_RST_EN_REG, DPORT_MAC_RST);
  37. REG_CLR_BIT(DPORT_WIFI_RST_EN_REG, DPORT_MAC_RST);
  38. // Enable WiFi peripheral clock
  39. SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, 0x87cf);
  40. ESP_LOGV(TAG, "register_chipv7_phy, init_data=%p, cal_data=%p, mode=%d",
  41. init_data, calibration_data, mode);
  42. phy_set_wifi_mode_only(0);
  43. register_chipv7_phy(init_data, calibration_data, mode);
  44. coex_bt_high_prio();
  45. return ESP_OK;
  46. }
  47. // PHY init data handling functions
  48. #if CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
  49. #include "esp_partition.h"
  50. const esp_phy_init_data_t* esp_phy_get_init_data()
  51. {
  52. const esp_partition_t* partition = esp_partition_find_first(
  53. ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_PHY, NULL);
  54. if (partition == NULL) {
  55. ESP_LOGE(TAG, "PHY data partition not found");
  56. return NULL;
  57. }
  58. ESP_LOGD(TAG, "loading PHY init data from partition at offset 0x%x", partition->address);
  59. size_t init_data_store_length = sizeof(phy_init_magic_pre) +
  60. sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
  61. uint8_t* init_data_store = (uint8_t*) malloc(init_data_store_length);
  62. if (init_data_store == NULL) {
  63. ESP_LOGE(TAG, "failed to allocate memory for PHY init data");
  64. return NULL;
  65. }
  66. esp_err_t err = esp_partition_read(partition, 0, init_data_store, init_data_store_length);
  67. if (err != ESP_OK) {
  68. ESP_LOGE(TAG, "failed to read PHY data partition (%d)", err);
  69. return NULL;
  70. }
  71. if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre)) != 0 ||
  72. memcmp(init_data_store + init_data_store_length - sizeof(phy_init_magic_post),
  73. PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0) {
  74. ESP_LOGE(TAG, "failed to validate PHY data partition");
  75. return NULL;
  76. }
  77. ESP_LOGE(TAG, "PHY data partition validated");
  78. return (const esp_phy_init_data_t*) (init_data_store + sizeof(phy_init_magic_pre));
  79. }
  80. void esp_phy_release_init_data(const esp_phy_init_data_t* init_data)
  81. {
  82. free((uint8_t*) init_data - sizeof(phy_init_magic_pre));
  83. }
  84. #else // CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
  85. // phy_init_data.h will declare static 'phy_init_data' variable initialized with default init data
  86. const esp_phy_init_data_t* esp_phy_get_init_data()
  87. {
  88. ESP_LOGD(TAG, "loading PHY init data from application binary");
  89. return &phy_init_data;
  90. }
  91. void esp_phy_release_init_data(const esp_phy_init_data_t* init_data)
  92. {
  93. // no-op
  94. }
  95. #endif // CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
  96. // PHY calibration data handling functions
  97. static const char* PHY_NAMESPACE = "phy";
  98. static const char* PHY_CAL_VERSION_KEY = "cal_version";
  99. static const char* PHY_CAL_MAC_KEY = "cal_mac";
  100. static const char* PHY_CAL_DATA_KEY = "cal_data";
  101. static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
  102. esp_phy_calibration_data_t* out_cal_data);
  103. static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
  104. const esp_phy_calibration_data_t* cal_data);
  105. esp_err_t esp_phy_load_cal_data_from_nvs(esp_phy_calibration_data_t* out_cal_data)
  106. {
  107. nvs_handle handle;
  108. esp_err_t err = nvs_open(PHY_NAMESPACE, NVS_READONLY, &handle);
  109. if (err != ESP_OK) {
  110. ESP_LOGD(TAG, "%s: failed to open NVS namespace (%d)", __func__, err);
  111. return err;
  112. }
  113. else {
  114. err = load_cal_data_from_nvs_handle(handle, out_cal_data);
  115. nvs_close(handle);
  116. return err;
  117. }
  118. }
  119. esp_err_t esp_phy_store_cal_data_to_nvs(const esp_phy_calibration_data_t* cal_data)
  120. {
  121. nvs_handle handle;
  122. esp_err_t err = nvs_open(PHY_NAMESPACE, NVS_READWRITE, &handle);
  123. if (err != ESP_OK) {
  124. ESP_LOGD(TAG, "%s: failed to open NVS namespace (%d)", __func__, err);
  125. return err;
  126. }
  127. else {
  128. err = store_cal_data_to_nvs_handle(handle, cal_data);
  129. nvs_close(handle);
  130. return err;
  131. }
  132. }
  133. static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
  134. esp_phy_calibration_data_t* out_cal_data)
  135. {
  136. esp_err_t err;
  137. uint32_t cal_data_version;
  138. err = nvs_get_u32(handle, PHY_CAL_VERSION_KEY, &cal_data_version);
  139. if (err != ESP_OK) {
  140. ESP_LOGD(TAG, "%s: failed to get cal_version (%d)", __func__, err);
  141. return err;
  142. }
  143. uint32_t cal_format_version = phy_get_rf_cal_version() & (~BIT(16));
  144. ESP_LOGV(TAG, "phy_get_rf_cal_version: %d\n", cal_format_version);
  145. if (cal_data_version != cal_format_version) {
  146. ESP_LOGD(TAG, "%s: expected calibration data format %d, found %d",
  147. __func__, cal_format_version, cal_data_version);
  148. return ESP_FAIL;
  149. }
  150. uint8_t cal_data_mac[6];
  151. size_t length = sizeof(cal_data_mac);
  152. err = nvs_get_blob(handle, PHY_CAL_MAC_KEY, cal_data_mac, &length);
  153. if (err != ESP_OK) {
  154. ESP_LOGD(TAG, "%s: failed to get cal_mac (%d)", __func__, err);
  155. return err;
  156. }
  157. if (length != sizeof(cal_data_mac)) {
  158. ESP_LOGD(TAG, "%s: invalid length of cal_mac (%d)", __func__, length);
  159. return ESP_ERR_INVALID_SIZE;
  160. }
  161. uint8_t sta_mac[6];
  162. esp_efuse_read_mac(sta_mac);
  163. if (memcmp(sta_mac, cal_data_mac, sizeof(sta_mac)) != 0) {
  164. ESP_LOGE(TAG, "%s: calibration data MAC check failed: expected " \
  165. MACSTR ", found " MACSTR,
  166. __func__, MAC2STR(sta_mac), MAC2STR(cal_data_mac));
  167. return ESP_FAIL;
  168. }
  169. length = sizeof(*out_cal_data);
  170. err = nvs_get_blob(handle, PHY_CAL_DATA_KEY, out_cal_data, &length);
  171. if (err != ESP_OK) {
  172. ESP_LOGE(TAG, "%s: failed to get cal_data(%d)", __func__, err);
  173. return err;
  174. }
  175. if (length != sizeof(*out_cal_data)) {
  176. ESP_LOGD(TAG, "%s: invalid length of cal_data (%d)", __func__, length);
  177. return ESP_ERR_INVALID_SIZE;
  178. }
  179. return ESP_OK;
  180. }
  181. static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
  182. const esp_phy_calibration_data_t* cal_data)
  183. {
  184. esp_err_t err;
  185. uint32_t cal_format_version = phy_get_rf_cal_version() & (~BIT(16));
  186. ESP_LOGV(TAG, "phy_get_rf_cal_version: %d\n", cal_format_version);
  187. err = nvs_set_u32(handle, PHY_CAL_VERSION_KEY, cal_format_version);
  188. if (err != ESP_OK) {
  189. return err;
  190. }
  191. uint8_t sta_mac[6];
  192. esp_efuse_read_mac(sta_mac);
  193. err = nvs_set_blob(handle, PHY_CAL_MAC_KEY, sta_mac, sizeof(sta_mac));
  194. if (err != ESP_OK) {
  195. return err;
  196. }
  197. err = nvs_set_blob(handle, PHY_CAL_DATA_KEY, cal_data, sizeof(*cal_data));
  198. return err;
  199. }
  200. void register_chipv7_phy_stub()
  201. {
  202. }