You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by "cwespressif (via GitHub)" <gi...@apache.org> on 2023/06/05 03:28:08 UTC

[GitHub] [nuttx] cwespressif opened a new pull request, #9475: xtensa/esp32: Support multiple PHY init data bin

cwespressif opened a new pull request, #9475:
URL: https://github.com/apache/nuttx/pull/9475

   ## Summary
   
   Support updating PHY initialization data based on country codes.
   
   ## Impact
   
   ## Testing
   
   - If  `CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION`  and `CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA`  are enabled, PHY initialization data (PHY initialization data is used for RF calibration) will be loaded from a partition, make sure that PHY data partition is included (type: `'data'`, subtype: `'phy'`).
   
   - The corresponding PHY init data type can be automatically switched according to the country code, China's PHY init data bin is used by default, country code can be modified through the wapi command: `wapi country <ifname> <country code>`.
   - Tested with Wi-Fi: `./tools/configure esp32-devkitc:wifi`
   ![image](https://github.com/apache/nuttx/assets/63690793/3c6f7741-9ada-4cac-abf8-80cf4fe9d31d)
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] pkarashchenko commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "pkarashchenko (via GitHub)" <gi...@apache.org>.
pkarashchenko commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1217763140


##########
arch/xtensa/src/esp32/Kconfig:
##########
@@ -2170,6 +2170,63 @@ config ESP32_UNIVERSAL_MAC_ADDRESSES
 	default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
 	default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
 
+menu "PHY"
+	depends on ESP32_PARTITION_TABLE
+
+menuconfig ESP32_PHY_INIT_DATA_IN_PARTITION
+	bool "Use a partition to store PHY init data"
+	default n
+	help

Review Comment:
   ```suggestion
   	---help---
   ```



##########
arch/xtensa/src/esp32/Kconfig:
##########
@@ -2170,6 +2170,63 @@ config ESP32_UNIVERSAL_MAC_ADDRESSES
 	default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
 	default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
 
+menu "PHY"
+	depends on ESP32_PARTITION_TABLE
+
+menuconfig ESP32_PHY_INIT_DATA_IN_PARTITION
+	bool "Use a partition to store PHY init data"
+	default n
+	help
+		If enabled, PHY init data will be loaded from a partition.
+		When using a custom partition table, make sure that PHY data
+		partition is included (type: 'data', subtype: 'phy').
+		With default partition tables, this is done automatically.
+		If PHY init data is stored in a partition, it has to be flashed there,
+		otherwise runtime error will occur.
+
+		If this option is not enabled, PHY init data will be embedded
+		into the application binary.
+
+		If unsure, choose 'n'.
+
+config ESP32_PHY_DEFAULT_INIT_IF_INVALID
+	bool "Reset default PHY init data if invalid"
+	default n
+	depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+	help
+		If enabled, PHY init data will be restored to default if
+		it cannot be verified successfully to avoid endless bootloops.
+
+		If unsure, choose 'n'.
+
+if ESP32_PHY_INIT_DATA_IN_PARTITION
+config ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+	bool "Support multiple PHY init data bin"
+	depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+	default n
+	help
+		If enabled, the corresponding PHY init data type can be automatically switched
+		according to the country code. China's PHY init data bin is used by default.
+		Can be modified by country information in API esp_wifi_set_country().
+		The priority of switching the PHY init data type is:
+		1. Country configured by API esp_wifi_set_country()
+		and the parameter policy is WIFI_COUNTRY_POLICY_MANUAL.
+		2. Country notified by the connected AP.
+		3. Country configured by API esp_wifi_set_country()
+		and the parameter policy is WIFI_COUNTRY_POLICY_AUTO.
+
+config ESP32_PHY_INIT_DATA_ERROR
+	bool "Terminate operation when PHY init data error"
+	depends on ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+	default n
+	help

Review Comment:
   ```suggestion
   	---help---
   ```



##########
arch/xtensa/src/esp32/Kconfig:
##########
@@ -2170,6 +2170,63 @@ config ESP32_UNIVERSAL_MAC_ADDRESSES
 	default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
 	default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
 
+menu "PHY"
+	depends on ESP32_PARTITION_TABLE
+
+menuconfig ESP32_PHY_INIT_DATA_IN_PARTITION
+	bool "Use a partition to store PHY init data"
+	default n
+	help
+		If enabled, PHY init data will be loaded from a partition.
+		When using a custom partition table, make sure that PHY data
+		partition is included (type: 'data', subtype: 'phy').
+		With default partition tables, this is done automatically.
+		If PHY init data is stored in a partition, it has to be flashed there,
+		otherwise runtime error will occur.
+
+		If this option is not enabled, PHY init data will be embedded
+		into the application binary.
+
+		If unsure, choose 'n'.
+
+config ESP32_PHY_DEFAULT_INIT_IF_INVALID
+	bool "Reset default PHY init data if invalid"
+	default n
+	depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+	help
+		If enabled, PHY init data will be restored to default if
+		it cannot be verified successfully to avoid endless bootloops.
+
+		If unsure, choose 'n'.
+
+if ESP32_PHY_INIT_DATA_IN_PARTITION
+config ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+	bool "Support multiple PHY init data bin"
+	depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+	default n
+	help

Review Comment:
   ```suggestion
   	---help---
   ```



##########
arch/xtensa/src/esp32/esp32_partition.c:
##########
@@ -846,3 +913,99 @@ int esp32_partition_init(void)
 
   return OK;
 }
+
+/****************************************************************************
+ * Name: esp32_partition_read
+ *
+ * Description:
+ *   Read data from SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_read(const char *label, size_t offset, void *buf,
+                         size_t size)
+{
+  int ret;
+  int partion_offset;
+  DEBUGASSERT(label != NULL && buf != NULL);
+  struct mtd_dev_s *mtd = esp32_spiflash_get_mtd();
+  if (!mtd)
+    {
+      ferr("ERROR: Failed to get SPI flash MTD\n");
+      return -ENOSYS;
+    }
+
+  partion_offset = partition_get_offset(label, sizeof(label));
+  if (partion_offset < 0)
+    {
+      ferr("ERROR: Failed to get partition: %s offset\n", label);
+      return partion_offset;
+    }
+
+  ret = MTD_READ(mtd, partion_offset + offset,
+                 size, (uint8_t *)buf);
+  if (ret != size)
+    {
+      ferr("ERROR: Failed to get read data from MTD\n");
+      return -EIO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_partition_write
+ *
+ * Description:
+ *   Write data to SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_write(const char *label, size_t offset, void *buf,
+                         size_t size)

Review Comment:
   ```suggestion
   int esp32_partition_write(const char *label, size_t offset, void *buf,
                             size_t size)
   ```



##########
arch/xtensa/src/esp32/esp32_partition.c:
##########
@@ -760,6 +760,73 @@ static int partition_create_dev(const struct partition_info_priv *info,
   return OK;
 }
 
+/****************************************************************************
+ * Name: partition_get_offset
+ *
+ * Description:
+ *   Get offset in SPI flash of the partition label
+ *
+ * Input Parameters:
+ *   label - Partition label
+ *   size  - Data number
+ *
+ * Returned Value:
+ *   Get partition offset(>= 0) if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+static int partition_get_offset(const char *label, size_t size)
+{
+  int i;
+  int ret;
+  uint8_t *pbuf;
+  int partion_offset;
+  const struct partition_info_priv *info;
+  DEBUGASSERT(label != NULL);
+  struct mtd_dev_s *mtd = esp32_spiflash_get_mtd();
+  if (!mtd)
+    {
+      ferr("ERROR: Failed to get SPI flash MTD\n");
+      return -ENOSYS;
+    }
+
+  pbuf = kmm_malloc(PARTITION_MAX_SIZE);
+  if (!pbuf)
+    {
+      ferr("ERROR: Failed to allocate %d byte\n", PARTITION_MAX_SIZE);
+      return -ENOMEM;
+    }
+
+  ret = MTD_READ(mtd, PARTITION_TABLE_OFFSET,
+                PARTITION_MAX_SIZE, pbuf);

Review Comment:
   ```suggestion
     ret = MTD_READ(mtd, PARTITION_TABLE_OFFSET,
                    PARTITION_MAX_SIZE, pbuf);
   ```



##########
arch/xtensa/src/esp32/Kconfig:
##########
@@ -2170,6 +2170,63 @@ config ESP32_UNIVERSAL_MAC_ADDRESSES
 	default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
 	default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
 
+menu "PHY"
+	depends on ESP32_PARTITION_TABLE
+
+menuconfig ESP32_PHY_INIT_DATA_IN_PARTITION
+	bool "Use a partition to store PHY init data"
+	default n
+	help
+		If enabled, PHY init data will be loaded from a partition.
+		When using a custom partition table, make sure that PHY data
+		partition is included (type: 'data', subtype: 'phy').
+		With default partition tables, this is done automatically.
+		If PHY init data is stored in a partition, it has to be flashed there,
+		otherwise runtime error will occur.
+
+		If this option is not enabled, PHY init data will be embedded
+		into the application binary.
+
+		If unsure, choose 'n'.
+
+config ESP32_PHY_DEFAULT_INIT_IF_INVALID
+	bool "Reset default PHY init data if invalid"
+	default n
+	depends on ESP32_PHY_INIT_DATA_IN_PARTITION
+	help

Review Comment:
   ```suggestion
   	---help---
   ```



##########
arch/xtensa/src/esp32/esp32_partition.h:
##########
@@ -84,6 +84,45 @@ extern "C"
 
 int esp32_partition_init(void);
 
+/****************************************************************************
+ * Name: esp32_partition_read
+ *
+ * Description:
+ *   Read data from SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_read(const char *label, size_t offset, void *buf,
+                         size_t size);
+
+/****************************************************************************
+ * Name: esp32_partition_write
+ *
+ * Description:
+ *   Write data to SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_write(const char *label, size_t offset, void *buf,
+                         size_t size);

Review Comment:
   ```suggestion
   int esp32_partition_write(const char *label, size_t offset, void *buf,
                             size_t size);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };

Review Comment:
   Optional
   ```suggestion
   static char g_phy_current_country[PHY_COUNTRY_CODE_LEN];
   ```
   or remove 2 spaces indentation.



##########
arch/xtensa/src/esp32/esp32_partition.c:
##########
@@ -846,3 +913,99 @@ int esp32_partition_init(void)
 
   return OK;
 }
+
+/****************************************************************************
+ * Name: esp32_partition_read
+ *
+ * Description:
+ *   Read data from SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_read(const char *label, size_t offset, void *buf,
+                         size_t size)
+{
+  int ret;
+  int partion_offset;
+  DEBUGASSERT(label != NULL && buf != NULL);
+  struct mtd_dev_s *mtd = esp32_spiflash_get_mtd();
+  if (!mtd)
+    {
+      ferr("ERROR: Failed to get SPI flash MTD\n");
+      return -ENOSYS;
+    }
+
+  partion_offset = partition_get_offset(label, sizeof(label));
+  if (partion_offset < 0)
+    {
+      ferr("ERROR: Failed to get partition: %s offset\n", label);
+      return partion_offset;
+    }
+
+  ret = MTD_READ(mtd, partion_offset + offset,
+                 size, (uint8_t *)buf);
+  if (ret != size)
+    {
+      ferr("ERROR: Failed to get read data from MTD\n");
+      return -EIO;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp32_partition_write
+ *
+ * Description:
+ *   Write data to SPI Flash at designated address.
+ *
+ * Input Parameters:
+ *   label  - Partition label
+ *   offset - Offset in SPI Flash
+ *   buf    - Data buffer pointer
+ *   size   - Data number
+ *
+ * Returned Value:
+ *   0 if success or a negative value if fail.
+ *
+ ****************************************************************************/
+
+int esp32_partition_write(const char *label, size_t offset, void *buf,
+                         size_t size)
+{
+  int ret;
+  int partion_offset;
+  DEBUGASSERT(label != NULL && buf != NULL);
+  struct mtd_dev_s *mtd = esp32_spiflash_get_mtd();
+  if (!mtd)
+    {
+      ferr("ERROR: Failed to get SPI flash MTD\n");
+      return -ENOSYS;
+    }
+
+  partion_offset = partition_get_offset(label, sizeof(label));
+  if (partion_offset < 0)
+    {
+      ferr("ERROR: Failed to get partition: %s offset\n", label);
+      return partion_offset;
+    }
+
+  ret = MTD_WRITE(mtd, partion_offset + offset,
+                 size, (uint8_t *)buf);

Review Comment:
   ```suggestion
     ret = MTD_WRITE(mtd, partion_offset + offset,
                     size, (uint8_t *)buf);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;

Review Comment:
   Optional
   ```suggestion
   static phy_init_data_type_t g_phy_init_data_type;
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;

Review Comment:
   Optional
   ```suggestion
   static phy_init_data_type_t g_current_apply_phy_init_data;
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";

Review Comment:
   Optional
   ```suggestion
   static const char *phy_partion_label = "phy_init";
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };
+
+/* Whether it is a new bin */
+
+static bool g_multiple_phy_init_data_bin = false;

Review Comment:
   Optional
   ```suggestion
   static bool g_multiple_phy_init_data_bin;
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };
+
+/* Whether it is a new bin */
+
+static bool g_multiple_phy_init_data_bin = false;
+
+/* PHY init data type array */
+
+static char *g_phy_type[ESP_PHY_INIT_DATA_TYPE_NUMBER] =
+  {
+    "DEFAULT", "SRRC", "FCC", "CE", "NCC", "KCC", "MIC", "IC",
+    "ACMA", "ANATEL", "ISED", "WPC", "OFCA", "IFETEL", "RCM"
+  };

Review Comment:
   remove 2 spaces indentation.



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };
+
+/* Whether it is a new bin */
+
+static bool g_multiple_phy_init_data_bin = false;
+
+/* PHY init data type array */
+
+static char *g_phy_type[ESP_PHY_INIT_DATA_TYPE_NUMBER] =
+  {
+    "DEFAULT", "SRRC", "FCC", "CE", "NCC", "KCC", "MIC", "IC",
+    "ACMA", "ANATEL", "ISED", "WPC", "OFCA", "IFETEL", "RCM"
+  };
+
+/* Country and PHY init data type map */
+
+static phy_country_to_bin_type_t g_country_code_map_type_table[] =
+  {
+    {"AT",  ESP_PHY_INIT_DATA_TYPE_CE},

Review Comment:
   ```suggestion
       {"AT", ESP_PHY_INIT_DATA_TYPE_CE},
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };
+
+/* Whether it is a new bin */
+
+static bool g_multiple_phy_init_data_bin = false;
+
+/* PHY init data type array */
+
+static char *g_phy_type[ESP_PHY_INIT_DATA_TYPE_NUMBER] =
+  {
+    "DEFAULT", "SRRC", "FCC", "CE", "NCC", "KCC", "MIC", "IC",
+    "ACMA", "ANATEL", "ISED", "WPC", "OFCA", "IFETEL", "RCM"
+  };
+
+/* Country and PHY init data type map */
+
+static phy_country_to_bin_type_t g_country_code_map_type_table[] =
+  {
+    {"AT",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"AU",  ESP_PHY_INIT_DATA_TYPE_ACMA},
+    {"BE",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"BG",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"BR",  ESP_PHY_INIT_DATA_TYPE_ANATEL},
+    {"CA",  ESP_PHY_INIT_DATA_TYPE_ISED},
+    {"CH",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"CN",  ESP_PHY_INIT_DATA_TYPE_SRRC},
+    {"CY",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"CZ",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"DE",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"DK",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"EE",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"ES",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"FI",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"FR",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"GB",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"GR",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"HK",  ESP_PHY_INIT_DATA_TYPE_OFCA},
+    {"HR",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"HU",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"IE",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"IN",  ESP_PHY_INIT_DATA_TYPE_WPC},
+    {"IS",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"IT",  ESP_PHY_INIT_DATA_TYPE_CE},
+    {"JP",  ESP_PHY_INIT_DATA_TYPE_MIC},
+    {"KR",  ESP_PHY_INIT_DATA_TYPE_KCC},

Review Comment:
   remove 2 spaces indentation.



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -86,6 +89,85 @@ static uint32_t *g_phy_digital_regs_mem = NULL;
 
 static bool g_is_phy_calibrated = false;
 
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+static const char phy_partion_label[] = "phy_init";
+#endif
+
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+static phy_init_data_type_t g_phy_init_data_type = 0;
+
+static phy_init_data_type_t g_current_apply_phy_init_data = 0;
+
+static char g_phy_current_country[PHY_COUNTRY_CODE_LEN] =
+  {
+    0
+  };
+
+/* Whether it is a new bin */
+
+static bool g_multiple_phy_init_data_bin = false;
+
+/* PHY init data type array */
+
+static char *g_phy_type[ESP_PHY_INIT_DATA_TYPE_NUMBER] =

Review Comment:
   ```suggestion
   static const char *g_phy_type[ESP_PHY_INIT_DATA_TYPE_NUMBER] =
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);

Review Comment:
   ```suggestion
     uint8_t num = nitems(g_country_code_map_type_table);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);

Review Comment:
   Optional
   ```suggestion
     uint32_t crc_data = crc32_le(0, data, length);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);

Review Comment:
   Better to use `HTONL` in kernel
   ```suggestion
     uint32_t crc_size_conversion = HTONL(crc_data);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))

Review Comment:
   Can we change `checksum` to be `uint32_t *` to avoid cast?



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static esp_err_t phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const uint8_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *(input_data + (i * sizeof(esp_phy_init_data_t))

Review Comment:
   Maybe can cast `input_data` to local variable of `esp_phy_init_data_t *` and use `[I]` here? Just for better readability.



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))

Review Comment:
   ```suggestion
         if (!memcmp(country, g_country_code_map_type_table[i].cc,
                     sizeof(g_phy_current_country)))
   ```
   Why use `sizeof(g_phy_current_country)` and not `sizeof(g_country_code_map_type_table[i].cc)` or `PHY_COUNTRY_CODE_LEN`?



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static esp_err_t phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const uint8_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *(input_data + (i * sizeof(esp_phy_init_data_t))
+          + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre), input_data +
+          (i * sizeof(esp_phy_init_data_t)), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,
+      control_info->control_info_checksum, sizeof(phy_control_info_data_t) -
+                                sizeof(control_info->control_info_checksum));
+      if (ret != OK)
+        {
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data control info check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  uint8_t *init_data_multiple = (uint8_t *)
+        kmm_malloc(sizeof(esp_phy_init_data_t) * control_info->number);
+  if (init_data_multiple == NULL)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, length +
+          sizeof(phy_control_info_data_t), init_data_multiple,
+          sizeof(esp_phy_init_data_t) * control_info->number);
+  if (ret != OK)
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY init data multiple bin partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret = phy_crc_check(init_data_multiple,
+              control_info->multiple_bin_checksum,
+              sizeof(esp_phy_init_data_t) * control_info->number);
+      if (ret != OK)
+        {
+          kmm_free(init_data_multiple);
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data multiple bin check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  ret = phy_find_bin_data_according_type(data, control_info,
+                              init_data_multiple, init_data_type);
+  if (ret != OK)
+    {
+      wlerr("ERROR: %s has not been certified, use DEFAULT PHY init data\n",
+            g_phy_type[init_data_type]);
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+  else
+    {
+      g_phy_init_data_type = init_data_type;
+    }
+
+  kmm_free(init_data_multiple);
+  kmm_free(control_info);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_phy_update_init_data
+ *
+ * Description:
+ *   Update PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int esp_phy_update_init_data(phy_init_data_type_t init_data_type)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+      sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for updated country code "
+            "PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to read updated country code PHY data\n");
+      return ret;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC,
+      sizeof(phy_init_magic_pre)) != 0 ||
+      memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to validate updated country code PHY data\n");
+      return ERROR;
+    }
+
+  /* find init data bin according init data type */
+
+  if (init_data_type != ESP_PHY_INIT_DATA_TYPE_DEFAULT)
+    {
+      ret = phy_get_multiple_init_data(init_data_store, length,
+                                       init_data_type);
+      if (ret != OK)
+        {
+          kmm_free(init_data_store);
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_ERROR
+          abort();
+#else
+          return ret;
+#endif
+        }
+    }
+  else
+    {
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+
+  if (g_current_apply_phy_init_data != g_phy_init_data_type)
+    {
+      ret = esp_phy_apply_phy_init_data(init_data_store +
+                              sizeof(phy_init_magic_pre));
+      if (ret != OK)
+        {
+          wlerr("ERROR: PHY init data failed to load\n");
+          kmm_free(init_data_store);
+          return ret;
+        }
+
+      wlinfo("PHY init data type updated from %s to %s\n",
+             g_phy_type[g_current_apply_phy_init_data],
+             g_phy_type[g_phy_init_data_type]);
+      g_current_apply_phy_init_data = g_phy_init_data_type;
+    }
+
+  kmm_free(init_data_store);
+  return OK;
+}
+
+#endif
+
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+
+/****************************************************************************
+ * Name: esp_phy_get_init_data
+ *
+ * Description:
+ *   Get PHY init data
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to PHY init data structure
+ *
+ ****************************************************************************/
+
+const esp_phy_init_data_t *esp_phy_get_init_data(void)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+          sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return NULL;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to get read data from MTD\n");
+      kmm_free(init_data_store);
+      return NULL;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre))
+      != 0 || memcmp(init_data_store + length - sizeof(phy_init_magic_post),

Review Comment:
   Can we use `!= 0` or `== 0` in other places where `memcmp` is used?



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static esp_err_t phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const uint8_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *(input_data + (i * sizeof(esp_phy_init_data_t))
+          + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre), input_data +
+          (i * sizeof(esp_phy_init_data_t)), sizeof(esp_phy_init_data_t));

Review Comment:
   ```suggestion
             memcpy(output_data + sizeof(phy_init_magic_pre),
                    input_data + (i * sizeof(esp_phy_init_data_t)),
                    sizeof(esp_phy_init_data_t));
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.h:
##########
@@ -39,7 +39,10 @@
  * headers
  */
 
-#define CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN 0
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+#undef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
+#define CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN 1

Review Comment:
   ```suggestion
   #  undef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN
   #  define CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA_BIN 1
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -366,6 +918,54 @@ int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
   return 0;
 }
 
+/****************************************************************************
+ * Name: esp32_phy_update_country_info
+ *
+ * Description:
+ *   Update PHY init data according to country code
+ *
+ * Input Parameters:
+ *   country - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+int esp32_phy_update_country_info(const char *country)
+{
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+  uint8_t phy_init_data_type_map = 0;
+  if (!memcmp(country, g_phy_current_country, sizeof(g_phy_current_country)))
+    {
+      return OK;
+    }
+
+  memcpy(g_phy_current_country, country, sizeof(g_phy_current_country));
+  if (!g_multiple_phy_init_data_bin)
+    {
+      wlerr("ERROR: Does not support multiple PHY init data bins\n");
+      return ERROR;
+    }
+
+  phy_init_data_type_map = phy_find_bin_type_according_country(country);
+  if (phy_init_data_type_map == g_phy_init_data_type)
+    {
+      return OK;
+    }
+
+  int ret =  esp_phy_update_init_data(phy_init_data_type_map);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to update PHY init data\n");
+      return ret;
+    }
+

Review Comment:
   ```suggestion
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] pkarashchenko commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "pkarashchenko (via GitHub)" <gi...@apache.org>.
pkarashchenko commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1219784103


##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));

Review Comment:
   ```suggestion
             memcpy(output_data + sizeof(phy_init_magic_pre),
                    (input_data + i), sizeof(esp_phy_init_data_t));
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,

Review Comment:
   ```suggestion
         ret = phy_crc_check(control_info->multiple_bin_checksum,
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,
+      control_info->control_info_checksum, sizeof(phy_control_info_data_t) -
+                                sizeof(control_info->control_info_checksum));
+      if (ret != OK)
+        {
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data control info check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  uint8_t *init_data_multiple = (uint8_t *)
+        kmm_malloc(sizeof(esp_phy_init_data_t) * control_info->number);
+  if (init_data_multiple == NULL)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, length +
+          sizeof(phy_control_info_data_t), init_data_multiple,
+          sizeof(esp_phy_init_data_t) * control_info->number);
+  if (ret != OK)
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY init data multiple bin partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret = phy_crc_check(init_data_multiple,
+              control_info->multiple_bin_checksum,
+              sizeof(esp_phy_init_data_t) * control_info->number);
+      if (ret != OK)
+        {
+          kmm_free(init_data_multiple);
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data multiple bin check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  ret = phy_find_bin_data_according_type(data, control_info,
+          (const esp_phy_init_data_t *)init_data_multiple, init_data_type);
+  if (ret != OK)
+    {
+      wlerr("ERROR: %s has not been certified, use DEFAULT PHY init data\n",
+            g_phy_type[init_data_type]);
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+  else
+    {
+      g_phy_init_data_type = init_data_type;
+    }
+
+  kmm_free(init_data_multiple);
+  kmm_free(control_info);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_update_init_data
+ *
+ * Description:
+ *   Update PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_update_init_data(phy_init_data_type_t init_data_type)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+      sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for updated country code "
+            "PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to read updated country code PHY data\n");
+      return ret;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC,
+      sizeof(phy_init_magic_pre)) != 0 ||
+      memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to validate updated country code PHY data\n");
+      return ERROR;
+    }
+
+  /* find init data bin according init data type */
+
+  if (init_data_type != ESP_PHY_INIT_DATA_TYPE_DEFAULT)
+    {
+      ret = phy_get_multiple_init_data(init_data_store, length,
+                                       init_data_type);
+      if (ret != OK)
+        {
+          kmm_free(init_data_store);
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_ERROR
+          abort();
+#else
+          return ret;
+#endif
+        }
+    }
+  else
+    {
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+
+  if (g_current_apply_phy_init_data != g_phy_init_data_type)
+    {
+      ret = esp_phy_apply_phy_init_data(init_data_store +
+                              sizeof(phy_init_magic_pre));
+      if (ret != OK)
+        {
+          wlerr("ERROR: PHY init data failed to load\n");
+          kmm_free(init_data_store);
+          return ret;
+        }
+
+      wlinfo("PHY init data type updated from %s to %s\n",
+             g_phy_type[g_current_apply_phy_init_data],
+             g_phy_type[g_phy_init_data_type]);
+      g_current_apply_phy_init_data = g_phy_init_data_type;
+    }
+
+  kmm_free(init_data_store);
+  return OK;
+}
+
+#endif
+
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+
+/****************************************************************************
+ * Name: esp_phy_get_init_data
+ *
+ * Description:
+ *   Get PHY init data
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to PHY init data structure
+ *
+ ****************************************************************************/
+
+const esp_phy_init_data_t *esp_phy_get_init_data(void)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+          sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return NULL;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to get read data from MTD\n");
+      kmm_free(init_data_store);
+      return NULL;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre))
+      != 0 || memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+              PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+#ifdef CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID
+      wlerr("ERROR: Failed to validate PHY data partition, restoring "
+            "default data into flash...");
+      memcpy(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre),
+             &phy_init_data, sizeof(phy_init_data));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre) +
+        sizeof(phy_init_data), PHY_INIT_MAGIC, sizeof(phy_init_magic_post));
+      DEBUGASSERT(memcmp(init_data_store, PHY_INIT_MAGIC,
+                sizeof(phy_init_magic_pre)) == 0);
+      DEBUGASSERT(memcmp(init_data_store + length -
+                sizeof(phy_init_magic_post), PHY_INIT_MAGIC,
+                sizeof(phy_init_magic_post)) == 0);

Review Comment:
   ```suggestion
         DEBUGASSERT(memcmp(init_data_store + length -
                     sizeof(phy_init_magic_post), PHY_INIT_MAGIC,
                     sizeof(phy_init_magic_post)) == 0);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,
+      control_info->control_info_checksum, sizeof(phy_control_info_data_t) -
+                                sizeof(control_info->control_info_checksum));
+      if (ret != OK)
+        {
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data control info check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  uint8_t *init_data_multiple = (uint8_t *)
+        kmm_malloc(sizeof(esp_phy_init_data_t) * control_info->number);
+  if (init_data_multiple == NULL)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, length +
+          sizeof(phy_control_info_data_t), init_data_multiple,
+          sizeof(esp_phy_init_data_t) * control_info->number);
+  if (ret != OK)
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY init data multiple bin partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret = phy_crc_check(init_data_multiple,
+              control_info->multiple_bin_checksum,
+              sizeof(esp_phy_init_data_t) * control_info->number);
+      if (ret != OK)
+        {
+          kmm_free(init_data_multiple);
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data multiple bin check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  ret = phy_find_bin_data_according_type(data, control_info,
+          (const esp_phy_init_data_t *)init_data_multiple, init_data_type);
+  if (ret != OK)
+    {
+      wlerr("ERROR: %s has not been certified, use DEFAULT PHY init data\n",
+            g_phy_type[init_data_type]);
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+  else
+    {
+      g_phy_init_data_type = init_data_type;
+    }
+
+  kmm_free(init_data_multiple);
+  kmm_free(control_info);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_update_init_data
+ *
+ * Description:
+ *   Update PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_update_init_data(phy_init_data_type_t init_data_type)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+      sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for updated country code "
+            "PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to read updated country code PHY data\n");
+      return ret;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC,
+      sizeof(phy_init_magic_pre)) != 0 ||
+      memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to validate updated country code PHY data\n");
+      return ERROR;
+    }
+
+  /* find init data bin according init data type */
+
+  if (init_data_type != ESP_PHY_INIT_DATA_TYPE_DEFAULT)
+    {
+      ret = phy_get_multiple_init_data(init_data_store, length,
+                                       init_data_type);
+      if (ret != OK)
+        {
+          kmm_free(init_data_store);
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_ERROR
+          abort();
+#else
+          return ret;
+#endif
+        }
+    }
+  else
+    {
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+
+  if (g_current_apply_phy_init_data != g_phy_init_data_type)
+    {
+      ret = esp_phy_apply_phy_init_data(init_data_store +
+                              sizeof(phy_init_magic_pre));
+      if (ret != OK)
+        {
+          wlerr("ERROR: PHY init data failed to load\n");
+          kmm_free(init_data_store);
+          return ret;
+        }
+
+      wlinfo("PHY init data type updated from %s to %s\n",
+             g_phy_type[g_current_apply_phy_init_data],
+             g_phy_type[g_phy_init_data_type]);
+      g_current_apply_phy_init_data = g_phy_init_data_type;
+    }
+
+  kmm_free(init_data_store);
+  return OK;
+}
+
+#endif
+
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+
+/****************************************************************************
+ * Name: esp_phy_get_init_data
+ *
+ * Description:
+ *   Get PHY init data
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to PHY init data structure
+ *
+ ****************************************************************************/
+
+const esp_phy_init_data_t *esp_phy_get_init_data(void)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+          sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return NULL;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to get read data from MTD\n");
+      kmm_free(init_data_store);
+      return NULL;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre))
+      != 0 || memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+              PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+#ifdef CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID
+      wlerr("ERROR: Failed to validate PHY data partition, restoring "
+            "default data into flash...");
+      memcpy(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre),
+             &phy_init_data, sizeof(phy_init_data));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre) +
+        sizeof(phy_init_data), PHY_INIT_MAGIC, sizeof(phy_init_magic_post));

Review Comment:
   ```suggestion
         memcpy(init_data_store + sizeof(phy_init_magic_pre) +
                sizeof(phy_init_data), PHY_INIT_MAGIC,
                sizeof(phy_init_magic_post));
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,
+      control_info->control_info_checksum, sizeof(phy_control_info_data_t) -
+                                sizeof(control_info->control_info_checksum));
+      if (ret != OK)
+        {
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data control info check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  uint8_t *init_data_multiple = (uint8_t *)
+        kmm_malloc(sizeof(esp_phy_init_data_t) * control_info->number);
+  if (init_data_multiple == NULL)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, length +
+          sizeof(phy_control_info_data_t), init_data_multiple,
+          sizeof(esp_phy_init_data_t) * control_info->number);
+  if (ret != OK)
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY init data multiple bin partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret = phy_crc_check(init_data_multiple,
+              control_info->multiple_bin_checksum,
+              sizeof(esp_phy_init_data_t) * control_info->number);
+      if (ret != OK)
+        {
+          kmm_free(init_data_multiple);
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data multiple bin check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  ret = phy_find_bin_data_according_type(data, control_info,
+          (const esp_phy_init_data_t *)init_data_multiple, init_data_type);
+  if (ret != OK)
+    {
+      wlerr("ERROR: %s has not been certified, use DEFAULT PHY init data\n",
+            g_phy_type[init_data_type]);
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+  else
+    {
+      g_phy_init_data_type = init_data_type;
+    }
+
+  kmm_free(init_data_multiple);
+  kmm_free(control_info);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_update_init_data
+ *
+ * Description:
+ *   Update PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_update_init_data(phy_init_data_type_t init_data_type)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+      sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for updated country code "
+            "PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to read updated country code PHY data\n");
+      return ret;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC,
+      sizeof(phy_init_magic_pre)) != 0 ||
+      memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to validate updated country code PHY data\n");
+      return ERROR;
+    }
+
+  /* find init data bin according init data type */
+
+  if (init_data_type != ESP_PHY_INIT_DATA_TYPE_DEFAULT)
+    {
+      ret = phy_get_multiple_init_data(init_data_store, length,
+                                       init_data_type);
+      if (ret != OK)
+        {
+          kmm_free(init_data_store);
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_ERROR
+          abort();
+#else
+          return ret;
+#endif
+        }
+    }
+  else
+    {
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+
+  if (g_current_apply_phy_init_data != g_phy_init_data_type)
+    {
+      ret = esp_phy_apply_phy_init_data(init_data_store +
+                              sizeof(phy_init_magic_pre));
+      if (ret != OK)
+        {
+          wlerr("ERROR: PHY init data failed to load\n");
+          kmm_free(init_data_store);
+          return ret;
+        }
+
+      wlinfo("PHY init data type updated from %s to %s\n",
+             g_phy_type[g_current_apply_phy_init_data],
+             g_phy_type[g_phy_init_data_type]);
+      g_current_apply_phy_init_data = g_phy_init_data_type;
+    }
+
+  kmm_free(init_data_store);
+  return OK;
+}
+
+#endif
+
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+
+/****************************************************************************
+ * Name: esp_phy_get_init_data
+ *
+ * Description:
+ *   Get PHY init data
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to PHY init data structure
+ *
+ ****************************************************************************/
+
+const esp_phy_init_data_t *esp_phy_get_init_data(void)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+          sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return NULL;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to get read data from MTD\n");
+      kmm_free(init_data_store);
+      return NULL;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre))
+      != 0 || memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+              PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+#ifdef CONFIG_ESP32_PHY_DEFAULT_INIT_IF_INVALID
+      wlerr("ERROR: Failed to validate PHY data partition, restoring "
+            "default data into flash...");
+      memcpy(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre),
+             &phy_init_data, sizeof(phy_init_data));
+      memcpy(init_data_store + sizeof(phy_init_magic_pre) +
+        sizeof(phy_init_data), PHY_INIT_MAGIC, sizeof(phy_init_magic_post));
+      DEBUGASSERT(memcmp(init_data_store, PHY_INIT_MAGIC,
+                sizeof(phy_init_magic_pre)) == 0);

Review Comment:
   ```suggestion
         DEBUGASSERT(memcmp(init_data_store, PHY_INIT_MAGIC,
                     sizeof(phy_init_magic_pre)) == 0);
   ```



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))

Review Comment:
   I'm not sure if ESP32 supports unaligned access. If it is, then my comment can be ignored, but I see that
   ```
   typedef struct {
       uint8_t control_info_checksum[4];     /*!< 4-byte control infomation checksum */
       uint8_t multiple_bin_checksum[4];     /*!< 4-byte multiple bin checksum */
       uint8_t check_algorithm;              /*!< check algorithm */
       uint8_t version;                      /*!< PHY init data bin version */
       uint8_t number;                       /*!< PHY init data bin number */
       uint8_t length[2];                    /*!< Length of each PHY init data bin */
       uint8_t reserved[19];                 /*!< 19-byte reserved  */
   } __attribute__ ((packed)) phy_control_info_data_t;
   ```
   So if unaligned access is not supported casting and dereferencing `checksum` to `uint_32_t *` may lead to unaligned access.
   If unaligned access is not supported then we need to go with
   ```
   uint32_t tmp = checksum[0] | (checksum[1] << 8) | (checksum[2] << 16) | (checksum[3] << 24);
   if (crc_size_conversion != tmp)
   ```
   to be safe



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] cwespressif commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "cwespressif (via GitHub)" <gi...@apache.org>.
cwespressif commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1220764863


##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +367,474 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = crc32_le(0, data, length);
+  uint32_t crc_size_conversion = HTONL(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = nitems(g_country_code_map_type_table);
+  for (i = 0; i < num; i++)
+    {
+      if (memcmp(country, g_country_code_map_type_table[i].cc,
+          PHY_COUNTRY_CODE_LEN) == 0)
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const esp_phy_init_data_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *((uint8_t *)(input_data + i)
+                              + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre),
+                (input_data + i), sizeof(esp_phy_init_data_t));

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] cwespressif commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "cwespressif (via GitHub)" <gi...@apache.org>.
cwespressif commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1219086518


##########
arch/xtensa/src/esp32/Kconfig:
##########
@@ -2170,6 +2170,63 @@ config ESP32_UNIVERSAL_MAC_ADDRESSES
 	default 2 if ESP32_UNIVERSAL_MAC_ADDRESSES_TWO
 	default 4 if ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
 
+menu "PHY"
+	depends on ESP32_PARTITION_TABLE
+
+menuconfig ESP32_PHY_INIT_DATA_IN_PARTITION
+	bool "Use a partition to store PHY init data"
+	default n
+	help

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] cwespressif commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "cwespressif (via GitHub)" <gi...@apache.org>.
cwespressif commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1219092335


##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static esp_err_t phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const uint8_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *(input_data + (i * sizeof(esp_phy_init_data_t))

Review Comment:
   Done,  thanks for the suggestion.



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))
+        {
+          phy_init_data_type = g_country_code_map_type_table[i].type;
+          wlinfo("Current country is %c%c, PHY init data type is %s\n",
+                  g_country_code_map_type_table[i].cc[0],
+                  g_country_code_map_type_table[i].cc[1],
+                  g_phy_type[g_country_code_map_type_table[i].type]);
+          break;
+        }
+    }
+
+  if (i == num)
+    {
+      phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+      wlerr("Use the default certification code beacuse %c%c doesn't "
+            "have a certificate\n", country[0], country[1]);
+    }
+
+  return phy_init_data_type;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_data_according_type
+ *
+ * Description:
+ *   Find the PHY initialization data according to PHY init data type
+ *
+ * Input Parameters:
+ *   output_data    - Output data buffer pointer
+ *   control_info   - PHY init data control infomation
+ *   input_data     - Input data buffer pointer
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static esp_err_t phy_find_bin_data_according_type(uint8_t *output_data,
+        const phy_control_info_data_t *control_info,
+        const uint8_t *input_data,
+        phy_init_data_type_t init_data_type)
+{
+  int i;
+  for (i = 0; i < control_info->number; i++)
+    {
+      if (init_data_type == *(input_data + (i * sizeof(esp_phy_init_data_t))
+          + PHY_INIT_DATA_TYPE_OFFSET))
+        {
+          memcpy(output_data + sizeof(phy_init_magic_pre), input_data +
+          (i * sizeof(esp_phy_init_data_t)), sizeof(esp_phy_init_data_t));
+          break;
+        }
+    }
+
+  if (i == control_info->number)
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_get_multiple_init_data
+ *
+ * Description:
+ *   Get multiple PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   data           - Data buffer pointer
+ *   length         - Data length
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_get_multiple_init_data(uint8_t *data, size_t length,
+                                      phy_init_data_type_t init_data_type)
+{
+  phy_control_info_data_t *control_info = (phy_control_info_data_t *)
+                                kmm_malloc(sizeof(phy_control_info_data_t));
+  if (control_info == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for\
+            PHY init data control info\n");
+      return -ENOMEM;
+    }
+
+  int ret = esp32_partition_read(phy_partion_label, length,
+              control_info, sizeof(phy_control_info_data_t));
+  if (ret != OK)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY control info data partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret =  phy_crc_check(control_info->multiple_bin_checksum,
+      control_info->control_info_checksum, sizeof(phy_control_info_data_t) -
+                                sizeof(control_info->control_info_checksum));
+      if (ret != OK)
+        {
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data control info check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  uint8_t *init_data_multiple = (uint8_t *)
+        kmm_malloc(sizeof(esp_phy_init_data_t) * control_info->number);
+  if (init_data_multiple == NULL)
+    {
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, length +
+          sizeof(phy_control_info_data_t), init_data_multiple,
+          sizeof(esp_phy_init_data_t) * control_info->number);
+  if (ret != OK)
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Failed to read PHY init data multiple bin partition\n");
+      return ret;
+    }
+
+  if ((control_info->check_algorithm) == PHY_CRC_ALGORITHM)
+    {
+      ret = phy_crc_check(init_data_multiple,
+              control_info->multiple_bin_checksum,
+              sizeof(esp_phy_init_data_t) * control_info->number);
+      if (ret != OK)
+        {
+          kmm_free(init_data_multiple);
+          kmm_free(control_info);
+          wlerr("ERROR: PHY init data multiple bin check error\n");
+          return ret;
+        }
+    }
+  else
+    {
+      kmm_free(init_data_multiple);
+      kmm_free(control_info);
+      wlerr("ERROR: Check algorithm not CRC, PHY init data update failed\n");
+      return ERROR;
+    }
+
+  ret = phy_find_bin_data_according_type(data, control_info,
+                              init_data_multiple, init_data_type);
+  if (ret != OK)
+    {
+      wlerr("ERROR: %s has not been certified, use DEFAULT PHY init data\n",
+            g_phy_type[init_data_type]);
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+  else
+    {
+      g_phy_init_data_type = init_data_type;
+    }
+
+  kmm_free(init_data_multiple);
+  kmm_free(control_info);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: esp_phy_update_init_data
+ *
+ * Description:
+ *   Update PHY init data according to PHY init data type
+ *
+ * Input Parameters:
+ *   init_data_type - PHY init data type
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int esp_phy_update_init_data(phy_init_data_type_t init_data_type)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+      sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for updated country code "
+            "PHY init data\n");
+      return -ENOMEM;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to read updated country code PHY data\n");
+      return ret;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC,
+      sizeof(phy_init_magic_pre)) != 0 ||
+      memcmp(init_data_store + length - sizeof(phy_init_magic_post),
+      PHY_INIT_MAGIC, sizeof(phy_init_magic_post)) != 0)
+    {
+      kmm_free(init_data_store);
+      wlerr("ERROR: Failed to validate updated country code PHY data\n");
+      return ERROR;
+    }
+
+  /* find init data bin according init data type */
+
+  if (init_data_type != ESP_PHY_INIT_DATA_TYPE_DEFAULT)
+    {
+      ret = phy_get_multiple_init_data(init_data_store, length,
+                                       init_data_type);
+      if (ret != OK)
+        {
+          kmm_free(init_data_store);
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_ERROR
+          abort();
+#else
+          return ret;
+#endif
+        }
+    }
+  else
+    {
+      g_phy_init_data_type = ESP_PHY_INIT_DATA_TYPE_DEFAULT;
+    }
+
+  if (g_current_apply_phy_init_data != g_phy_init_data_type)
+    {
+      ret = esp_phy_apply_phy_init_data(init_data_store +
+                              sizeof(phy_init_magic_pre));
+      if (ret != OK)
+        {
+          wlerr("ERROR: PHY init data failed to load\n");
+          kmm_free(init_data_store);
+          return ret;
+        }
+
+      wlinfo("PHY init data type updated from %s to %s\n",
+             g_phy_type[g_current_apply_phy_init_data],
+             g_phy_type[g_phy_init_data_type]);
+      g_current_apply_phy_init_data = g_phy_init_data_type;
+    }
+
+  kmm_free(init_data_store);
+  return OK;
+}
+
+#endif
+
+#ifdef CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION
+
+/****************************************************************************
+ * Name: esp_phy_get_init_data
+ *
+ * Description:
+ *   Get PHY init data
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Pointer to PHY init data structure
+ *
+ ****************************************************************************/
+
+const esp_phy_init_data_t *esp_phy_get_init_data(void)
+{
+  int ret;
+  size_t length = sizeof(phy_init_magic_pre) +
+          sizeof(esp_phy_init_data_t) + sizeof(phy_init_magic_post);
+  uint8_t *init_data_store = (uint8_t *)kmm_malloc(length);
+  if (init_data_store == NULL)
+    {
+      wlerr("ERROR: Failed to allocate memory for PHY init data\n");
+      return NULL;
+    }
+
+  ret = esp32_partition_read(phy_partion_label, 0, init_data_store, length);
+  if (ret != OK)
+    {
+      wlerr("ERROR: Failed to get read data from MTD\n");
+      kmm_free(init_data_store);
+      return NULL;
+    }
+
+  if (memcmp(init_data_store, PHY_INIT_MAGIC, sizeof(phy_init_magic_pre))
+      != 0 || memcmp(init_data_store + length - sizeof(phy_init_magic_post),

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] cwespressif commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "cwespressif (via GitHub)" <gi...@apache.org>.
cwespressif commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1219093902


##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);
+  for (i = 0; i < num; i++)
+    {
+      if (!memcmp(country, g_country_code_map_type_table[i].cc,
+          sizeof(g_phy_current_country)))

Review Comment:
   Done, already using `PHY_COUNTRY_CODE_LEN`



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))
+    {
+      return ERROR;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: phy_find_bin_type_according_country
+ *
+ * Description:
+ *   Find the PHY initialization data type according to country code
+ *
+ * Input Parameters:
+ *   country - Country code pointer
+ *
+ * Returned Value:
+ *   PHY initialization data type
+ *
+ ****************************************************************************/
+
+static uint8_t phy_find_bin_type_according_country(const char *country)
+{
+  uint8_t i;
+  uint8_t phy_init_data_type;
+  uint8_t num = sizeof(g_country_code_map_type_table) /
+                sizeof(phy_country_to_bin_type_t);

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] cwespressif commented on a diff in pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "cwespressif (via GitHub)" <gi...@apache.org>.
cwespressif commented on code in PR #9475:
URL: https://github.com/apache/nuttx/pull/9475#discussion_r1219108971


##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);
+  if (crc_size_conversion != *(uint32_t *)(checksum))

Review Comment:
   No, the uint8_t type pointer checksum is read from flash, if conversion is not done here, then conversion will need to be done on the checksum.



##########
arch/xtensa/src/esp32/esp32_wireless.c:
##########
@@ -288,6 +370,476 @@ void esp32_phy_disable_clock(void)
   leave_critical_section(flags);
 }
 
+#ifdef CONFIG_ESP32_SUPPORT_MULTIPLE_PHY_INIT_DATA
+
+/****************************************************************************
+ * Name: phy_crc_check
+ *
+ * Description:
+ *   Check the checksum value of data
+ *
+ * Input Parameters:
+ *   data     - Data buffer pointer
+ *   length   - Data length
+ *   checksum - Checksum pointer
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int phy_crc_check(uint8_t *data, const uint8_t *checksum,
+                         size_t length)
+{
+  uint32_t crc_data = 0;
+  crc_data = crc32_le(crc_data, data, length);
+  uint32_t crc_size_conversion = htonl(crc_data);

Review Comment:
   Done



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


[GitHub] [nuttx] xiaoxiang781216 merged pull request #9475: xtensa/esp32: Support multiple PHY init data bin

Posted by "xiaoxiang781216 (via GitHub)" <gi...@apache.org>.
xiaoxiang781216 merged PR #9475:
URL: https://github.com/apache/nuttx/pull/9475


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org