You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2020/09/25 02:38:18 UTC

[GitHub] [incubator-nuttx] v01d commented on a change in pull request #1893: xtensa/esp32: Add ESP32 WiFi adapter and driver

v01d commented on a change in pull request #1893:
URL: https://github.com/apache/incubator-nuttx/pull/1893#discussion_r494708581



##########
File path: arch/xtensa/src/esp32/Make.defs
##########
@@ -136,3 +136,36 @@ ifeq ($(CONFIG_ARCH_USE_MODULE_TEXT),y)
 CHIP_CSRCS += esp32_modtext.c
 CMN_ASRCS += xtensa_loadstore.S
 endif
+
+ifeq ($(CONFIG_ESP32_WIRELESS),y)
+WIRELESS_DRV_UNPACK  = esp-wireless-drivers-3rdparty
+WIRELESS_DRV_ZIP     = master.zip
+WIRELESS_DRV_URL     = https://github.com/espressif/esp-wireless-drivers-3rdparty/archive

Review comment:
       better to point to specific commit

##########
File path: arch/xtensa/src/esp32/Kconfig
##########
@@ -531,4 +533,24 @@ config ESP32_ETH_PHY_ADDR
 
 endmenu # ESP32_EMAC
 
+menu "WiFi configuration"
+	depends on ESP32_WIRELESS
+
+config ESP32_WIFI_SAVE_PARAM
+	bool "Save WiFi Parameters"
+	default n
+	help
+		Enable this option, WiFi adapter save WiFi parameters
+		into file system without generating or calculating some
+		connection parameters again.

Review comment:
       ```suggestion
   		If you enable this option, WiFi adapter parameters will be saved
   		into the file system instead of computing them each time.
   ```
   
   Changed a bit the wording. Maybe you could specify which parameters?

##########
File path: arch/xtensa/src/esp32/esp32_wifi_adapter.c
##########
@@ -0,0 +1,4443 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_wifi_adapter.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <mqueue.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <clock/clock.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "nuttx/kmalloc.h"
+#include "nuttx/spinlock.h"
+#include <nuttx/irq.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
+
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_emac.h"
+#include "esp32_cpuint.h"
+#include "esp32_wifi_adapter.h"
+
+#include "espidf_wifi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PHY_RF_MASK   ((1 << PHY_BT_MODULE) | (1 << PHY_WIFI_MODULE))
+
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+#  define NVS_FS_PREFIX CONFIG_ESP32_WIFI_FS_MOUNTPT
+#  define NVS_DIR_BASE  NVS_FS_PREFIX"/wifi."
+#  define NVS_FILE_MODE 0777
+#endif
+
+#define WIFI_CONNECT_TIMEOUT  (10)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* WiFi interrupt adapter private data */
+
+struct irq_adpt
+{
+  void (*func)(void *arg);  /* Interrupt callback function */
+  void *arg;                /* Interrupt private data */
+};
+
+/* WiFi message queue private data */
+
+struct mq_adpt
+{
+  mqd_t    mq;              /* Message queue handle */
+  uint32_t msgsize;         /* Message size */
+  char     name[16];        /* Message queue name */
+};
+
+/* WiFi time private data */
+
+struct time_adpt
+{
+  time_t      sec;          /* Second value */
+  suseconds_t usec;         /* Micro second value */
+};
+
+/* WiFi timer private data */
+
+struct timer_adpt
+{
+  struct wdog_s wdog;       /* Timer handle */
+  struct work_s work;       /* Work priavte data */
+  bool          repeat;     /* Flags indicate if it is cycle */
+  uint32_t      delay;      /* Timeout ticks */
+
+  /* Timer callback function */
+
+  void          (*func)(void *priv);
+  void          *priv;      /* Timer private data */
+};
+
+/* WiFi event private data */
+
+struct evt_adpt
+{
+  sq_entry_t entry;         /* Sequence entry */
+  int32_t id;               /* Event ID */
+  uint8_t buf[0];           /* Event private data */
+};
+
+/* WiFi event notification private data */
+
+struct wifi_notify
+{
+  bool assigned;            /* Flag indicate if it is used */
+  pid_t pid;                /* Signal's target thread PID */
+  struct sigevent event;    /* Signal event private data */
+  struct sigwork_s work;    /* Signal work private data */
+};
+
+/* WiFi NVS private data */
+
+struct nvs_adpt
+{
+  char *index_name;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void esp_set_isr(int32_t n, void *f, void *arg);
+static void esp32_ints_on(uint32_t mask);
+static void esp32_ints_off(uint32_t mask);
+static void *esp_spin_lock_create(void);
+static void esp_spin_lock_delete(void *lock);
+static uint32_t esp_wifi_int_disable(void *wifi_int_mux);
+static void esp_wifi_int_restore(void *wifi_int_mux, uint32_t tmp);
+static void IRAM_ATTR esp_task_yield_from_isr(void);
+static void *esp_semphr_create(uint32_t max, uint32_t init);
+static void esp_semphr_delete(void *semphr);
+static int32_t esp_semphr_take(void *semphr, uint32_t block_time_tick);
+static int32_t esp_semphr_give(void *semphr);
+static void *esp_thread_semphr_get(void);
+static void *esp_mutex_create(void);
+static void *esp_recursive_mutex_create(void);
+static void esp_mutex_delete(void *mutex_data);
+static int32_t esp_mutex_lock(void *mutex_data);
+static int32_t esp_mutex_unlock(void *mutex_data);
+static void *esp_queue_create(uint32_t queue_len, uint32_t item_size);
+static void esp_queue_delete(void *queue);
+static int32_t esp_queue_send(void *queue, void *item,
+                              uint32_t block_time_tick);
+static int32_t esp_queue_send_from_isr(void *queue, void *item, void *hptw);
+static int32_t esp_queue_send_to_back(void *queue, void *item,
+                                      uint32_t block_time_tick);
+static int32_t esp_queue_send_to_front(void *queue, void *item,
+                                       uint32_t block_time_tick);
+static int32_t esp_queue_recv(void *queue, void *item,
+                              uint32_t block_time_tick);
+static uint32_t esp_queue_msg_waiting(void *queue);
+static void *esp_event_group_create(void);
+static void esp_event_group_delete(void *event);
+static uint32_t esp_event_group_set_bits(void *event, uint32_t bits);
+static uint32_t esp_event_group_clear_bits(void *event, uint32_t bits);
+static uint32_t esp_event_group_wait_bits(void *event,
+                                          uint32_t bits_to_wait_for,
+                                          int32_t clear_on_exit,
+                                          int32_t wait_for_all_bits,
+                                          uint32_t block_time_tick);
+static int32_t esp_task_create_pinned_to_core(void *task_func,
+                                              const char *name,
+                                              uint32_t stack_depth,
+                                              void *param,
+                                              uint32_t prio,
+                                              void *task_handle,
+                                              uint32_t core_id);
+static int32_t esp_task_create(void *task_func, const char *name,
+                               uint32_t stack_depth, void *param,
+                               uint32_t prio, void *task_handle);
+static void esp_task_delete(void *task_handle);
+static void esp_task_delay(uint32_t tick);
+static int32_t esp_task_ms_to_tick(uint32_t ms);
+static void *esp_task_get_current_task(void);
+static int32_t esp_task_get_max_priority(void);
+static void *esp_malloc(uint32_t size);
+static uint32_t esp_rand(void);
+static void esp_dport_access_stall_other_cpu_start(void);
+static void esp_dport_access_stall_other_cpu_end(void);
+static int32_t esp_phy_deinit_rf(uint32_t module);
+static void esp_phy_init(uint32_t module);
+static void esp_phy_enable_clock(void);
+static void esp_phy_disable_clock(void);
+static int32_t esp_wifi_read_mac(uint8_t *mac, uint32_t type);
+static void esp_timer_arm(void *timer, uint32_t tmout, bool repeat);
+static void esp_timer_disarm(void *timer);
+static void esp32_timer_done(void *timer);
+static void esp_timer_setfn(void *timer, void *pfunction, void *parg);
+static void esp_timer_cb(wdparm_t parm);
+static void esp_timer_arm_us(void *timer, uint32_t us, bool repeat);
+static void esp_periph_module_enable(uint32_t periph);
+static void esp_periph_module_disable(uint32_t periph);
+static int32_t esp_nvs_set_i8(uint32_t handle, const char *key,
+                              int8_t value);
+static int32_t esp_nvs_get_i8(uint32_t handle, const char *key,
+                              int8_t *out_value);
+static int32_t esp_nvs_set_u8(uint32_t handle, const char *key,
+                              uint8_t value);
+static int32_t esp_nvs_get_u8(uint32_t handle, const char *key,
+                              uint8_t *out_value);
+static int32_t esp_nvs_set_u16(uint32_t handle, const char *key,
+                               uint16_t value);
+static int32_t esp_nvs_get_u16(uint32_t handle, const char *key,
+                               uint16_t *out_value);
+static int32_t esp_nvs_open(const char *name, uint32_t open_mode,
+                            uint32_t *out_handle);
+static void esp_nvs_close(uint32_t handle);
+static int32_t esp_nvs_commit(uint32_t handle);
+static int32_t esp_nvs_set_blob(uint32_t handle, const char *key,
+                                const void *value, size_t length);
+static int32_t esp_nvs_get_blob(uint32_t handle, const char *key,
+                                void *out_value, size_t *length);
+static int32_t esp_nvs_erase_key(uint32_t handle, const char *key);
+static int32_t esp_get_random(uint8_t *buf, size_t len);
+static int32_t esp_get_time(void *t);
+static void esp_log_writev(uint32_t level, const char *tag,
+                           const char *format, va_list args);
+static void *esp_malloc_internal(size_t size);
+static void *esp_realloc_internal(void *ptr, size_t size);
+static void *esp_calloc_internal(size_t n, size_t size);
+static void *esp_zalloc_internal(size_t size);
+static void *esp_wifi_malloc(size_t size);
+static void *esp_wifi_realloc(void *ptr, size_t size);
+static void *esp_wifi_calloc(size_t n, size_t size);
+static void *esp_wifi_zalloc(size_t size);
+static int32_t esp_modem_enter_sleep(uint32_t module);
+static int32_t esp_modem_exit_sleep(uint32_t module);
+static int32_t esp_modem_register_sleep(uint32_t module);
+static int32_t esp_modem_deregister_sleep(uint32_t module);
+static void *esp_wifi_create_queue(int32_t queue_len, int32_t item_size);
+static void esp_wifi_delete_queue(void *queue);
+static uint32_t esp_coex_status_get(void);
+static void esp_coex_condition_set(uint32_t type, bool dissatisfy);
+static int32_t esp_coex_wifi_request(uint32_t event, uint32_t latency,
+                                     uint32_t duration);
+static int32_t esp_coex_wifi_release(uint32_t event);
+
+/****************************************************************************
+ * Public Functions declaration
+ ****************************************************************************/
+
+int64_t esp_timer_get_time(void);
+void esp_fill_random(void *buf, size_t len);
+void esp_log_write(uint32_t level, const char *tag, const char *format, ...);
+uint32_t esp_log_timestamp(void);
+uint8_t esp_crc8(const uint8_t *p, uint32_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* WiFi interrupt private data */
+
+static int s_wifi_irq;
+
+/* WiFi thread private data */
+
+static pthread_key_t s_wifi_thread_key;
+static bool s_wifi_tkey_init;
+
+/* WiFi sleep private data */
+
+static uint32_t s_esp32_module_mask;
+static uint32_t s_esp32_module_sleep;
+static bool s_esp32_sleep;
+static uint32_t s_phy_clk_en_cnt = 0;
+static bool s_esp23_phy_en;
+static uint32_t s_esp32_phy_init_mask;
+static int64_t s_esp32_phy_rf_stop_tm;
+
+/* WiFi event private data */
+
+static struct work_s s_wifi_evt_work;
+static sq_queue_t s_wifi_evt_queue;
+static struct wifi_notify s_wifi_notify[WIFI_ADPT_EVT_MAX];
+static sem_t s_connect_sem;
+static bool s_connected;
+
+static uint8_t s_ssid[32];
+static uint8_t s_password[64];
+static uint8_t s_ssid_len;
+static uint8_t s_password_len;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* WiFi OS adapter data */
+
+wifi_osi_funcs_t g_wifi_osi_funcs =
+{
+  ._version = ESP_WIFI_OS_ADAPTER_VERSION,
+  ._set_isr = esp_set_isr,
+  ._ints_on = esp32_ints_on,
+  ._ints_off = esp32_ints_off,
+  ._spin_lock_create = esp_spin_lock_create,
+  ._spin_lock_delete = esp_spin_lock_delete,
+  ._wifi_int_disable = esp_wifi_int_disable,
+  ._wifi_int_restore = esp_wifi_int_restore,
+  ._task_yield_from_isr = esp_task_yield_from_isr,
+  ._semphr_create = esp_semphr_create,
+  ._semphr_delete = esp_semphr_delete,
+  ._semphr_take = esp_semphr_take,
+  ._semphr_give = esp_semphr_give,
+  ._wifi_thread_semphr_get = esp_thread_semphr_get,
+  ._mutex_create = esp_mutex_create,
+  ._recursive_mutex_create = esp_recursive_mutex_create,
+  ._mutex_delete = esp_mutex_delete,
+  ._mutex_lock = esp_mutex_lock,
+  ._mutex_unlock = esp_mutex_unlock,
+  ._queue_create = esp_queue_create,
+  ._queue_delete = esp_queue_delete,
+  ._queue_send = esp_queue_send,
+  ._queue_send_from_isr = esp_queue_send_from_isr,
+  ._queue_send_to_back = esp_queue_send_to_back,
+  ._queue_send_to_front = esp_queue_send_to_front,
+  ._queue_recv = esp_queue_recv,
+  ._queue_msg_waiting = esp_queue_msg_waiting,
+  ._event_group_create = esp_event_group_create,
+  ._event_group_delete = esp_event_group_delete,
+  ._event_group_set_bits = esp_event_group_set_bits,
+  ._event_group_clear_bits = esp_event_group_clear_bits,
+  ._event_group_wait_bits = esp_event_group_wait_bits,
+  ._task_create_pinned_to_core = esp_task_create_pinned_to_core,
+  ._task_create = esp_task_create,
+  ._task_delete = esp_task_delete,
+  ._task_delay = esp_task_delay,
+  ._task_ms_to_tick = esp_task_ms_to_tick,
+  ._task_get_current_task = esp_task_get_current_task,
+  ._task_get_max_priority = esp_task_get_max_priority,
+  ._malloc = esp_malloc,
+  ._free = free,
+  ._event_post = esp_event_post,
+  ._get_free_heap_size = esp_get_free_heap_size,
+  ._rand = esp_rand,
+  ._dport_access_stall_other_cpu_start_wrap =
+      esp_dport_access_stall_other_cpu_start,
+  ._dport_access_stall_other_cpu_end_wrap =
+      esp_dport_access_stall_other_cpu_end,
+  ._phy_rf_deinit = esp_phy_deinit_rf,
+  ._phy_load_cal_and_init = esp_phy_init,
+  ._phy_common_clock_enable = esp_phy_enable_clock,
+  ._phy_common_clock_disable = esp_phy_disable_clock,
+  ._read_mac = esp_wifi_read_mac,
+  ._timer_arm = esp_timer_arm,
+  ._timer_disarm = esp_timer_disarm,
+  ._timer_done = esp32_timer_done,
+  ._timer_setfn = esp_timer_setfn,
+  ._timer_arm_us = esp_timer_arm_us,
+  ._periph_module_enable = esp_periph_module_enable,
+  ._periph_module_disable = esp_periph_module_disable,
+  ._esp_timer_get_time = esp_timer_get_time,
+  ._nvs_set_i8 = esp_nvs_set_i8,
+  ._nvs_get_i8 = esp_nvs_get_i8,
+  ._nvs_set_u8 = esp_nvs_set_u8,
+  ._nvs_get_u8 = esp_nvs_get_u8,
+  ._nvs_set_u16 = esp_nvs_set_u16,
+  ._nvs_get_u16 = esp_nvs_get_u16,
+  ._nvs_open = esp_nvs_open,
+  ._nvs_close = esp_nvs_close,
+  ._nvs_commit = esp_nvs_commit,
+  ._nvs_set_blob = esp_nvs_set_blob,
+  ._nvs_get_blob = esp_nvs_get_blob,
+  ._nvs_erase_key = esp_nvs_erase_key,
+  ._get_random = esp_get_random,
+  ._get_time = esp_get_time,
+  ._random = esp_random,
+  ._log_write = esp_log_write,
+  ._log_writev = esp_log_writev,
+  ._log_timestamp = esp_log_timestamp,
+  ._malloc_internal =  esp_malloc_internal,
+  ._realloc_internal = esp_realloc_internal,
+  ._calloc_internal = esp_calloc_internal,
+  ._zalloc_internal = esp_zalloc_internal,
+  ._wifi_malloc = esp_wifi_malloc,
+  ._wifi_realloc = esp_wifi_realloc,
+  ._wifi_calloc = esp_wifi_calloc,
+  ._wifi_zalloc = esp_wifi_zalloc,
+  ._wifi_create_queue = esp_wifi_create_queue,
+  ._wifi_delete_queue = esp_wifi_delete_queue,
+  ._modem_sleep_enter = esp_modem_enter_sleep,
+  ._modem_sleep_exit = esp_modem_exit_sleep,
+  ._modem_sleep_register = esp_modem_register_sleep,
+  ._modem_sleep_deregister = esp_modem_deregister_sleep,
+  ._coex_status_get = esp_coex_status_get,
+  ._coex_condition_set = esp_coex_condition_set,
+  ._coex_wifi_request = esp_coex_wifi_request,
+  ._coex_wifi_release = esp_coex_wifi_release,
+  ._magic = ESP_WIFI_OS_ADAPTER_MAGIC,
+};
+
+/* WiFi feature capacity data */
+
+uint64_t g_wifi_feature_caps;
+
+/* WiFi TAG string data */
+
+ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
+
+/****************************************************************************
+ * Private Functions and Public Functions only used by libraries
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_errno_trans
+ *
+ * Description:
+ *   Transform from nuttx error code to WiFi adapter error code
+ *
+ * Input Parameters:
+ *   ret - Nuttx error code
+ *
+ * Returned Value:
+ *   WiFi adapter error code
+ *
+ ****************************************************************************/
+
+static inline int32_t esp_errno_trans(int ret)
+{
+  if (!ret)
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_int_adpt_cb
+ *
+ * Description:
+ *   WiFi interrupt adapter callback function
+ *
+ * Input Parameters:
+ *   arg - interrupt adapter private data
+ *
+ * Returned Value:
+ *   0 on success
+ *
+ ****************************************************************************/
+
+static int esp_int_adpt_cb(int irq, void *context, FAR void *arg)
+{
+  struct irq_adpt *adapter = (struct irq_adpt *)arg;
+
+  adapter->func(adapter->arg);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_thread_semphr_free
+ *
+ * Description:
+ *   Delete thread self's semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semphore data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_thread_semphr_free(void *semphr)
+{
+  if (semphr)
+    {
+      esp_semphr_delete(semphr);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_update_time
+ *
+ * Description:
+ *   Transform ticks to time and add this time to timespec value
+ *
+ * Input Parameters:
+ *   timespec - Input timespec data pointer
+ *   ticks    - System ticks
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_update_time(struct timespec *timespec, uint32_t ticks)
+{
+  uint32_t tmp;
+
+  tmp = TICK2SEC(ticks);
+  timespec->tv_sec += tmp;
+
+  ticks -= SEC2TICK(tmp);
+  tmp = TICK2NSEC(ticks);
+
+  timespec->tv_nsec += tmp;
+}
+
+/****************************************************************************
+ * Name: esp_set_isr
+ *
+ * Description:
+ *   Register interrupt function
+ *
+ * Input Parameters:
+ *   n   - Interrupt ID
+ *   f   - Interrupt function
+ *   arg - Function private data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_set_isr(int32_t n, void *f, void *arg)
+{
+  int ret;
+  struct irq_adpt *adapter;
+  int irq;
+  int cpu = 0;
+  int tmp;
+
+  irq = esp32_alloc_levelint(1);
+  if (irq < 0)
+    {
+      wlerr("ERROR: Failed to alloc interrupt\n");
+      assert(0);
+      return ;
+    }
+
+  up_disable_irq(irq);
+
+  tmp = sizeof(struct irq_adpt);
+  adapter = kmm_malloc(tmp);
+  if (!adapter)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      assert(0);
+      return ;
+    }
+
+  adapter->func = f;
+  adapter->arg = arg;
+
+  tmp = n + XTENSA_IRQ_FIRSTPERIPH;
+  ret = irq_attach(tmp, esp_int_adpt_cb, adapter);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to attach IRQ %d\n", tmp);
+      assert(0);
+      return ;
+    }
+
+  esp32_attach_peripheral(cpu, n, irq);
+
+  s_wifi_irq = irq;
+}
+
+/****************************************************************************
+ * Name: esp32_ints_on
+ *
+ * Description:
+ *   Enable WiFi interrupt
+ *
+ * Input Parameters:
+ *   mask - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32_ints_on(uint32_t mask)
+{
+  up_enable_irq(s_wifi_irq);
+}
+
+/****************************************************************************
+ * Name: esp32_ints_on
+ *
+ * Description:
+ *   Disable WiFi interrupt
+ *
+ * Input Parameters:
+ *   mask - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32_ints_off(uint32_t mask)
+{
+  up_disable_irq(s_wifi_irq);
+}
+
+/****************************************************************************
+ * Name: esp_spin_lock_create
+ *
+ * Description:
+ *   Create spin lock in SMP mode
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Spin lock data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_spin_lock_create(void)
+{
+#ifdef CONFIG_SMP
+  spinlock_t *lock;
+  int tmp;
+
+  tmp = sizeof(struct spinlock_t);
+  lock = kmm_malloc(tmp);
+  if (!lock)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      DEBUGASSERT(0);
+    }
+
+  spin_initialize(lock, SP_UNLOCKED);
+
+  return lock;
+#else
+  /* If return NULL, code may check fail  */
+
+  return (void *)1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_spin_lock_delete
+ *
+ * Description:
+ *   Delete spin lock
+ *
+ * Input Parameters:
+ *   lock - Spin lock data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_spin_lock_delete(void *lock)
+{
+#ifdef CONFIG_SMP
+  kmm_free(lock);
+#else
+  DEBUGASSERT((int)lock == 1);
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_wifi_int_disable
+ *
+ * Description:
+ *   Enter critical by disable interrup, and take spin lock if
+ *   in SMP mode
+ *
+ * Input Parameters:
+ *   wifi_int_mux - Spin lock data pointer
+ *
+ * Returned Value:
+ *   CPU PS value.
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp_wifi_int_disable(void *wifi_int_mux)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+#ifdef CONFIG_SMP
+  spin_lock((volatile spinlock_t *)wifi_int_mux);
+#endif
+
+  return (uint32_t)flags;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_int_restore
+ *
+ * Description:
+ *   Exit from critical by enable interrup, and release spin
+ *   lock if in SMP mode
+ *
+ * Input Parameters:
+ *   wifi_int_mux - Spin lock data pointer
+ *   tmp          - CPU PS value.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp_wifi_int_restore(void *wifi_int_mux, uint32_t tmp)
+{
+  irqstate_t flags = (irqstate_t)tmp;
+
+#ifdef CONFIG_SMP
+  spin_unlock((volatile spinlock_t *)wifi_int_mux);
+#endif
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: esp_task_yield_from_isr
+ *
+ * Description:
+ *   Do nothing in Nuttx
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp_task_yield_from_isr(void)
+{
+  /* Do nothing */
+}
+
+/****************************************************************************
+ * Name: esp_semphr_create
+ *
+ * Description:
+ *   Create and initialize semaphore
+ *
+ * Input Parameters:
+ *   max  - No mean
+ *   init - semaphore initialization value
+ *
+ * Returned Value:
+ *   Semphore data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_semphr_create(uint32_t max, uint32_t init)
+{
+  int ret;
+  sem_t *sem;
+  int tmp;
+
+  tmp = sizeof(sem_t);
+  sem = kmm_malloc(tmp);
+  if (!sem)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = sem_init(sem, 0, init);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize sem error=%d\n", ret);
+      kmm_free(sem);
+      return NULL;
+    }
+
+  return sem;
+}
+
+/****************************************************************************
+ * Name: esp_semphr_delete
+ *
+ * Description:
+ *   Delete semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semphore data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_semphr_delete(void *semphr)
+{
+  sem_t *sem = (sem_t *)semphr;
+
+  sem_destroy(sem);
+  kmm_free(sem);
+}
+
+/****************************************************************************
+ * Name: esp_semphr_take
+ *
+ * Description:
+ *   Wait semaphore within a certain period of time
+ *
+ * Input Parameters:
+ *   semphr - Semphore data pointer
+ *   ticks  - Wait system ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_semphr_take(void *semphr, uint32_t ticks)
+{
+  int ret;
+  struct timespec timeout;
+  sem_t *sem = (sem_t *)semphr;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING)
+    {
+      ret = sem_wait(sem);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to wait sem\n");
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = sem_timedwait(sem, &timeout);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to wait sem in %d ticks\n", ticks);
+        }
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_semphr_give
+ *
+ * Description:
+ *   Post semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semphore data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_semphr_give(void *semphr)
+{
+  int ret;
+  sem_t *sem = (sem_t *)semphr;
+
+  ret = sem_post(sem);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to post sem error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_thread_semphr_get
+ *
+ * Description:
+ *   Get thread self's semaphore
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Semphore data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_thread_semphr_get(void)
+{
+  int ret;
+  void *sem;
+
+  if (s_wifi_tkey_init)
+  {
+    ret = pthread_key_create(&s_wifi_thread_key, esp_thread_semphr_free);
+    if (ret)
+      {
+        wlerr("ERROR: Failed to create pthread key\n");
+        return NULL;
+      }
+
+    s_wifi_tkey_init = true;
+  }
+
+  sem = pthread_getspecific(s_wifi_thread_key);
+  if (!sem)
+    {
+      sem = esp_semphr_create(1, 0);
+      if (!sem)
+        {
+          wlerr("ERROR: Failed to create semaphore\n");
+          return NULL;
+        }
+
+      ret = pthread_setspecific(s_wifi_thread_key, sem);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to set specific\n");
+          esp_semphr_delete(sem);
+          return NULL;
+        }
+    }
+
+  return sem;
+}
+
+/****************************************************************************
+ * Name: esp_mutex_create
+ *
+ * Description:
+ *   Create mutex
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Mutex data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_mutex_create(void)
+{
+  int ret;
+  pthread_mutex_t *mutex;
+  int tmp;
+
+  tmp = sizeof(pthread_mutex_t);
+  mutex = kmm_malloc(tmp);
+  if (!mutex)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = pthread_mutex_init(mutex, NULL);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize mutex error=%d\n", ret);
+      kmm_free(mutex);
+      return NULL;
+    }
+
+  return mutex;
+}
+
+/****************************************************************************
+ * Name: esp_recursive_mutex_create
+ *
+ * Description:
+ *   Create recursive mutex
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Recursive mutex data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_recursive_mutex_create(void)
+{
+  int ret;
+  pthread_mutex_t *mutex;
+  pthread_mutexattr_t attr;
+  int tmp;
+
+  ret = pthread_mutexattr_init(&attr);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize attr error=%d\n", ret);
+      return NULL;
+    }
+
+  ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to set attr type error=%d\n", ret);
+      return NULL;
+    }
+
+  tmp = sizeof(pthread_mutex_t);
+  mutex = kmm_malloc(tmp);
+  if (!mutex)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = pthread_mutex_init(mutex, &attr);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize mutex error=%d\n", ret);
+      kmm_free(mutex);
+      return NULL;
+    }
+
+  return mutex;
+}
+
+/****************************************************************************
+ * Name: esp_mutex_delete
+ *
+ * Description:
+ *   Delete mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_mutex_delete(void *mutex_data)
+{
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  pthread_mutex_destroy(mutex);
+  kmm_free(mutex);
+}
+
+/****************************************************************************
+ * Name: esp_mutex_lock
+ *
+ * Description:
+ *   Lock mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_mutex_lock(void *mutex_data)
+{
+  int ret;
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  ret = pthread_mutex_lock(mutex);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to lock mutex error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_mutex_unlock
+ *
+ * Description:
+ *   Unlock mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_mutex_unlock(void *mutex_data)
+{
+  int ret;
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  ret = pthread_mutex_unlock(mutex);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to unlock mutex error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_queue_create
+ *
+ * Description:
+ *   Create message queue
+ *
+ * Input Parameters:
+ *   queue_len - queue message number
+ *   item_size - message size
+ *
+ * Returned Value:
+ *   Message queue data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_queue_create(uint32_t queue_len, uint32_t item_size)
+{
+  struct mq_attr attr;
+  mqd_t mq;
+  struct mq_adpt *mq_adpt;
+
+  mq_adpt = kmm_malloc(sizeof(struct mq_adpt));
+  if (!mq_adpt)
+    {
+      wlerr("ERROR: Failed to malloc\n");
+      return NULL;
+    }
+
+  snprintf(mq_adpt->name, sizeof(mq_adpt->name),
+           "/tmp/%X", mq_adpt);
+
+  attr.mq_maxmsg  = queue_len;
+  attr.mq_msgsize = item_size;
+  attr.mq_curmsgs = 0;
+  attr.mq_flags   = 0;
+
+  mq = mq_open(mq_adpt->name, O_RDWR | O_CREAT, 0644, &attr);
+  if (!mq)
+    {
+      wlerr("ERROR: Failed to create mqueue\n");
+      kmm_free(mq_adpt);
+      return NULL;
+    }
+
+  mq_adpt->mq = mq;
+  mq_adpt->msgsize = item_size;
+
+  return (void *)mq_adpt;
+}
+
+/****************************************************************************
+ * Name: esp_queue_delete
+ *
+ * Description:
+ *   Delete message queue
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_queue_delete(void *queue)
+{
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  mq_close(mq_adpt->mq);
+  mq_unlink(mq_adpt->name);
+  kmm_free(mq_adpt);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_generic
+ *
+ * Description:
+ *   Generic send message to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *   prio  - Message priority
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_generic(void *queue, void *item,
+                                      uint32_t ticks, int prio)
+{
+  int ret;
+  struct timespec timeout;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0)
+    {
+      /**
+       * WiFi interrupt function will call this adapter function to send
+       * message to message queue, so here we should call kernel API
+       * instead of application API
+       */
+
+      ret = nxmq_send(mq_adpt->mq, (const char *)item,
+                    mq_adpt->msgsize, prio);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to send message to mqueue error=%d\n",
+               ret);
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = mq_timedsend(mq_adpt->mq, (const char *)item,
+                         mq_adpt->msgsize, prio, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to timedsend message to mqueue error=%d\n",
+               ret);
+        }
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send
+ *
+ * Description:
+ *   Send message of low priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send(void *queue, void *item, uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_from_isr
+ *
+ * Description:
+ *   Send message of low priority to queue in ISR within
+ *   a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   hptw  - No mean
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_from_isr(void *queue, void *item, void *hptw)
+{
+  /* Force to set the value to be false */
+
+  *((int *)hptw) = false;
+
+  return esp_queue_send_generic(queue, item, 0, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_to_back
+ *
+ * Description:
+ *   Send message of low priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_to_back(void *queue, void *item,
+                                      uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_from_isr
+ *
+ * Description:
+ *   Send message of high priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_to_front(void *queue, void *item,
+                                       uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 1);
+}
+
+/****************************************************************************
+ * Name: esp_queue_recv
+ *
+ * Description:
+ *   Receive message from queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_recv(void *queue, void *item, uint32_t ticks)
+{
+  ssize_t ret;
+  struct timespec timeout;
+  unsigned int prio;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING)
+    {
+      ret = mq_receive(mq_adpt->mq, (char *)item,
+                       mq_adpt->msgsize, &prio);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to receive from mqueue error=%d\n", ret);
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = mq_timedreceive(mq_adpt->mq, (char *)item,
+                            mq_adpt->msgsize, &prio, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to timedreceive from mqueue error=%d\n",
+               ret);
+        }
+    }
+
+  return ret > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: esp_queue_msg_waiting
+ *
+ * Description:
+ *   Get message number in the message queue
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *
+ * Returned Value:
+ *   Message number
+ *
+ ****************************************************************************/
+
+static uint32_t esp_queue_msg_waiting(void *queue)
+{
+  int ret;
+  struct mq_attr attr;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  ret = mq_getattr(mq_adpt->mq, &attr);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to get attr from mqueue error=%d\n", ret);
+      return 0;
+    }
+
+  return attr.mq_curmsgs;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_create
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void *esp_event_group_create(void)
+{
+  DEBUGASSERT(0);
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_delete
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_event_group_delete(void *event)
+{
+  DEBUGASSERT(0);
+}
+
+/****************************************************************************
+ * Name: esp_event_group_set_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_set_bits(void *event, uint32_t bits)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_clear_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_clear_bits(void *event, uint32_t bits)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_wait_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_wait_bits(void *event,
+                                          uint32_t bits_to_wait_for,
+                                          int32_t clear_on_exit,
+                                          int32_t wait_for_all_bits,
+                                          uint32_t block_time_tick)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_task_create_pinned_to_core
+ *
+ * Description:
+ *   Create task and bind it to target CPU, the task will run when it
+ *   is created
+ *
+ * Input Parameters:
+ *   entry       - Task entry
+ *   name        - Task name
+ *   stack_depth - Task stack size
+ *   param       - Task private data
+ *   prio        - Task priority
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *   core_id     - CPU which the task runs in
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_create_pinned_to_core(void *entry,
+                                              const char *name,
+                                              uint32_t stack_depth,
+                                              void *param,
+                                              uint32_t prio,
+                                              void *task_handle,
+                                              uint32_t core_id)
+{
+  int pid;
+#ifdef CONFIG_SMP
+  int ret;
+  cpu_set_t cpuset;
+#endif
+
+  pid = kthread_create(name, prio, stack_depth, entry,
+                      (char * const *)param);
+  if (pid > 0)
+    {
+      *((int *)task_handle) = pid;
+
+#ifdef CONFIG_SMP
+      if (core_id < CONFIG_SMP_NCPUS)
+        {
+          CPU_ZERO(&cpuset);
+          CPU_SET(core_id, &cpuset);
+          ret = nxsched_set_affinity(pid, sizeof(cpuset), &cpuset);
+          if (ret)
+            {
+              wlerr("ERROR: Failed to set affinity error=%d\n", ret);
+              return false;
+            }
+        }
+#endif
+    }
+  else
+    {
+      wlerr("ERROR: Failed to create task\n");
+    }
+
+  return pid > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: esp_task_create
+ *
+ * Description:
+ *   Create task and the task will run when it is created
+ *
+ * Input Parameters:
+ *   entry       - Task entry
+ *   name        - Task name
+ *   stack_depth - Task stack size
+ *   param       - Task private data
+ *   prio        - Task priority
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_create(void *entry, const char *name,
+                               uint32_t stack_depth, void *param,
+                               uint32_t prio, void *task_handle)
+{
+  return esp_task_create_pinned_to_core(entry, name, stack_depth, param,
+                                        prio, task_handle, UINT32_MAX);
+}
+
+/****************************************************************************
+ * Name: esp_task_delete
+ *
+ * Description:
+ *   Delete the target task
+ *
+ * Input Parameters:
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_task_delete(void *task_handle)
+{
+  pid_t pid = (pid_t)((uintptr_t)task_handle);
+
+  kthread_delete(pid);
+}
+
+/****************************************************************************
+ * Name: esp_task_delay
+ *
+ * Description:
+ *   Current task wait for some ticks
+ *
+ * Input Parameters:
+ *   tick - Waiting ticks
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_task_delay(uint32_t tick)
+{
+  useconds_t us = TICK2USEC(tick);
+
+  usleep(us);
+}
+
+/****************************************************************************
+ * Name: esp_task_ms_to_tick
+ *
+ * Description:
+ *   Transform from millim seconds to system ticks
+ *
+ * Input Parameters:
+ *   ms - Millim seconds
+ *
+ * Returned Value:
+ *   System ticks
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_ms_to_tick(uint32_t ms)
+{
+  return MSEC2TICK(ms);
+}
+
+/****************************************************************************
+ * Name: esp_task_get_current_task
+ *
+ * Description:
+ *   Transform from millim seconds to system ticks
+ *
+ * Input Parameters:
+ *   ms - Millim seconds
+ *
+ * Returned Value:
+ *   System ticks
+ *
+ ****************************************************************************/
+
+static void *esp_task_get_current_task(void)
+{
+  pid_t pid = getpid();
+
+  return (void *)((uintptr_t)pid);
+}
+
+/****************************************************************************
+ * Name: esp_task_get_current_task
+ *
+ * Description:
+ *   Get OS task maxium priority
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Task maxium priority
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_get_max_priority(void)
+{
+  return SCHED_PRIORITY_MAX;
+}
+
+/****************************************************************************
+ * Name: esp_malloc_internal
+ *
+ * Description:
+ *   Allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_malloc(uint32_t size)
+{
+  return malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_event_id_map
+ *
+ * Description:
+ *   Transform from esp-idf event ID to WiFi adapter event ID
+ *
+ * Input Parameters:
+ *   event_id - esp-idf event ID
+ *
+ * Returned Value:
+ *   WiFi adapter event ID
+ *
+ ****************************************************************************/
+
+static int esp_event_id_map(int event_id)
+{
+  int id;
+
+  switch (event_id)
+    {
+      case WIFI_EVENT_STA_START:
+        id = WIFI_ADPT_EVT_STA_START;
+        break;
+      case WIFI_EVENT_STA_CONNECTED:
+        id = WIFI_ADPT_EVT_STA_CONNECT;
+        break;
+      case WIFI_EVENT_STA_DISCONNECTED:
+        id = WIFI_ADPT_EVT_STA_DISCONNECT;
+        break;
+      case WIFI_EVENT_STA_AUTHMODE_CHANGE:
+        id = WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE;
+        break;
+      case WIFI_EVENT_STA_STOP:
+        id = WIFI_ADPT_EVT_STA_STOP;
+        break;
+      default:
+        return -1;
+    }
+
+  return id;
+}
+
+/****************************************************************************
+ * Name: esp_evt_work_cb
+ *
+ * Description:
+ *   Process the cached event
+ *
+ * Input Parameters:
+ *   arg - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_evt_work_cb(FAR void *arg)
+{
+  int ret;
+  irqstate_t flags;
+  struct evt_adpt *evt_adpt;
+  struct wifi_notify *notify;
+
+  while (1)
+    {
+      flags = enter_critical_section();
+      evt_adpt = (struct evt_adpt *)sq_remfirst(&s_wifi_evt_queue);
+      leave_critical_section(flags);
+      if (!evt_adpt)
+        {
+          break;
+        }
+
+      switch (evt_adpt->id)
+        {
+          case WIFI_ADPT_EVT_STA_START:
+            ret = esp_wifi_connect();
+            if (ret)
+              {
+                wlerr("ERROR: Failed to connect\n");
+              }
+            break;
+          case WIFI_ADPT_EVT_STA_CONNECT:
+            s_connected = true;
+            ret = sem_post(&s_connect_sem);
+            if (ret)
+              {
+                wlerr("ERROR: Failed to post sem error=%d\n", errno);
+              }
+            break;
+          case WIFI_ADPT_EVT_STA_DISCONNECT:
+            s_connected = false;
+            ret = esp_wifi_connect();
+            if (ret)
+              {
+                wlerr("ERROR: Failed to connect\n");
+              }
+            break;
+          default:
+            break;
+        }
+
+      notify = &s_wifi_notify[evt_adpt->id];
+      if (notify->assigned)
+        {
+          notify->event.sigev_value.sival_ptr = evt_adpt->buf;
+
+          ret = nxsig_notification(notify->pid, &notify->event,
+                                   SI_QUEUE, &notify->work);
+          if (ret < 0)
+            {
+              wlwarn("ERROR: nxsig_notification event ID=%d failed: %d\n",
+                     evt_adpt->id, ret);
+            }
+        }
+
+      free(evt_adpt);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_event_post
+ *
+ * Description:
+ *   Active work queue and let the work to process the cached event
+ *
+ * Input Parameters:
+ *   event_base      - Event set name
+ *   event_id        - Event ID
+ *   event_data      - Event private data
+ *   event_data_size - Event data size
+ *   ticks           - Waiting system ticks
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int32_t esp_event_post(esp_event_base_t event_base,
+                       int32_t event_id,
+                       void *event_data,
+                       size_t event_data_size,
+                       uint32_t ticks)
+{
+  size_t size;
+  int32_t id;
+  irqstate_t flags;
+  struct evt_adpt *evt_adpt;
+
+  wlinfo("Event: base=%s id=%d data=%p data_size=%d ticks=%u\n", event_base,
+         event_id, event_data, event_data_size, ticks);
+
+  id = esp_event_id_map(event_id);
+  if (id < 0)
+    {
+      wlerr("ERROR: No process event %d\n", event_id);
+      return -1;
+    }
+
+  size = event_data_size + sizeof(struct evt_adpt);
+  evt_adpt = malloc(size);
+  if (!evt_adpt)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", size);
+      return -1;
+    }
+
+  evt_adpt->id = id;
+  memcpy(evt_adpt->buf, event_data, event_data_size);
+
+  flags = enter_critical_section();
+  sq_addlast(&evt_adpt->entry, &s_wifi_evt_queue);
+  leave_critical_section(flags);
+
+  work_queue(LPWORK, &s_wifi_evt_work, esp_evt_work_cb, NULL, 0);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_task_get_current_task
+ *
+ * Description:
+ *   Get free heap size by byte
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Free heap size
+ *
+ ****************************************************************************/
+
+uint32_t esp_get_free_heap_size(void)
+{
+  int ret;
+  struct mallinfo info;
+
+  ret = mm_mallinfo(&g_mmheap, &info);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to create task\n");
+      return 0;
+    }
+
+  return info.fordblks;
+}
+
+/****************************************************************************
+ * Name: esp_random
+ *
+ * Description:
+ *   Get a random data of type unsigned long
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Random data
+ *
+ ****************************************************************************/
+
+unsigned long esp_random(void)
+{
+  return (unsigned long)random();
+}
+
+/****************************************************************************
+ * Name: esp_dport_access_stall_other_cpu_start
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_dport_access_stall_other_cpu_start(void)
+{
+#ifdef CONFIG_SMP
+  DEBUGASSERT(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_dport_access_stall_other_cpu_end
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_dport_access_stall_other_cpu_end(void)
+{
+#ifdef CONFIG_SMP
+  DEBUGASSERT(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_phy_rf_init
+ *
+ * Description:
+ *   Initialize PHY hardware with given parameters
+ *
+ * Input Parameters:
+ *   init_data        - PHY hardware initialization parameters
+ *   mode             - PHY RF calculation mode
+ *   calibration_data - PHY RF calculation parameters
+ *   module           - PHY mode which is to be initialized
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int32_t esp_phy_rf_init(const esp_phy_init_data_t *init_data,
+                        esp_phy_calibration_mode_t mode,
+                        esp_phy_calibration_data_t *calibration_data,
+                        phy_rf_module_t module)
+{
+  irqstate_t flags;
+  int64_t time;
+  bool enable = false;
+
+  if (module >= PHY_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  flags = enter_critical_section();
+
+  s_esp32_phy_init_mask |= 1 << module;
+
+  if (s_esp23_phy_en)
+    {
+      leave_critical_section(flags);
+      return 0;
+    }
+
+  if (module == PHY_MODEM_MODULE)
+    {
+      if (s_esp32_phy_init_mask & PHY_RF_MASK)
+        {
+          enable = true;
+        }
+    }
+  else if (module == PHY_WIFI_MODULE || module == PHY_BT_MODULE)
+    {
+      enable = true;
+    }
+
+  if (enable)
+    {
+      if (s_esp32_phy_rf_stop_tm)
+        {
+          time = esp_timer_get_time() - s_esp32_phy_rf_stop_tm;
+          esp_wifi_internal_update_mac_time((uint32_t)time);
+          s_esp32_phy_rf_stop_tm = 0;
+        }
+
+      esp_phy_enable_clock();
+
+      phy_set_wifi_mode_only(0);
+
+      register_chipv7_phy(init_data, calibration_data, mode);
+
+      s_esp23_phy_en = true;
+    }
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_phy_deinit_rf
+ *
+ * Description:
+ *   Deinitialize PHY hardware
+ *
+ * Input Parameters:
+ *   module - PHY mode which is to be deinitialized
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_phy_deinit_rf(uint32_t module)
+{
+  irqstate_t flags;
+  bool disable = false;
+
+  if (module >= PHY_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  flags = enter_critical_section();
+
+  s_esp32_phy_init_mask |= ~(1 << module);
+
+  if (!s_esp23_phy_en)
+    {
+      leave_critical_section(flags);
+      return 0;
+    }
+
+  if (module == PHY_MODEM_MODULE)
+    {
+      disable = true;
+    }
+  else if (module == PHY_WIFI_MODULE || module == PHY_BT_MODULE)
+    {
+      if (!(s_esp32_phy_init_mask & PHY_RF_MASK))
+        {
+          disable = true;
+        }
+    }
+
+  if (disable)
+    {
+      phy_close_rf();
+
+      s_esp32_phy_rf_stop_tm = esp_timer_get_time();
+
+      esp_phy_disable_clock();
+
+      s_esp23_phy_en = false;
+    }
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_phy_init
+ *
+ * Description:
+ *   Initialize PHY hardware
+ *
+ * Input Parameters:
+ *   module - PHY mode which is to be initialized
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_phy_init(uint32_t module)
+{
+  int ret;
+  esp_phy_calibration_data_t *cal_data;
+
+  cal_data = kmm_zalloc(sizeof(esp_phy_calibration_data_t));
+  if (!cal_data)
+    {
+      wlerr("ERROR: Failed to malloc");
+      DEBUGASSERT(0);
+    }
+
+  ret = esp_phy_rf_init(&phy_init_data, PHY_RF_CAL_FULL, cal_data, module);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize RF");
+      DEBUGASSERT(0);
+    }
+
+  kmm_free(cal_data);
+}
+
+/****************************************************************************
+ * Name: esp_phy_enable_clock
+ *
+ * Description:
+ *   Enable PHY hardware clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_phy_enable_clock(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  if (s_phy_clk_en_cnt == 0)
+    {
+      modifyreg32(DPORT_WIFI_CLK_EN_REG, 0,
+                  DPORT_WIFI_CLK_WIFI_BT_COMMON_M);
+    }
+
+  s_phy_clk_en_cnt++;
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: esp_phy_disable_clock
+ *
+ * Description:
+ *   Disable PHY hardware clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_phy_disable_clock(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  if (s_phy_clk_en_cnt)
+    {
+      s_phy_clk_en_cnt--;
+      if (!s_phy_clk_en_cnt)
+        {
+          modifyreg32(DPORT_WIFI_CLK_EN_REG,
+                      DPORT_WIFI_CLK_WIFI_BT_COMMON_M,
+                      0);
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: esp_read_mac
+ *
+ * Description:
+ *   Read MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *   type - MAC address type
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int32_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
+{
+  uint32_t regval[2];
+  uint8_t tmp;
+  uint8_t *data = (uint8_t *)regval;
+  uint8_t crc;
+  int i;
+
+  if (type > ESP_MAC_WIFI_SOFTAP)
+    {
+      wlerr("ERROR: Input type is error=%d\n", type);
+      return -1;
+    }
+
+  regval[0] = getreg32(MAC_ADDR0_REG);
+  regval[1] = getreg32(MAC_ADDR1_REG);
+
+  crc = data[6];
+  for (i = 0; i < 6; i++)
+    {
+      mac[i] = data[5 - i];
+    }
+
+  if (crc != esp_crc8(mac, 6))
+    {
+      wlerr("ERROR: Failed to check MAC address CRC\n");
+      return -1;
+    }
+
+  if (type == ESP_MAC_WIFI_SOFTAP)
+    {
+      tmp = mac[0];
+      for (i = 0; i < 64; i++)
+        {
+          mac[0] = tmp | 0x02;
+          mac[0] ^= i << 2;
+
+          if (mac[0] != tmp)
+            {
+              break;
+            }
+        }
+
+      if (i >= 64)
+        {
+          wlerr("ERROR: Failed to generate softAP MAC\n");
+          return -1;
+        }
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_read_mac
+ *
+ * Description:
+ *   Read MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *   type - MAC address type
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_wifi_read_mac(uint8_t *mac, uint32_t type)
+{
+  return esp_read_mac(mac, type);
+}
+
+/****************************************************************************
+ * Name: esp_timer_arm
+ *
+ * Description:
+ *   Set timer timeout period and repeat flag
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *   ms     - millim seconds
+ *   repeat - true: run cycle, false: run once
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_arm(void *ptimer, uint32_t ms, bool repeat)
+{
+  esp_timer_arm_us(ptimer, ms * 1000, repeat);
+}
+
+/****************************************************************************
+ * Name: esp_timer_disarm
+ *
+ * Description:
+ *   Disable timer
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_disarm(void *ptimer)
+{
+  struct timer_adpt *timer_adpt;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+
+  if (ets_timer->priv)
+    {
+      timer_adpt = (struct timer_adpt *)ets_timer->priv;
+
+      wd_cancel(&timer_adpt->wdog);
+      work_cancel(LPWORK, &timer_adpt->work);
+    }
+}
+
+/****************************************************************************
+ * Name: esp32_timer_done
+ *
+ * Description:
+ *   Disable and free timer
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32_timer_done(void *ptimer)
+{
+  struct timer_adpt *timer_adpt;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+
+  if (ets_timer->priv)
+    {
+      timer_adpt = (struct timer_adpt *)ets_timer->priv;
+
+      wd_cancel(&timer_adpt->wdog);
+      work_cancel(LPWORK, &timer_adpt->work);
+
+      kmm_free(timer_adpt);
+
+      ets_timer->priv = NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_timer_setfn
+ *
+ * Description:
+ *   Set timer callback function and private data
+ *
+ * Input Parameters:
+ *   ptimer    - Timer data pointer
+ *   pfunction - Callback function
+ *   parg      - Callback function private data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_setfn(void *ptimer, void *pfunction, void *parg)
+{
+  struct timer_adpt *timer_adpt;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+
+  if (ets_timer->priv)
+    {
+      return ;
+    }
+
+  timer_adpt = kmm_zalloc(sizeof(struct timer_adpt));
+  if (!timer_adpt)
+    {
+      wlerr("ERROR: Failed to malloc\n");
+      return ;
+    }
+
+  timer_adpt->func = pfunction;
+  timer_adpt->priv = parg;
+
+  ets_timer->priv = timer_adpt;
+}
+
+/****************************************************************************
+ * Name: esp_timer_work_cb
+ *
+ * Description:
+ *   Process timer callback function in workqueue and active
+ *   it if it has repeat flag
+ *
+ * Input Parameters:
+ *   arg - Timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_work_cb(FAR void *arg)
+{
+  struct ets_timer *ets_timer = (struct ets_timer *)arg;
+  struct timer_adpt *timer_adpt =
+            (struct timer_adpt *)ets_timer->priv;
+
+  timer_adpt->func(timer_adpt->priv);
+  if (timer_adpt->repeat)
+    {
+      wd_start(&timer_adpt->wdog, timer_adpt->delay,
+               esp_timer_cb, (wdparm_t)ets_timer);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_timer_cb
+ *
+ * Description:
+ *   Post event to work queue and let work queue to process the timer's
+ *   real callback function
+ *
+ * Input Parameters:
+ *   parm - Timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_cb(wdparm_t parm)
+{
+  struct ets_timer *ets_timer = (struct ets_timer *)parm;
+  struct timer_adpt *timer_adpt =
+            (struct timer_adpt *)ets_timer->priv;
+
+  work_queue(LPWORK, &timer_adpt->work,
+             esp_timer_work_cb, ets_timer, 0);
+}
+
+/****************************************************************************
+ * Name: esp_timer_arm_us
+ *
+ * Description:
+ *   Set timer timeout period and repeat flag
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *   us     - micro seconds
+ *   repeat - true: run cycle, false: run once
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_timer_arm_us(void *ptimer, uint32_t us, bool repeat)
+{
+  uint32_t delay;
+  struct timer_adpt *timer_adpt;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+
+  if (ets_timer->priv)
+    {
+      timer_adpt = (struct timer_adpt *)ets_timer->priv;
+
+      wd_cancel(&timer_adpt->wdog);
+      work_cancel(LPWORK, &timer_adpt->work);
+
+      delay = USEC2TICK(us);
+      timer_adpt->repeat = (uint32_t)repeat;
+      timer_adpt->delay = delay;
+
+      wd_start(&timer_adpt->wdog, delay,
+               esp_timer_cb, (wdparm_t)ets_timer);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_periph_module_enable
+ *
+ * Description:
+ *   Enable WiFi module clock
+ *
+ * Input Parameters:
+ *   periph - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_periph_module_enable(uint32_t periph)
+{
+  modifyreg32(DPORT_WIFI_CLK_EN_REG, 0, DPORT_WIFI_CLK_WIFI_EN_M);
+}
+
+/****************************************************************************
+ * Name: esp_periph_module_enable
+ *
+ * Description:
+ *   Disable WiFi module clock
+ *
+ * Input Parameters:
+ *   periph - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_periph_module_disable(uint32_t periph)
+{
+  modifyreg32(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN_M, 0);
+}
+
+/****************************************************************************
+ * Name: esp_timer_get_time
+ *
+ * Description:
+ *   Get system time of type int64_t
+ *
+ * Input Parameters:
+ *   periph - No mean
+ *
+ * Returned Value:
+ *   System time
+ *
+ ****************************************************************************/
+
+int64_t esp_timer_get_time(void)
+{
+  int64_t us;
+  struct timeval tv;
+  int ret;
+
+  ret = gettimeofday(&tv, NULL);
+  if (!ret)
+    {
+      us = tv.tv_sec * (1000 * 1000) + tv.tv_usec;
+    }
+  else
+    {
+      us = 0;
+      wlerr("ERROR: Failed to get time of day\n");
+    }
+
+  return us;
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_i8
+ *
+ * Description:
+ *   Save data of type int8_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_set_i8(uint32_t handle,
+                              const char *key,
+                              int8_t value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(int8_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_i8
+ *
+ * Description:
+ *   Read data of type int8_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_get_i8(uint32_t handle,
+                              const char *key,
+                              int8_t *out_value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  size_t len = sizeof(int8_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_u8
+ *
+ * Description:
+ *   Save data of type uint8_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_set_u8(uint32_t handle,
+                              const char *key,
+                              uint8_t value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(uint8_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_u8
+ *
+ * Description:
+ *   Read data of type uint8_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_get_u8(uint32_t handle,
+                              const char *key,
+                              uint8_t *out_value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  size_t len = sizeof(uint8_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_u16
+ *
+ * Description:
+ *   Save data of type uint16_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_set_u16(uint32_t handle,
+                               const char *key,
+                               uint16_t value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(uint16_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_u16
+ *
+ * Description:
+ *   Read data of type uint16_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_get_u16(uint32_t handle,
+                               const char *key,
+                               uint16_t *out_value)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  size_t len = sizeof(uint16_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_open
+ *
+ * Description:
+ *   Create a file system storage data object
+ *
+ * Input Parameters:
+ *   name       - Storage index
+ *   open_mode  - Storage mode
+ *   out_handle - Storage handle
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_open(const char *name,
+                            uint32_t open_mode,
+                            uint32_t *out_handle)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  int ret;
+  struct nvs_adpt *nvs_adpt;
+  int tmp;
+  char *index_name;
+
+  tmp = sizeof(struct nvs_adpt);
+  nvs_adpt = kmm_malloc(tmp);
+  if (!nvs_adpt)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return -1;
+    }
+
+  ret = asprintf(&index_name, "%s", name);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS index_name string\n");
+      kmm_free(nvs_adpt);
+      return -1;
+    }
+
+  nvs_adpt->index_name = index_name;
+  *out_handle = (uint32_t)nvs_adpt;
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_close
+ *
+ * Description:
+ *   Close storage data object and free resource
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static void esp_nvs_close(uint32_t handle)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+
+  kmm_free(nvs_adpt->index_name);
+  kmm_free(nvs_adpt);
+#else
+  DEBUGASSERT(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_commit
+ *
+ * Description:
+ *   This function has no practical effect
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_commit(uint32_t handle)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_blob
+ *
+ * Description:
+ *   Save a block of data into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored buffer pointer
+ *   length - Buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_set_blob(uint32_t handle,
+                                const char *key,
+                                const void *value,
+                                size_t length)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  int fd;
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  ret = unlink(dir);
+  if (ret)
+    {
+      if (errno != ENOENT)
+        {
+          wlerr("ERROR: Failed to unlink %s error=%d\n", dir, errno);
+          free(dir);
+          return -1;
+        }
+    }
+
+  fd = open(dir, O_WRONLY | O_CREAT, NVS_FILE_MODE);
+  if (fd < 0)
+    {
+      wlerr("ERROR: Failed to set open %s\n", dir);
+      free(dir);
+      return -1;
+    }
+
+  ret = write(fd, value, length);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to write to %s\n", dir);
+      free(dir);
+      close(fd);
+      return -1;
+    }
+
+  free(dir);
+  close(fd);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_blob
+ *
+ * Description:
+ *   Read a block of data from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *   length    - Buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_get_blob(uint32_t handle,
+                                const char *key,
+                                void *out_value,
+                                size_t *length)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  int fd;
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  fd = open(dir, O_RDONLY, NVS_FILE_MODE);
+  if (fd < 0)
+    {
+      free(dir);
+      if (errno == ENOENT)
+        {
+          wlinfo("INFO: No file %s\n", dir);
+          return ESP_ERR_NVS_NOT_FOUND;
+        }
+      wlerr("ERROR: Failed to get open %s\n", dir);
+      return -1;
+    }
+
+  ret = read(fd, out_value, *length);
+  if (ret <= 0)
+    {
+      wlerr("ERROR: Failed to write to %s\n", dir);
+      free(dir);
+      close(fd);
+      return -1;
+    }
+  else
+    {
+      *length = ret;
+    }
+
+  free(dir);
+  close(fd);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_erase_key
+ *
+ * Description:
+ *   Read a block of data from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_nvs_erase_key(uint32_t handle, const char *key)
+{
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  ret = unlink(dir);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to delete NVS file %s\n", dir);
+      free(dir);
+      return -1;
+    }
+
+  free(dir);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_fill_random
+ *
+ * Description:
+ *   Fill random data int given buffer of given length
+ *
+ * Input Parameters:
+ *   buf - buffer pointer
+ *   len - buffer length
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+void esp_fill_random(void *buf, size_t len)
+{
+  uint8_t *p = (uint8_t *)buf;
+  uint32_t tmp;
+  uint32_t n;
+
+  while (len > 0)
+    {
+      tmp = random();
+      n = len < 4 ? len : 4;
+
+      memcpy(p, &tmp, n);
+
+      p += n;
+      len -= n;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_get_random
+ *
+ * Description:
+ *   Fill random data int given buffer of given length
+ *
+ * Input Parameters:
+ *   buf - buffer pointer
+ *   len - buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_get_random(uint8_t *buf, size_t len)
+{
+  esp_fill_random(buf, len);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_get_time
+ *
+ * Description:
+ *   Get std C time
+ *
+ * Input Parameters:
+ *   t - buffer to store time of type timeval
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_get_time(void *t)
+{
+  int ret;
+  struct timeval tv;
+  struct time_adpt *time_adpt = (struct time_adpt *)t;
+
+  ret = gettimeofday(&tv, NULL);
+  if (!ret)
+    {
+      time_adpt->sec  = (time_t)tv.tv_sec;
+      time_adpt->usec = (suseconds_t)tv.tv_usec;
+    }
+  else
+    {
+      wlerr("ERROR: Failed to get time of day\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_rand
+ *
+ * Description:
+ *   Get random data of type uint32_t
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Random data
+ *
+ ****************************************************************************/
+
+static uint32_t esp_rand(void)
+{
+  return esp_random();
+}
+
+/****************************************************************************
+ * Name: esp_log_writev
+ *
+ * Description:
+ *   Output log with by format string and its arguments
+ *
+ * Input Parameters:
+ *   level  - log level, no mean here
+ *   tag    - log TAG, no mean here
+ *   format - format string
+ *   args   - arguments list
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_log_writev(uint32_t level, const char *tag,
+                           const char *format, va_list args)
+{
+  int pri;
+
+  switch (level)
+    {
+      case ESP_LOG_ERROR:
+        pri = LOG_ERR;
+        break;
+      case ESP_LOG_WARN:
+        pri = LOG_WARNING;
+        break;
+      case ESP_LOG_INFO:
+        pri = LOG_INFO;
+        break;
+      default:
+        pri = LOG_DEBUG;
+        break;
+    }
+
+  vsyslog(pri, format, args);
+}
+
+/****************************************************************************
+ * Name: esp_log_write
+ *
+ * Description:
+ *   Output log with by format string and its arguments
+ *
+ * Input Parameters:
+ *   level  - log level, no mean here
+ *   tag    - log TAG, no mean here
+ *   format - format string
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_log_write(uint32_t level,
+                   const char *tag,
+                   const char *format, ...)
+{
+    va_list list;
+    va_start(list, format);
+    esp_log_writev(level, tag, format, list);
+    va_end(list);
+}
+
+/****************************************************************************
+ * Name: esp_log_timestamp
+ *
+ * Description:
+ *   Get system time by millim second
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   System time
+ *
+ ****************************************************************************/
+
+uint32_t esp_log_timestamp(void)
+{
+  return (uint32_t)(esp_timer_get_time() / 1000);
+}
+
+/****************************************************************************
+ * Name: esp_malloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_malloc_internal(size_t size)
+{
+  return kmm_malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_realloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory by old memory block
+ *
+ * Input Parameters:
+ *   ptr  - old memory pointer
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_realloc_internal(void *ptr, size_t size)
+{
+  return kmm_realloc(ptr, size);
+}
+
+/****************************************************************************
+ * Name: esp_calloc_internal
+ *
+ * Description:
+ *   Drivers allocate some continuous blocks of memory
+ *
+ * Input Parameters:
+ *   n    - memory block number
+ *   size - memory block size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_calloc_internal(size_t n, size_t size)
+{
+  return kmm_calloc(n, size);
+}
+
+/****************************************************************************
+ * Name: esp_zalloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory and clear it with 0
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_zalloc_internal(size_t size)
+{
+  return kmm_zalloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_malloc_internal
+ *
+ * Description:
+ *   Applications allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_malloc(size_t size)
+{
+  return malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_realloc_internal
+ *
+ * Description:
+ *   Applications allocate a block of memory by old memory block
+ *
+ * Input Parameters:
+ *   ptr  - old memory pointer
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_realloc(void *ptr, size_t size)
+{
+  return realloc(ptr, size);
+}
+
+/****************************************************************************
+ * Name: esp_calloc_internal
+ *
+ * Description:
+ *   Applications allocate some continuous blocks of memory
+ *
+ * Input Parameters:
+ *   n    - memory block number
+ *   size - memory block size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_calloc(size_t n, size_t size)
+{
+  return calloc(n, size);
+}
+
+/****************************************************************************
+ * Name: esp_zalloc_internal
+ *
+ * Description:
+ *   Applications allocate a block of memory and clear it with 0
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_zalloc(size_t size)
+{
+  return zalloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_create_queue
+ *
+ * Description:
+ *   Create WiFi static message queue
+ *
+ * Input Parameters:
+ *   queue_len - queue message number
+ *   item_size - message size
+ *
+ * Returned Value:
+ *   WiFi static message queue data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_create_queue(int32_t queue_len, int32_t item_size)
+{
+  wifi_static_queue_t *wifi_queue;
+
+  wifi_queue = kmm_malloc(sizeof(wifi_static_queue_t));
+  if (!wifi_queue)
+    {
+      wlerr("ERROR: Failed to malloc\n");
+      return NULL;
+    }
+
+  wifi_queue->handle = esp_queue_create(queue_len, item_size);
+  if (!wifi_queue->handle)
+    {
+      wlerr("ERROR: Failed to create queue\n");
+      kmm_free(wifi_queue);
+      return NULL;
+    }
+
+  return wifi_queue;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_delete_queue
+ *
+ * Description:
+ *   Delete WiFi static message queue
+ *
+ * Input Parameters:
+ *   queue - WiFi static message queue data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_wifi_delete_queue(void *queue)
+{
+  wifi_static_queue_t *wifi_queue = (wifi_static_queue_t *)queue;
+
+  esp_queue_delete(wifi_queue->handle);
+  kmm_free(wifi_queue);
+}
+
+/****************************************************************************
+ * Name: esp_modem_enter_sleep
+ *
+ * Description:
+ *   Let given module to enter sleep mode
+ *
+ * Input Parameters:
+ *   module - hardware module ID
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_modem_enter_sleep(uint32_t module)
+{
+  int ret = 0;
+  irqstate_t flags;
+  uint32_t bit;
+
+  if (module >= (uint32_t)MODEM_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  bit = 1 << module;
+
+  if (!(s_esp32_module_mask & bit))
+    {
+      return -1;
+    }
+
+  flags = enter_critical_section();
+
+  s_esp32_module_sleep |= bit;
+  if (!s_esp32_sleep && (s_esp32_module_sleep == s_esp32_module_mask))
+    {
+      ret = esp_phy_deinit_rf(PHY_MODEM_MODULE);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to close RF\n");
+        }
+      else
+        {
+          s_esp32_sleep = true;
+        }
+    }
+
+  leave_critical_section(flags);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_modem_enter_sleep
+ *
+ * Description:
+ *   Let given module to exit from sleep mode
+ *
+ * Input Parameters:
+ *   module - hardware module ID
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_modem_exit_sleep(uint32_t module)
+{
+  int ret = 0;
+  irqstate_t flags;
+  uint32_t bit;
+
+  if (module >= (uint32_t)MODEM_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  bit = 1 << module;
+
+  if (!(s_esp32_module_mask & bit))
+    {
+      return -1;
+    }
+
+  flags = enter_critical_section();
+
+  s_esp32_module_sleep &= ~bit;
+  if (s_esp32_sleep)
+    {
+      ret = esp_phy_rf_init(NULL, PHY_RF_CAL_NONE,
+                            NULL, PHY_MODEM_MODULE);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to open RF\n");
+        }
+      else
+        {
+          s_esp32_sleep = false;
+        }
+    }
+
+  leave_critical_section(flags);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_modem_register_sleep
+ *
+ * Description:
+ *   Regitser given module so that it can enter sleep mode
+ *
+ * Input Parameters:
+ *   module - hardware module ID
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_modem_register_sleep(uint32_t module)
+{
+  irqstate_t flags;
+  uint32_t bit;
+
+  if (module >= (uint32_t)MODEM_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  bit = 1 << module;
+
+  flags = enter_critical_section();
+
+  if (s_esp32_module_mask & bit)
+    {
+      /* Has registered and return success */
+
+      return 0;
+    }
+
+  s_esp32_module_mask |= bit;
+  s_esp32_module_sleep |= bit;
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_modem_deregister_sleep
+ *
+ * Description:
+ *   Deregitser given module so that it can't enter sleep mode
+ *
+ * Input Parameters:
+ *   module - hardware module ID
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_modem_deregister_sleep(uint32_t module)
+{
+  int ret;
+  irqstate_t flags;
+  uint32_t bit;
+
+  if (module >= (uint32_t)MODEM_MODULE_COUNT)
+    {
+      return -1;
+    }
+
+  bit = 1 << module;
+
+  flags = enter_critical_section();
+
+  if (!(s_esp32_module_mask & bit))
+    {
+      /* Has deregistered and return success */
+
+      return 0;
+    }
+
+  s_esp32_module_mask &= ~bit;
+  s_esp32_module_sleep &= ~bit;
+  if (!s_esp32_module_mask)
+    {
+      s_esp32_module_mask = 0;
+      if (s_esp32_sleep)
+        {
+          s_esp32_sleep = false;
+          ret = esp_phy_rf_init(NULL, PHY_RF_CAL_NONE,
+                                NULL, PHY_MODEM_MODULE);
+          if (ret)
+            {
+              wlerr("ERROR: Failed to open RF\n");
+            }
+        }
+    }
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_coex_status_get
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_coex_status_get(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_coex_condition_set
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_coex_condition_set(uint32_t type, bool dissatisfy)
+{
+}
+
+/****************************************************************************
+ * Name: esp_coex_wifi_request
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int32_t esp_coex_wifi_request(uint32_t event, uint32_t latency,
+                                     uint32_t duration)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_coex_wifi_release
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int32_t esp_coex_wifi_release(uint32_t event)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Functions needed by libphy.a
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_dport_access_reg_read
+ *
+ * Description:
+ *   Read regitser value safely in SMP
+ *
+ * Input Parameters:
+ *   reg - Regitser address
+ *
+ * Returned Value:
+ *   Regitser value
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
+{
+#ifdef CONFIG_SMP
+  DEBUGASSERT(0);
+#else
+  return getreg32(reg);
+#endif
+}
+
+/****************************************************************************
+ * Name: phy_enter_critical
+ *
+ * Description:
+ *   Enter critical state
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   CPU PS value
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR phy_enter_critical(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: phy_exit_critical
+ *
+ * Description:
+ *   Exit from critical state
+ *
+ * Input Parameters:
+ *   level - CPU PS value
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR phy_exit_critical(uint32_t level)
+{
+  leave_critical_section(level);
+}
+
+/****************************************************************************
+ * Name: phy_printf
+ *
+ * Description:
+ *   Output format string and its arguments
+ *
+ * Input Parameters:
+ *   format - format string
+ *
+ * Returned Value:
+ *   0
+ *
+ ****************************************************************************/
+
+int phy_printf(const char *format, ...)
+{
+  va_list arg;
+
+  va_start(arg, format);
+  vsyslog(LOG_INFO, format, arg);
+  va_end(arg);
+
+  return 0;
+}

Review comment:
       why not use wlinfo?

##########
File path: arch/xtensa/src/esp32/esp32_wifi_adapter.c
##########
@@ -0,0 +1,4443 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_wifi_adapter.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <mqueue.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <clock/clock.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "nuttx/kmalloc.h"
+#include "nuttx/spinlock.h"
+#include <nuttx/irq.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
+
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_emac.h"
+#include "esp32_cpuint.h"
+#include "esp32_wifi_adapter.h"
+
+#include "espidf_wifi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PHY_RF_MASK   ((1 << PHY_BT_MODULE) | (1 << PHY_WIFI_MODULE))
+
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+#  define NVS_FS_PREFIX CONFIG_ESP32_WIFI_FS_MOUNTPT
+#  define NVS_DIR_BASE  NVS_FS_PREFIX"/wifi."
+#  define NVS_FILE_MODE 0777
+#endif
+
+#define WIFI_CONNECT_TIMEOUT  (10)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* WiFi interrupt adapter private data */
+
+struct irq_adpt
+{
+  void (*func)(void *arg);  /* Interrupt callback function */
+  void *arg;                /* Interrupt private data */
+};
+
+/* WiFi message queue private data */
+
+struct mq_adpt
+{
+  mqd_t    mq;              /* Message queue handle */
+  uint32_t msgsize;         /* Message size */
+  char     name[16];        /* Message queue name */
+};
+
+/* WiFi time private data */
+
+struct time_adpt
+{
+  time_t      sec;          /* Second value */
+  suseconds_t usec;         /* Micro second value */
+};
+
+/* WiFi timer private data */
+
+struct timer_adpt
+{
+  struct wdog_s wdog;       /* Timer handle */
+  struct work_s work;       /* Work priavte data */

Review comment:
       ```suggestion
     struct work_s work;       /* Work private data */
   ```

##########
File path: arch/xtensa/src/esp32/esp32_wifi_adapter.c
##########
@@ -0,0 +1,4443 @@
+/****************************************************************************
+ * arch/xtensa/src/esp32/esp32_wifi_adapter.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <mqueue.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <clock/clock.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "nuttx/kmalloc.h"
+#include "nuttx/spinlock.h"
+#include <nuttx/irq.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
+
+#include "xtensa.h"
+#include "xtensa_attr.h"
+#include "hardware/esp32_dport.h"
+#include "hardware/esp32_emac.h"
+#include "esp32_cpuint.h"
+#include "esp32_wifi_adapter.h"
+
+#include "espidf_wifi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define PHY_RF_MASK   ((1 << PHY_BT_MODULE) | (1 << PHY_WIFI_MODULE))
+
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+#  define NVS_FS_PREFIX CONFIG_ESP32_WIFI_FS_MOUNTPT
+#  define NVS_DIR_BASE  NVS_FS_PREFIX"/wifi."
+#  define NVS_FILE_MODE 0777
+#endif
+
+#define WIFI_CONNECT_TIMEOUT  (10)

Review comment:
       make this configurable?




----------------------------------------------------------------
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.

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