You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/12/04 12:39:21 UTC

[incubator-nuttx] branch master updated: xtensa/esp32: Refactor ESP32 Wi-Fi driver

This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 3bb9a42  xtensa/esp32: Refactor ESP32 Wi-Fi driver
3bb9a42 is described below

commit 3bb9a42c6b9d8cd09fb6cb7f014df0ccfbd5197b
Author: Dong Heng <do...@espressif.com>
AuthorDate: Thu Nov 12 15:55:38 2020 +0800

    xtensa/esp32: Refactor ESP32 Wi-Fi driver
---
 arch/xtensa/src/esp32/Kconfig                      |   28 +
 arch/xtensa/src/esp32/Make.defs                    |    2 +-
 arch/xtensa/src/esp32/esp32_rt_timer.c             |   24 +
 arch/xtensa/src/esp32/esp32_rt_timer.h             |   16 +
 arch/xtensa/src/esp32/esp32_wifi_adapter.c         | 1041 +++++++++++-------
 arch/xtensa/src/esp32/esp32_wifi_adapter.h         |   19 +
 arch/xtensa/src/esp32/esp32_wlan.c                 | 1104 +++++++++++---------
 arch/xtensa/src/esp32/esp32_wlan.h                 |    8 +-
 arch/xtensa/src/esp32/hardware/esp32_dport.h       |    1 +
 boards/xtensa/esp32/esp32-core/src/esp32_bringup.c |    2 +-
 10 files changed, 1326 insertions(+), 919 deletions(-)

diff --git a/arch/xtensa/src/esp32/Kconfig b/arch/xtensa/src/esp32/Kconfig
index 2cc2f39..7b8b849 100644
--- a/arch/xtensa/src/esp32/Kconfig
+++ b/arch/xtensa/src/esp32/Kconfig
@@ -661,6 +661,34 @@ endmenu # ESP32_EMAC
 menu "WiFi configuration"
 	depends on ESP32_WIRELESS
 
+config ESP32_WIFI_STATIC_RXBUF_NUM
+    int "WiFi static RX buffer number"
+	default 10
+
+config ESP32_WIFI_DYNAMIC_RXBUF_NUM
+    int "WiFi dynamic RX buffer number"
+	default 32
+
+config ESP32_WIFI_DYNAMIC_TXBUF_NUM
+    int "WiFi dynamic TX buffer number"
+	default 32
+
+config ESP32_WIFI_TX_AMPDU
+	bool "WiFi TX AMPDU"
+	default y
+
+config ESP32_WIFI_RX_AMPDU
+	bool "WiFi RX AMPDU"
+	default y
+
+config ESP32_WIFI_RXBA_AMPDU_WZ
+    int "WiFi RX BA AMPDU windown size"
+	default 6
+
+config ESP32_WLAN_RXBUF_NUM
+	int "WLAN netcard RX buffer number"
+	default 16
+
 config ESP32_WIFI_CONNECT_TIMEOUT
 	int "Connect timeout by second"
 	default 10
diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs
index c53ce20..b986485 100644
--- a/arch/xtensa/src/esp32/Make.defs
+++ b/arch/xtensa/src/esp32/Make.defs
@@ -180,7 +180,7 @@ endif
 
 ifeq ($(CONFIG_ESP32_WIRELESS),y)
 WIRELESS_DRV_UNPACK  = esp-wireless-drivers-3rdparty
-WIRELESS_DRV_ID      = 5cb6561
+WIRELESS_DRV_ID      = 4a352be
 WIRELESS_DRV_ZIP     = $(WIRELESS_DRV_ID).zip
 WIRELESS_DRV_URL     = https://github.com/espressif/esp-wireless-drivers-3rdparty/archive
 
diff --git a/arch/xtensa/src/esp32/esp32_rt_timer.c b/arch/xtensa/src/esp32/esp32_rt_timer.c
index da36d5a..51a476b 100644
--- a/arch/xtensa/src/esp32/esp32_rt_timer.c
+++ b/arch/xtensa/src/esp32/esp32_rt_timer.c
@@ -554,6 +554,30 @@ void rt_timer_delete(FAR struct rt_timer_s *timer)
 }
 
 /****************************************************************************
+ * Name: rt_timer_time_us
+ *
+ * Description:
+ *   Get time of RT timer by micro second.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Time of RT timer by micro second.
+ *
+ ****************************************************************************/
+
+uint64_t rt_timer_time_us(void)
+{
+  uint64_t counter;
+  struct esp32_tim_dev_s *tim = s_esp32_tim_dev;
+
+  ESP32_TIM_GETCTR(tim, &counter);
+
+  return counter;
+}
+
+/****************************************************************************
  * Name: esp32_rt_timer_init
  *
  * Description:
diff --git a/arch/xtensa/src/esp32/esp32_rt_timer.h b/arch/xtensa/src/esp32/esp32_rt_timer.h
index 3b9a222..b540b9e 100644
--- a/arch/xtensa/src/esp32/esp32_rt_timer.h
+++ b/arch/xtensa/src/esp32/esp32_rt_timer.h
@@ -151,6 +151,22 @@ void rt_timer_stop(FAR struct rt_timer_s *timer);
 void rt_timer_delete(FAR struct rt_timer_s *timer);
 
 /****************************************************************************
+ * Name: rt_timer_time_us
+ *
+ * Description:
+ *   Get time of RT timer by micro second.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Time of RT timer by micro second.
+ *
+ ****************************************************************************/
+
+uint64_t rt_timer_time_us(void);
+
+/****************************************************************************
  * Name: esp32_rt_timer_init
  *
  * Description:
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.c b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
index a0e7bfd..4aeeefc 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.c
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.c
@@ -145,14 +145,19 @@ struct nvs_adpt
  * Private Function Prototypes
  ****************************************************************************/
 
+static bool wifi_env_is_chip(void);
+static void wifi_set_intr(int32_t cpu_no, uint32_t intr_source,
+                          uint32_t intr_num, int32_t intr_prio);
+static void wifi_clear_intr(uint32_t intr_source, uint32_t intr_num);
 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 bool wifi_is_from_isr(void);
 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_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);
@@ -203,18 +208,24 @@ 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 wifi_apb80m_request(void);
+static void wifi_apb80m_release(void);
+static void wifi_phy_disable(void);
+static void wifi_phy_enable(void);
 static void esp_phy_enable_clock(void);
 static void esp_phy_disable_clock(void);
+static int32_t wifi_phy_update_country_info(const char *country);
 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_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 void wifi_reset_mac(void);
+static void wifi_clock_enable(void);
+static void wifi_clock_disable(void);
+static void wifi_rtc_enable_iso(void);
+static void wifi_rtc_disable_iso(void);
 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,
@@ -248,18 +259,32 @@ 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 int wifi_coex_init(void);
+static void wifi_coex_deinit(void);
+static int wifi_coex_enable(void);
+static void wifi_coex_disable(void);
 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);
 static unsigned long esp_random_ulong(void);
+static int wifi_coex_wifi_set_channel(uint8_t primary, uint8_t secondary);
+static int wifi_coex_get_event_duration(uint32_t event,
+                                        uint32_t *duration);
+static int wifi_coex_get_pti(uint32_t event, uint8_t *pti);
+static void wifi_coex_clear_schm_status_bit(uint32_t type,
+                                            uint32_t status);
+static void wifi_coex_set_schm_status_bit(uint32_t type,
+                                          uint32_t status);
+static int wifi_coex_set_schm_interval(uint32_t interval);
+static uint32_t wifi_coex_get_schm_interval(void);
+static uint8_t wifi_coex_get_schm_curr_period(void);
+static void *wifi_coex_get_schm_curr_phase(void);
+static int wifi_coex_set_schm_curr_phase_idx(int idx);
+static int wifi_coex_get_schm_curr_phase_idx(void);
 
 /****************************************************************************
  * Public Functions declaration
@@ -277,35 +302,44 @@ uint8_t esp_crc8(const uint8_t *p, uint32_t len);
 
 /* WiFi interrupt private data */
 
-static int s_wifi_irq;
+static int g_wifi_irq = -1;
 
 /* WiFi thread private data */
 
-static pthread_key_t s_wifi_thread_key;
-static bool s_wifi_tkey_init;
+static pthread_key_t g_wifi_thread_key;
+static bool g_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;
+static uint32_t g_phy_clk_en_cnt;
+
+/* Reference count of enabling PHY */
+
+static uint8_t g_phy_access_ref;
+
+/* time stamp updated when the PHY/RF is turned on */
+
+static int64_t g_phy_rf_en_ts;
+
+static uint32_t g_common_clock_disable_time;
 
 /* 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 struct work_s g_wifi_evt_work;
+static sq_queue_t g_wifi_evt_queue;
+static struct wifi_notify g_wifi_notify[WIFI_ADPT_EVT_MAX];
+static sem_t g_evtexcl_sem = SEM_INITIALIZER(1);
+static sem_t g_connect_sem = SEM_INITIALIZER(0);
+static bool g_connected;
+
+static uint8_t g_ssid[32];
+static uint8_t g_password[64];
+static uint8_t g_ssid_len;
+static uint8_t g_password_len;
 
-static uint8_t s_ssid[32];
-static uint8_t s_password[64];
-static uint8_t s_ssid_len;
-static uint8_t s_password_len;
+/* Callback function to update WiFi MAC time */
+
+wifi_mac_time_update_cb_t g_wifi_mac_time_update_cb;
 
 /****************************************************************************
  * Public Data
@@ -316,9 +350,13 @@ static uint8_t s_password_len;
 wifi_osi_funcs_t g_wifi_osi_funcs =
 {
   ._version = ESP_WIFI_OS_ADAPTER_VERSION,
+  ._env_is_chip = wifi_env_is_chip,
+  ._set_intr = wifi_set_intr,
+  ._clear_intr = wifi_clear_intr,
   ._set_isr = esp_set_isr,
   ._ints_on = esp32_ints_on,
   ._ints_off = esp32_ints_off,
+  ._is_from_isr = wifi_is_from_isr,
   ._spin_lock_create = esp_spin_lock_create,
   ._spin_lock_delete = esp_spin_lock_delete,
   ._wifi_int_disable = esp_wifi_int_disable,
@@ -363,18 +401,24 @@ wifi_osi_funcs_t g_wifi_osi_funcs =
       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,
+  ._wifi_apb80m_request = wifi_apb80m_request,
+  ._wifi_apb80m_release = wifi_apb80m_release,
+  ._phy_disable = wifi_phy_disable,
+  ._phy_enable = wifi_phy_enable,
   ._phy_common_clock_enable = esp_phy_enable_clock,
   ._phy_common_clock_disable = esp_phy_disable_clock,
+  ._phy_update_country_info = wifi_phy_update_country_info,
   ._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,
+  ._wifi_reset_mac = wifi_reset_mac,
+  ._wifi_clock_enable = wifi_clock_enable,
+  ._wifi_clock_disable = wifi_clock_disable,
+  ._wifi_rtc_enable_iso = wifi_rtc_enable_iso,
+  ._wifi_rtc_disable_iso = wifi_rtc_disable_iso,
   ._esp_timer_get_time = esp_timer_get_time,
   ._nvs_set_i8 = esp_nvs_set_i8,
   ._nvs_get_i8 = esp_nvs_get_i8,
@@ -404,14 +448,25 @@ wifi_osi_funcs_t g_wifi_osi_funcs =
   ._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_init = wifi_coex_init,
+  ._coex_deinit = wifi_coex_deinit,
+  ._coex_enable = wifi_coex_enable,
+  ._coex_disable = wifi_coex_disable,
   ._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,
+  ._coex_wifi_channel_set = wifi_coex_wifi_set_channel,
+  ._coex_event_duration_get = wifi_coex_get_event_duration,
+  ._coex_pti_get = wifi_coex_get_pti,
+  ._coex_schm_status_bit_clear = wifi_coex_clear_schm_status_bit,
+  ._coex_schm_status_bit_set = wifi_coex_set_schm_status_bit,
+  ._coex_schm_interval_set = wifi_coex_set_schm_interval,
+  ._coex_schm_interval_get = wifi_coex_get_schm_interval,
+  ._coex_schm_curr_period_get = wifi_coex_get_schm_curr_period,
+  ._coex_schm_curr_phase_get = wifi_coex_get_schm_curr_phase,
+  ._coex_schm_curr_phase_idx_set = wifi_coex_set_schm_curr_phase_idx,
+  ._coex_schm_curr_phase_idx_get = wifi_coex_get_schm_curr_phase_idx,
   ._magic = ESP_WIFI_OS_ADAPTER_MAGIC,
 };
 
@@ -527,6 +582,36 @@ static void esp_update_time(struct timespec *timespec, uint32_t ticks)
 }
 
 /****************************************************************************
+ * Name: esp_event_lock
+ *
+ * Description:
+ *   Lock or unlock the event process
+ *
+ * Input Parameters:
+ *   lock - true: Lock event process, false: unlock event process
+ *
+ * Returned Value:
+ *   The result of lock or unlock the event process
+ *
+ ****************************************************************************/
+
+static int esp_event_lock(bool lock)
+{
+  int ret;
+
+  if (lock)
+    {
+      ret = nxsem_wait_uninterruptible(&g_evtexcl_sem);
+    }
+  else
+    {
+      ret = nxsem_post(&g_evtexcl_sem);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
  * Name: esp_set_isr
  *
  * Description:
@@ -550,6 +635,11 @@ static void esp_set_isr(int32_t n, void *f, void *arg)
   int cpu = 0;
   int tmp;
 
+  if (g_wifi_irq >= 0)
+    {
+      return ;
+    }
+
   irq = esp32_alloc_levelint(1);
   if (irq < 0)
     {
@@ -583,7 +673,7 @@ static void esp_set_isr(int32_t n, void *f, void *arg)
 
   esp32_attach_peripheral(cpu, n, irq);
 
-  s_wifi_irq = irq;
+  g_wifi_irq = irq;
 }
 
 /****************************************************************************
@@ -602,7 +692,7 @@ static void esp_set_isr(int32_t n, void *f, void *arg)
 
 static void esp32_ints_on(uint32_t mask)
 {
-  up_enable_irq(s_wifi_irq);
+  up_enable_irq(g_wifi_irq);
 }
 
 /****************************************************************************
@@ -621,7 +711,26 @@ static void esp32_ints_on(uint32_t mask)
 
 static void esp32_ints_off(uint32_t mask)
 {
-  up_disable_irq(s_wifi_irq);
+  up_disable_irq(g_wifi_irq);
+}
+
+/****************************************************************************
+ * Name: wifi_is_from_isr
+ *
+ * Description:
+ *   Check current is in interrupt
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   true if in interrupt or false if not
+ *
+ ****************************************************************************/
+
+static bool IRAM_ATTR wifi_is_from_isr(void)
+{
+  return up_interrupt_context();
 }
 
 /****************************************************************************
@@ -921,19 +1030,19 @@ static void *esp_thread_semphr_get(void)
   int ret;
   void *sem;
 
-  if (s_wifi_tkey_init)
+  if (g_wifi_tkey_init)
   {
-    ret = pthread_key_create(&s_wifi_thread_key, esp_thread_semphr_free);
+    ret = pthread_key_create(&g_wifi_thread_key, esp_thread_semphr_free);
     if (ret)
       {
         wlerr("ERROR: Failed to create pthread key\n");
         return NULL;
       }
 
-    s_wifi_tkey_init = true;
+    g_wifi_tkey_init = true;
   }
 
-  sem = pthread_getspecific(s_wifi_thread_key);
+  sem = pthread_getspecific(g_wifi_thread_key);
   if (!sem)
     {
       sem = esp_semphr_create(1, 0);
@@ -943,7 +1052,7 @@ static void *esp_thread_semphr_get(void)
           return NULL;
         }
 
-      ret = pthread_setspecific(s_wifi_thread_key, sem);
+      ret = pthread_setspecific(g_wifi_thread_key, sem);
       if (ret)
         {
           wlerr("ERROR: Failed to set specific\n");
@@ -1800,7 +1909,7 @@ static void esp_evt_work_cb(FAR void *arg)
   while (1)
     {
       flags = enter_critical_section();
-      evt_adpt = (struct evt_adpt *)sq_remfirst(&s_wifi_evt_queue);
+      evt_adpt = (struct evt_adpt *)sq_remfirst(&g_wifi_evt_queue);
       leave_critical_section(flags);
       if (!evt_adpt)
         {
@@ -1810,6 +1919,11 @@ static void esp_evt_work_cb(FAR void *arg)
       switch (evt_adpt->id)
         {
           case WIFI_ADPT_EVT_STA_START:
+            ret = esp_wifi_set_ps(WIFI_PS_NONE);
+            if (ret)
+              {
+                wlerr("ERROR: Failed to close PS\n");
+              }
             ret = esp_wifi_connect();
             if (ret)
               {
@@ -1817,15 +1931,15 @@ static void esp_evt_work_cb(FAR void *arg)
               }
             break;
           case WIFI_ADPT_EVT_STA_CONNECT:
-            s_connected = true;
-            ret = sem_post(&s_connect_sem);
+            g_connected = true;
+            ret = sem_post(&g_connect_sem);
             if (ret)
               {
                 wlerr("ERROR: Failed to post sem error=%d\n", errno);
               }
             break;
           case WIFI_ADPT_EVT_STA_DISCONNECT:
-            s_connected = false;
+            g_connected = false;
             ret = esp_wifi_connect();
             if (ret)
               {
@@ -1836,7 +1950,9 @@ static void esp_evt_work_cb(FAR void *arg)
             break;
         }
 
-      notify = &s_wifi_notify[evt_adpt->id];
+      esp_event_lock(true);
+
+      notify = &g_wifi_notify[evt_adpt->id];
       if (notify->assigned)
         {
           notify->event.sigev_value.sival_ptr = evt_adpt->buf;
@@ -1850,11 +1966,65 @@ static void esp_evt_work_cb(FAR void *arg)
             }
         }
 
+      esp_event_lock(false);
+
       free(evt_adpt);
     }
 }
 
 /****************************************************************************
+ * Name: wifi_env_is_chip
+ *
+ * Description:
+ *   Config chip environment
+ *
+ * Returned Value:
+ *   True if on chip or false if on FPGA.
+ *
+ ****************************************************************************/
+
+static bool wifi_env_is_chip(void)
+{
+  return true;
+}
+
+/****************************************************************************
+ * Name: wifi_set_intr
+ *
+ * Description:
+ *   Do nothing
+ *
+ * Input Parameters:
+ *     cpu_no      - The CPU which the interrupt number belongs.
+ *     intr_source - The interrupt hardware source number.
+ *     intr_num    - The interrupt number CPU.
+ *     intr_prio   - The interrupt priority.
+ *
+ * Returned Value:
+ *     None
+ *
+ ****************************************************************************/
+
+static void wifi_set_intr(int32_t cpu_no, uint32_t intr_source,
+                          uint32_t intr_num, int32_t intr_prio)
+{
+  wlinfo("cpu_no=%d, intr_source=%u, intr_num=%u, intr_prio=%d");
+}
+
+/****************************************************************************
+ * Name: wifi_clear_intr
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR wifi_clear_intr(uint32_t intr_source,
+                                      uint32_t intr_num)
+{
+}
+
+/****************************************************************************
  * Name: esp_event_post
  *
  * Description:
@@ -1905,10 +2075,10 @@ int32_t esp_event_post(esp_event_base_t event_base,
   memcpy(evt_adpt->buf, event_data, event_data_size);
 
   flags = enter_critical_section();
-  sq_addlast(&evt_adpt->entry, &s_wifi_evt_queue);
+  sq_addlast(&evt_adpt->entry, &g_wifi_evt_queue);
   leave_critical_section(flags);
 
-  work_queue(LPWORK, &s_wifi_evt_work, esp_evt_work_cb, NULL, 0);
+  work_queue(LPWORK, &g_wifi_evt_work, esp_evt_work_cb, NULL, 0);
 
   return 0;
 }
@@ -1973,160 +2143,125 @@ static void esp_dport_access_stall_other_cpu_end(void)
 }
 
 /****************************************************************************
- * Name: esp_phy_rf_init
+ * Name: wifi_apb80m_request
  *
  * 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
+ *   Don't support
  *
  ****************************************************************************/
 
-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)
+static void wifi_apb80m_request(void)
 {
-  irqstate_t flags;
-  int64_t time;
-  bool enable = false;
+}
 
-  if (module >= PHY_MODULE_COUNT)
-    {
-      return -1;
-    }
+/****************************************************************************
+ * Name: wifi_apb80m_release
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  flags = enter_critical_section();
+static void wifi_apb80m_release(void)
+{
+}
 
-  s_esp32_phy_init_mask |= 1 << module;
+/****************************************************************************
+ * Name: phy_update_wifi_mac_time
+ *
+ * Description:
+ *   Update WiFi mac timer.
+ *
+ * Input Parameters:
+ *   en_clock_stopped - Check if clock is stoppped
+ *   now              - time now
+ *
+ * Returned Value:
+ *   NOne
+ *
+ ****************************************************************************/
 
-  if (s_esp23_phy_en)
-    {
-      leave_critical_section(flags);
-      return 0;
-    }
+static void phy_update_wifi_mac_time(bool en_clock_stopped, int64_t now)
+{
+  uint32_t diff;
 
-  if (module == PHY_MODEM_MODULE)
+  if (en_clock_stopped)
     {
-      if (s_esp32_phy_init_mask & PHY_RF_MASK)
-        {
-          enable = true;
-        }
-    }
-  else if (module == PHY_WIFI_MODULE || module == PHY_BT_MODULE)
-    {
-      enable = true;
+      g_common_clock_disable_time = (uint32_t)now;
     }
-
-  if (enable)
+  else
     {
-      if (s_esp32_phy_rf_stop_tm)
+      if (g_common_clock_disable_time)
         {
-          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);
+          diff = (uint64_t)now - g_common_clock_disable_time;
 
-      register_chipv7_phy(init_data, calibration_data, mode);
+          esp_wifi_internal_update_mac_time(diff);
 
-      s_esp23_phy_en = true;
+          g_common_clock_disable_time = 0;
+        }
     }
-
-  leave_critical_section(flags);
-
-  return 0;
 }
 
 /****************************************************************************
- * Name: esp_phy_deinit_rf
+ * Name: wifi_phy_disable
  *
  * Description:
  *   Deinitialize PHY hardware
  *
  * Input Parameters:
- *   module - PHY mode which is to be deinitialized
+ *   None
  *
  * Returned Value:
- *   0 if success or -1 if fail
+ *   None
  *
  ****************************************************************************/
 
-static int32_t esp_phy_deinit_rf(uint32_t module)
+static void wifi_phy_disable(void)
 {
   irqstate_t flags;
-  bool disable = false;
-
-  if (module >= PHY_MODULE_COUNT)
-    {
-      return -1;
-    }
-
   flags = enter_critical_section();
 
-  s_esp32_phy_init_mask |= ~(1 << module);
+  g_phy_access_ref--;
 
-  if (!s_esp23_phy_en)
+  if (g_phy_access_ref == 0)
     {
-      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;
-        }
-    }
+      /* Disable PHY and RF. */
 
-  if (disable)
-    {
       phy_close_rf();
 
-      s_esp32_phy_rf_stop_tm = esp_timer_get_time();
+      /* Update WiFi MAC time before disalbe
+       * WiFi/BT common peripheral clock.
+       */
+
+      phy_update_wifi_mac_time(true, esp_timer_get_time());
 
-      esp_phy_disable_clock();
+      /* Disable WiFi/BT common peripheral clock.
+       * Do not disable clock for hardware RNG.
+       */
 
-      s_esp23_phy_en = false;
+      esp_phy_disable_clock();
     }
 
   leave_critical_section(flags);
-
-  return 0;
 }
 
 /****************************************************************************
- * Name: esp_phy_init
+ * Name: wifi_phy_enable
  *
  * Description:
  *   Initialize PHY hardware
  *
  * Input Parameters:
- *   module - PHY mode which is to be initialized
+ *   None
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_phy_init(uint32_t module)
+static void wifi_phy_enable(void)
 {
-  int ret;
+  irqstate_t flags;
   esp_phy_calibration_data_t *cal_data;
 
   cal_data = kmm_zalloc(sizeof(esp_phy_calibration_data_t));
@@ -2136,13 +2271,24 @@ static void esp_phy_init(uint32_t module)
       DEBUGASSERT(0);
     }
 
-  ret = esp_phy_rf_init(&phy_init_data, PHY_RF_CAL_FULL, cal_data, module);
-  if (ret)
+  flags = enter_critical_section();
+
+  if (g_phy_access_ref == 0)
     {
-      wlerr("ERROR: Failed to initialize RF");
-      DEBUGASSERT(0);
+      /* Update time stamp */
+
+      g_phy_rf_en_ts = esp_timer_get_time();
+
+      /* Update WiFi MAC time before WiFi/BT common clock is enabled */
+
+      phy_update_wifi_mac_time(false, g_phy_rf_en_ts);
+      esp_phy_enable_clock();
+      phy_set_wifi_mode_only(0);
+      register_chipv7_phy(&phy_init_data, cal_data, PHY_RF_CAL_NONE);
     }
 
+  g_phy_access_ref++;
+  leave_critical_section(flags);
   kmm_free(cal_data);
 }
 
@@ -2166,13 +2312,13 @@ void esp_phy_enable_clock(void)
 
   flags = enter_critical_section();
 
-  if (s_phy_clk_en_cnt == 0)
+  if (g_phy_clk_en_cnt == 0)
     {
       modifyreg32(DPORT_WIFI_CLK_EN_REG, 0,
                   DPORT_WIFI_CLK_WIFI_BT_COMMON_M);
     }
 
-  s_phy_clk_en_cnt++;
+  g_phy_clk_en_cnt++;
 
   leave_critical_section(flags);
 }
@@ -2197,10 +2343,10 @@ void esp_phy_disable_clock(void)
 
   flags = enter_critical_section();
 
-  if (s_phy_clk_en_cnt)
+  if (g_phy_clk_en_cnt)
     {
-      s_phy_clk_en_cnt--;
-      if (!s_phy_clk_en_cnt)
+      g_phy_clk_en_cnt--;
+      if (!g_phy_clk_en_cnt)
         {
           modifyreg32(DPORT_WIFI_CLK_EN_REG,
                       DPORT_WIFI_CLK_WIFI_BT_COMMON_M,
@@ -2212,6 +2358,19 @@ void esp_phy_disable_clock(void)
 }
 
 /****************************************************************************
+ * Name: wifi_phy_update_country_info
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int32_t wifi_phy_update_country_info(const char *country)
+{
+  return -1;
+}
+
+/****************************************************************************
  * Name: esp_read_mac
  *
  * Description:
@@ -2466,44 +2625,88 @@ static void esp_timer_arm_us(void *ptimer, uint32_t us, bool repeat)
 }
 
 /****************************************************************************
- * Name: esp_periph_module_enable
+ * Name: wifi_reset_mac
  *
  * Description:
- *   Enable WiFi module clock
+ *   Reset WiFi hardware MAC
  *
  * Input Parameters:
- *   periph - No mean
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_reset_mac(void)
+{
+  modifyreg32(DPORT_WIFI_RST_EN_REG, 0, DPORT_MAC_RST_EN);
+  modifyreg32(DPORT_WIFI_RST_EN_REG, DPORT_MAC_RST_EN, 0);
+}
+
+/****************************************************************************
+ * Name: wifi_clock_enable
+ *
+ * Description:
+ *   Enable Wi-Fi clock
+ *
+ * Input Parameters:
+ *   None
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_periph_module_enable(uint32_t periph)
+static void wifi_clock_enable(void)
 {
   modifyreg32(DPORT_WIFI_CLK_EN_REG, 0, DPORT_WIFI_CLK_WIFI_EN_M);
 }
 
 /****************************************************************************
- * Name: esp_periph_module_enable
+ * Name: wifi_clock_disable
  *
  * Description:
- *   Disable WiFi module clock
+ *   Disable Wi-Fi clock
  *
  * Input Parameters:
- *   periph - No mean
+ *   None
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_periph_module_disable(uint32_t periph)
+static void wifi_clock_disable(void)
 {
   modifyreg32(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_WIFI_EN_M, 0);
 }
 
 /****************************************************************************
+ * Name: wifi_rtc_enable_iso
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_rtc_enable_iso(void)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_rtc_disable_iso
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_rtc_disable_iso(void)
+{
+}
+
+/****************************************************************************
  * Name: esp_timer_get_time
  *
  * Description:
@@ -2519,22 +2722,7 @@ static void esp_periph_module_disable(uint32_t periph)
 
 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;
+  return (int64_t)rt_timer_time_us();
 }
 
 /****************************************************************************
@@ -3173,10 +3361,10 @@ 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);
+  va_list list;
+  va_start(list, format);
+  esp_log_writev(level, tag, format, list);
+  va_end(list);
 }
 
 /****************************************************************************
@@ -3414,261 +3602,244 @@ static void esp_wifi_delete_queue(void *queue)
 }
 
 /****************************************************************************
- * Name: esp_modem_enter_sleep
+ * Name: wifi_coex_init
  *
  * Description:
- *   Let given module to enter sleep mode
+ *   Don't support
  *
- * Input Parameters:
- *   module - hardware module ID
+ ****************************************************************************/
+
+static int wifi_coex_init(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_deinit
  *
- * Returned Value:
- *   0 if success or -1 if fail
+ * Description:
+ *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_modem_enter_sleep(uint32_t module)
+static void wifi_coex_deinit(void)
 {
-  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);
+/****************************************************************************
+ * Name: wifi_coex_enable
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  return ret;
+static int wifi_coex_enable(void)
+{
+  return 0;
 }
 
 /****************************************************************************
- * Name: esp_modem_enter_sleep
+ * Name: wifi_coex_disable
  *
  * Description:
- *   Let given module to exit from sleep mode
- *
- * Input Parameters:
- *   module - hardware module ID
- *
- * Returned Value:
- *   0 if success or -1 if fail
+ *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_modem_exit_sleep(uint32_t module)
+static void wifi_coex_disable(void)
 {
-  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
+ * Name: esp_coex_status_get
  *
  * 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
+ *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_modem_register_sleep(uint32_t module)
+static uint32_t esp_coex_status_get(void)
 {
-  irqstate_t flags;
-  uint32_t bit;
+  return 0;
+}
 
-  if (module >= (uint32_t)MODEM_MODULE_COUNT)
-    {
-      return -1;
-    }
+/****************************************************************************
+ * Name: esp_coex_condition_set
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  bit = 1 << module;
+static void esp_coex_condition_set(uint32_t type, bool dissatisfy)
+{
+}
 
-  flags = enter_critical_section();
+/****************************************************************************
+ * Name: esp_coex_wifi_request
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  if (s_esp32_module_mask & bit)
-    {
-      /* Has registered and return success */
+static int32_t esp_coex_wifi_request(uint32_t event, uint32_t latency,
+                                     uint32_t duration)
+{
+  return 0;
+}
 
-      return 0;
-    }
+/****************************************************************************
+ * Name: esp_coex_wifi_release
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  s_esp32_module_mask |= bit;
-  s_esp32_module_sleep |= bit;
+static int32_t esp_coex_wifi_release(uint32_t event)
+{
+  return 0;
+}
 
-  leave_critical_section(flags);
+/****************************************************************************
+ * Name: wifi_coex_wifi_set_channel
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
+static int wifi_coex_wifi_set_channel(uint8_t primary, uint8_t secondary)
+{
   return 0;
 }
 
 /****************************************************************************
- * Name: esp_modem_deregister_sleep
+ * Name: wifi_coex_get_event_duration
  *
  * Description:
- *   Deregitser given module so that it can't enter sleep mode
+ *   Don't support
  *
- * Input Parameters:
- *   module - hardware module ID
+ ****************************************************************************/
+
+static int wifi_coex_get_event_duration(uint32_t event, uint32_t *duration)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_pti
  *
- * Returned Value:
- *   0 if success or -1 if fail
+ * Description:
+ *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_modem_deregister_sleep(uint32_t module)
+static int wifi_coex_get_pti(uint32_t event, uint8_t *pti)
 {
-  int ret;
-  irqstate_t flags;
-  uint32_t bit;
+  return 0;
+}
 
-  if (module >= (uint32_t)MODEM_MODULE_COUNT)
-    {
-      return -1;
-    }
+/****************************************************************************
+ * Name: wifi_coex_clear_schm_status_bit
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  bit = 1 << module;
+static void wifi_coex_clear_schm_status_bit(uint32_t type, uint32_t status)
+{
+}
 
-  flags = enter_critical_section();
+/****************************************************************************
+ * Name: wifi_coex_set_schm_status_bit
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  if (!(s_esp32_module_mask & bit))
-    {
-      /* Has deregistered and return success */
+static void wifi_coex_set_schm_status_bit(uint32_t type, uint32_t status)
+{
+}
 
-      return 0;
-    }
+/****************************************************************************
+ * Name: wifi_coex_set_schm_interval
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
-  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");
-            }
-        }
-    }
+static int wifi_coex_set_schm_interval(uint32_t interval)
+{
+  return 0;
+}
 
-  leave_critical_section(flags);
+/****************************************************************************
+ * Name: wifi_coex_get_schm_interval
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
 
+static uint32_t wifi_coex_get_schm_interval(void)
+{
   return 0;
 }
 
 /****************************************************************************
- * Name: esp_coex_status_get
+ * Name: wifi_coex_get_schm_curr_period
  *
  * Description:
  *   Don't support
  *
  ****************************************************************************/
 
-static uint32_t esp_coex_status_get(void)
+static uint8_t wifi_coex_get_schm_curr_period(void)
 {
   return 0;
 }
 
 /****************************************************************************
- * Name: esp_coex_condition_set
+ * Name: wifi_coex_get_schm_curr_phase
  *
  * Description:
  *   Don't support
  *
  ****************************************************************************/
 
-static void esp_coex_condition_set(uint32_t type, bool dissatisfy)
+static void *wifi_coex_get_schm_curr_phase(void)
 {
+  return NULL;
 }
 
 /****************************************************************************
- * Name: esp_coex_wifi_request
+ * Name: wifi_coex_set_schm_curr_phase_idx
  *
  * Description:
  *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_coex_wifi_request(uint32_t event, uint32_t latency,
-                                     uint32_t duration)
+static int wifi_coex_set_schm_curr_phase_idx(int idx)
 {
-  return 0;
+  return -1;
 }
 
 /****************************************************************************
- * Name: esp_coex_wifi_release
+ * Name: wifi_coex_get_schm_curr_phase_idx
  *
  * Description:
  *   Don't support
  *
  ****************************************************************************/
 
-static int32_t esp_coex_wifi_release(uint32_t event)
+static int wifi_coex_get_schm_curr_phase_idx(void)
 {
   return 0;
 }
@@ -3811,6 +3982,38 @@ int net80211_printf(const char *format, ...)
 }
 
 /****************************************************************************
+ * Functions needed by libnet80211.a
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_mesh_send_event_internal
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+int esp_mesh_send_event_internal(int32_t event_id,
+                                 void *event_data,
+                                 size_t event_data_size)
+{
+  return -1;
+}
+
+/****************************************************************************
+ * Name: esp_mesh_get_topology
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+void *esp_mesh_get_topology(void)
+{
+  return NULL;
+}
+
+/****************************************************************************
  * Functions needed by libwpa_supplicant.a
  ****************************************************************************/
 
@@ -3969,9 +4172,9 @@ int32_t esp_timer_delete(esp_timer_handle_t timer)
 void __assert_func(const char *file, int line,
                    const char *func, const char *expr)
 {
-    wlerr("ERROR: Assert failed in %s, %s:%d (%s)",
-          func, file, line, expr);
-    abort();
+  wlerr("ERROR: Assert failed in %s, %s:%d (%s)",
+        func, file, line, expr);
+  abort();
 }
 
 /****************************************************************************
@@ -4191,41 +4394,70 @@ int esp_wifi_notify_subscribe(pid_t pid, FAR struct sigevent *event)
 
   wlinfo("PID=%d event=%p\n", pid, event);
 
-  if (event->sigev_notify != SIGEV_SIGNAL)
-    {
-      wlerr("ERROR: sigev_notify %d is invalid\n", event->sigev_signo);
-      return -1;
-    }
+  esp_event_lock(true);
 
-  id = esp_event_id_map(event->sigev_signo);
-  if (id < 0)
+  if (event->sigev_notify == SIGEV_SIGNAL)
     {
-      wlerr("ERROR: No process event %d\n", event->sigev_signo);
+      id = esp_event_id_map(event->sigev_signo);
+      if (id < 0)
+        {
+          wlerr("ERROR: No process event %d\n", event->sigev_signo);
+        }
+      else
+        {
+          notify = &g_wifi_notify[id];
+
+          if (notify->assigned)
+            {
+              wlerr("ERROR: sigev_signo %d has subscribed\n",
+                    event->sigev_signo);
+            }
+          else
+            {
+              if (pid == 0)
+                {
+                  pid = getpid();
+                  wlinfo("Actual PID=%d\n", pid);
+                }
+
+              notify->pid = pid;
+              notify->event = *event;
+              notify->assigned = true;
+
+              ret = 0;
+            }
+        }
     }
-  else
+  else if (event->sigev_notify == SIGEV_NONE)
     {
-      notify = &s_wifi_notify[id];
-
-      if (notify->assigned)
+      id = esp_event_id_map(event->sigev_signo);
+      if (id < 0)
         {
-          wlerr("ERROR: sigev_signo %d has subscribed\n",
-                event->sigev_signo);
+          wlerr("ERROR: No process event %d\n", event->sigev_signo);
         }
       else
         {
-          if (pid == 0)
+          notify = &g_wifi_notify[id];
+
+          if (!notify->assigned)
             {
-              pid = getpid();
-              wlinfo("Actual PID=%d\n", pid);
+              wlerr("ERROR: sigev_signo %d has not subscribed\n",
+                    event->sigev_signo);
             }
+          else
+            {
+              notify->assigned = false;
 
-          notify->pid = pid;
-          notify->event = *event;
-          notify->assigned = true;
-
-          ret = 0;
+              ret = 0;
+            }
         }
     }
+  else
+    {
+      wlerr("ERROR: sigev_notify %d is invalid\n", event->sigev_signo);
+    }
+
+  esp_event_lock(false);
 
   return ret;
 }
@@ -4247,37 +4479,47 @@ int esp_wifi_notify_subscribe(pid_t pid, FAR struct sigevent *event)
 int esp_wifi_adapter_init(void)
 {
   int ret;
-  wifi_init_config_t init_cfg = WIFI_INIT_CONFIG_DEFAULT();
-
-  ret = sem_init(&s_connect_sem, 0, 0);
-  if (ret)
-    {
-      wlerr("ERROR: Failed to initialize sem error=%d\n", errno);
-      return -1;
-    }
-
-#ifndef CONFIG_ESP32_WIFI_SAVE_PARAM
-  init_cfg.nvs_enable = 0;
-#endif
+  wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
 
   ret = esp32_rt_timer_init();
   if (ret < 0)
     {
       wlerr("ERROR: Failed to initialize RT timer error=%d\n", ret);
-      sem_destroy(&s_connect_sem);
       return -1;
     }
 
-  ret = esp_wifi_init(&init_cfg);
+#ifdef CONFIG_ESP32_WIFI_SAVE_PARAM
+  wifi_cfg.nvs_enable = 1;
+#else
+  wifi_cfg.nvs_enable = 0;
+#endif
+
+#ifdef CONFIG_ESP32_WIFI_TX_AMPDU
+  wifi_cfg.ampdu_tx_enable = 1;
+#else
+  wifi_cfg.ampdu_tx_enable = 0;
+#endif
+
+#ifdef CONFIG_ESP32_WIFI_RX_AMPDU
+  wifi_cfg.ampdu_rx_enable = 1;
+#else
+  wifi_cfg.ampdu_rx_enable = 0;
+#endif
+
+  wifi_cfg.rx_ba_win          = CONFIG_ESP32_WIFI_RXBA_AMPDU_WZ;
+  wifi_cfg.static_rx_buf_num  = CONFIG_ESP32_WIFI_STATIC_RXBUF_NUM;
+  wifi_cfg.dynamic_rx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_RXBUF_NUM;
+  wifi_cfg.dynamic_tx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_TXBUF_NUM;
+
+  ret = esp_wifi_init(&wifi_cfg);
   if (ret)
     {
       wlerr("ERROR: Failed to initialize WiFi error=%d\n", ret);
-      sem_destroy(&s_connect_sem);
       esp32_rt_timer_deinit();
       return -1;
     }
 
-  sq_init(&s_wifi_evt_queue);
+  sq_init(&g_wifi_evt_queue);
 
   return 0;
 }
@@ -4299,8 +4541,8 @@ int esp_wifi_adapter_init(void)
 
 int esp_wifi_set_password(const uint8_t *pdata, uint8_t len)
 {
-  memcpy(s_password, pdata, len);
-  s_password_len = len;
+  memcpy(g_password, pdata, len);
+  g_password_len = len;
 
   return 0;
 }
@@ -4322,8 +4564,8 @@ int esp_wifi_set_password(const uint8_t *pdata, uint8_t len)
 
 int esp_wifi_set_ssid(const uint8_t *pdata, uint8_t len)
 {
-  memcpy(s_ssid, pdata, len);
-  s_ssid_len = len;
+  memcpy(g_ssid, pdata, len);
+  g_ssid_len = len;
 
   return 0;
 }
@@ -4348,7 +4590,7 @@ int esp_wifi_connect_internal(void)
   wifi_config_t wifi_cfg;
   struct timespec timeout;
 
-  if (s_connected)
+  if (g_connected)
     {
       wlinfo("INFO: WiFi has connected AP\n");
       return 0;
@@ -4363,8 +4605,8 @@ int esp_wifi_connect_internal(void)
     }
 
   memset(&wifi_cfg, 0, sizeof(wifi_config_t));
-  memcpy((char *)wifi_cfg.sta.ssid, s_ssid, s_ssid_len);
-  memcpy((char *)wifi_cfg.sta.password, s_password, s_password_len);
+  memcpy((char *)wifi_cfg.sta.ssid, g_ssid, g_ssid_len);
+  memcpy((char *)wifi_cfg.sta.password, g_password, g_password_len);
 
   ret = esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_cfg);
   if (ret)
@@ -4383,7 +4625,7 @@ int esp_wifi_connect_internal(void)
   clock_gettime(CLOCK_REALTIME, &timeout);
   timeout.tv_sec += WIFI_CONNECT_TIMEOUT;
 
-  ret = sem_timedwait(&s_connect_sem, &timeout);
+  ret = sem_timedwait(&g_connect_sem, &timeout);
   if (ret)
     {
       wlerr("ERROR: Failed to wait sem error=%d\n", errno);
@@ -4391,7 +4633,7 @@ int esp_wifi_connect_internal(void)
       return -1;
     }
 
-  if (!s_connected)
+  if (!g_connected)
     {
       wlerr("ERROR: Process connection error\n");
       esp_wifi_stop();
@@ -4400,3 +4642,22 @@ int esp_wifi_connect_internal(void)
 
   return 0;
 }
+
+/****************************************************************************
+ * Name: esp_wifi_sta_register_txdone_cb
+ *
+ * Description:
+ *   Register the txDone callback function of type wifi_tx_done_cb_t
+ *
+ * Input Parameters:
+ *   callback - The callback function
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_register_txdone_cb(void *callback)
+{
+  return esp_wifi_set_tx_done_cb((wifi_tx_done_cb_t)callback);
+}
diff --git a/arch/xtensa/src/esp32/esp32_wifi_adapter.h b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
index 33ccbfe..5a66d2c 100644
--- a/arch/xtensa/src/esp32/esp32_wifi_adapter.h
+++ b/arch/xtensa/src/esp32/esp32_wifi_adapter.h
@@ -60,6 +60,9 @@ enum wifi_adpt_evt_e
 
 typedef void (*wifi_evt_cb_t)(void *p);
 
+typedef void (* wifi_tx_done_cb_t)(uint8_t ifidx, uint8_t *data,
+                                   uint16_t *len, bool txstatus);
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -214,6 +217,22 @@ int esp_wifi_set_ssid(const uint8_t *pdata, uint8_t len);
 
 int esp_wifi_connect_internal(void);
 
+/****************************************************************************
+ * Name: esp_wifi_sta_register_txdone_cb
+ *
+ * Description:
+ *   Register the txDone callback function of type wifi_tx_done_cb_t
+ *
+ * Input Parameters:
+ *   callback - The callback function
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_register_txdone_cb(void *callback);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/arch/xtensa/src/esp32/esp32_wlan.c b/arch/xtensa/src/esp32/esp32_wlan.c
index 1a7ab34..d5cf9df 100644
--- a/arch/xtensa/src/esp32/esp32_wlan.c
+++ b/arch/xtensa/src/esp32/esp32_wlan.c
@@ -23,161 +23,186 @@
  ****************************************************************************/
 
 #include <nuttx/config.h>
-#include <debug.h>
+
+#ifdef CONFIG_ESP32_WIRELESS
+
 #include <queue.h>
 #include <errno.h>
+#include <debug.h>
+#include <crc64.h>
 #include <arpa/inet.h>
 
+#include <nuttx/nuttx.h>
 #include <nuttx/arch.h>
 #include <nuttx/irq.h>
 #include <nuttx/wdog.h>
 #include <nuttx/wqueue.h>
-#include <nuttx/net/mii.h>
 #include <nuttx/net/arp.h>
 #include <nuttx/net/netdev.h>
-#include <crc64.h>
-
 #if defined(CONFIG_NET_PKT)
 #  include <nuttx/net/pkt.h>
 #endif
 
-#include <nuttx/net/net.h>
-#include <nuttx/kmalloc.h>
-#include <debug.h>
-
 #include "esp32_wifi_adapter.h"
 
-#include <arch/board/board.h>
-
-#ifdef CONFIG_ESP32_WIRELESS
-
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define STA_DEVNO                  0
+/* WLAN station device ID */
 
-/* TX poll delay = 1 seconds.
+#define WLAN_STA_DEVNO            (0)
+
+/**
+ * TX poll delay = 1 seconds.
  * CLK_TCK is the number of clock ticks per second
  */
 
-#define ESP_WDDELAY                (1*CLK_TCK)
-#define ESPWORK                    LPWORK
+#define WLAN_WDDELAY              (1 * CLK_TCK)
 
 /* TX timeout = 1 minute */
 
-#define ESP_TXTIMEOUT              (60*CLK_TCK)
-#define DEFAULT_SCAN_LIST_SIZE     2
+#define WLAN_TXTOUT               (60 * CLK_TCK)
 
-/* Add 4 to the configured buffer size to account for the 2 byte checksum
- * memory needed at the end of the maximum size packet.  Buffer sizes must
- * be an even multiple of 4, 8, or 16 bytes (depending on buswidth).  We
- * will use the 16-byte alignment in all cases.
- */
+/* Low-priority workqueue processes RX/TX */
 
-#define OPTIMAL_ETH_BUFSIZE ((CONFIG_NET_ETH_PKTSIZE + 4 + 15) & ~15)
+#define WLAN_WORK                 LPWORK
 
-#ifndef CONFIG_ESP_ETH_BUFSIZE
-#  define CONFIG_ESP_ETH_BUFSIZE   OPTIMAL_ETH_BUFSIZE
-#endif
+/**
+ * Ethernet frame:
+ *     Resource address   :   6 bytes
+ *     Destination address:   6 bytes
+ *     Type               :   2 bytes
+ *     Payload            :   MAX 1500
+ *     Checksum           :   Ignore
+ *
+ *     Total size         :   1514
+ */
 
-#ifndef CONFIG_ESP_ETH_NTXDESC
-#  define CONFIG_ESP_ETH_NTXDESC   4
-#endif
+#define WLAN_BUF_SIZE             (CONFIG_NET_ETH_PKTSIZE)
 
-/* We need at least one more free buffer than transmit buffers */
+/* WiFi receive buffer number */
 
-#define ESP_ETH_NFREEBUFFERS (CONFIG_ESP_ETH_NTXDESC+1)
-#define ETH_MAX_LEN                1518
+#define WLAN_RXBUF_NUM            (CONFIG_ESP32_WLAN_RXBUF_NUM)
 
-/* This is a helper pointer for accessing the contents of wlan header */
+/**
+ * Receive threshold which let the receive function to trigger a sheduler
+ * to active application if possible.
+ */
 
-#define BUF ((struct eth_hdr_s *)priv->esp_dev.d_buf)
+#ifdef CONFIG_MM_IOB
+#  define IOBBUF_SIZE             (CONFIG_IOB_NBUFFERS * CONFIG_IOB_BUFSIZE)
+#  if (IOBBUF_SIZE) > (WLAN_BUF_SIZE + 1)
+#    define WLAN_RX_THRESHOLD     (IOBBUF_SIZE - WLAN_BUF_SIZE + 1)
+#  endif
+#endif
 
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-/* The esp_dev_s encapsulates all state information for a single
+/* Receive buffer */
+
+struct wlan_rxbuf
+{
+  sq_entry_t    entry;          /* Queue entry */
+
+  /* Packet data buffer */
+
+  uint8_t       buffer[WLAN_BUF_SIZE];
+  uint16_t      len;            /* Packet data length */
+};
+
+/* The wlan_priv_s encapsulates all state information for a single
  * hardware interface
  */
 
-struct esp_dev_s
+struct wlan_priv_s
 {
   bool   ifup;                  /* true:ifup false:ifdown */
-  struct wdog_s esp_txpoll;     /* TX poll timer */
-  struct wdog_s esp_txtimeout;  /* TX timeout timer */
-  struct work_s esp_irqwork;    /* For deferring interrupt work to the work queue */
-  struct work_s esp_pollwork;   /* For deferring poll work to the work queue */
+
+  struct wdog_s txpoll;         /* TX poll timer */
+  struct wdog_s txtimeout;      /* TX timeout timer */
+
+  struct work_s rxwork;         /* Send packet work */
+  struct work_s txwork;         /* Receive packet work */
+  struct work_s pollwork;       /* Poll work */
+  struct work_s toutwork;       /* Send packet timeout work */
 
   /* This holds the information visible to the NuttX network */
 
-  struct net_driver_s esp_dev;
-  sq_queue_t           freeb;    /* The free buffer list */
+  struct net_driver_s dev;
+
+  /* TX buffer */
+
+  uint8_t       txbuf[WLAN_BUF_SIZE];
+
+  /* Rest data in TX buffer which needs being sent */
+
+  uint8_t       txrst;
+
+  /* RX buffer cache */
+
+  struct wlan_rxbuf  rxbuf[WLAN_RXBUF_NUM];
+
+  /* RX buffer queue */
 
-  /* Buffer allocations */
+  sq_queue_t    rxb;
 
-  uint8_t alloc[CONFIG_ESP_ETH_NTXDESC*CONFIG_ESP_ETH_BUFSIZE];
-  uint8_t rxbuf[ETH_MAX_LEN];
-  uint32_t rx_len;
+  /* Free buffer queue */
+
+  sq_queue_t    freeb;
 };
 
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static struct esp_dev_s s_esp32_dev;
-static bool g_tx_ready = false;
+static struct wlan_priv_s g_wlan_priv;
 
 /****************************************************************************
  * Private Function Prototypes
  ****************************************************************************/
 
-/* Free buffer management */
-
-static void esp_initbuffer(FAR struct esp_dev_s *priv);
-static inline uint8_t *esp_allocbuffer(FAR struct esp_dev_s *priv);
-static inline void esp_freebuffer(FAR struct esp_dev_s *priv,
-                                  uint8_t *buffer);
-static inline bool esp_isfreebuffer(FAR struct esp_dev_s *priv);
-
 /* Common TX logic */
 
-static int  esp_transmit(FAR struct esp_dev_s *priv);
-static void esp_receive(FAR struct esp_dev_s *priv);
-static int  esp_txpoll(FAR struct net_driver_s *dev);
-static void esp_rxpoll(FAR void *arg);
-static void esp_dopoll(FAR struct esp_dev_s *priv);
-static void esp_netdev_notify_rx(FAR struct esp_dev_s *priv,
-                                 void *buffer, uint16_t len);
-static int esp_sta_input(void *buffer, uint16_t len, void *eb);
+static int  wlan_transmit(FAR struct wlan_priv_s *priv);
+static void wlan_rxpoll(FAR void *arg);
+static int  wlan_txpoll(FAR struct net_driver_s *dev);
+static void wlan_dopoll(FAR struct wlan_priv_s *priv);
 
 /* Watchdog timer expirations */
 
-static void esp_txtimeout_work(FAR void *arg);
-static void esp_txtimeout_expiry(wdparm_t arg);
+static void wlan_txtimeout_work(FAR void *arg);
+static void wlan_txtimeout_expiry(wdparm_t arg);
 
-static void esp_poll_work(FAR void *arg);
-static void esp_poll_expiry(wdparm_t arg);
+static void wlan_poll_work(FAR void *arg);
+static void wlan_poll_expiry(wdparm_t arg);
 
 /* NuttX callback functions */
 
-static int  esp_ifup(struct net_driver_s *dev);
-static int  esp_ifdown(struct net_driver_s *dev);
+static int wlan_ifup(struct net_driver_s *dev);
+static int wlan_ifdown(struct net_driver_s *dev);
 
-static void esp_txavail_work(FAR void *arg);
-static int  esp_txavail(struct net_driver_s *dev);
+static void wlan_txavail_work(FAR void *arg);
+static int wlan_txavail(struct net_driver_s *dev);
 
 #if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
-static int  esp_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+static int wlan_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
 #endif
+
 #ifdef CONFIG_NET_MCASTGROUP
-static int  esp_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+static int wlan_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
 #endif
+
 #ifdef CONFIG_NETDEV_IOCTL
-static int  esp_ioctl(struct net_driver_s *dev, int cmd,
-              unsigned long arg);
+static int wlan_ioctl(struct net_driver_s *dev, int cmd,
+                      unsigned long arg);
 #endif
+
+static void wlan_tx_done(uint8_t ifidx, uint8_t *data,
+                         uint16_t *len, bool txstatus);
+static int wlan_rx_done(void *buffer, uint16_t len, void *eb);
 static int esp32_net_initialize(unsigned int devno);
 
 /****************************************************************************
@@ -188,73 +213,91 @@ static int esp32_net_initialize(unsigned int devno);
  * Note:
  *     All TX done/RX done/Error trigger functions are not called from
  *     interrupts, this is much different from ethernet driver, including:
- *       * esp_sta_input
+ *       * wlan_rx_done
+ *       * wlan_tx_done
  *
  *     These functions are called in a WiFi private thread. So we just use
  *     mutex/semaphore instead of disable interrupt, if necessary.
  */
 
 /****************************************************************************
- * Function: esp_initbuffer
+ * Function: wlan_init_buffer
  *
  * Description:
- *   Initialize the free buffer list.
+ *   Initialize the free buffer list
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv - Reference to the driver state structure
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_initbuffer(FAR struct esp_dev_s *priv)
+static inline void wlan_init_buffer(struct wlan_priv_s *priv)
 {
-  uint8_t *buffer;
   int i;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
 
-  /* Initialize the head of the free buffer list */
+  priv->txrst = 0;
 
-  sq_init(&priv->freeb);
+  priv->dev.d_buf = NULL;
+  priv->dev.d_len = 0;
 
-  /* Add all of the pre-allocated buffers to the free buffer list */
+  sq_init(&priv->freeb);
+  sq_init(&priv->rxb);
 
-  for (i = 0, buffer = priv->alloc; i < ESP_ETH_NFREEBUFFERS;
-       i++, buffer += CONFIG_ESP_ETH_BUFSIZE)
+  for (i = 0; i < WLAN_RXBUF_NUM; i++)
     {
-      sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb);
+      sq_addlast(&priv->rxbuf[i].entry, &priv->freeb);
     }
+
+  leave_critical_section(flags);
 }
 
 /****************************************************************************
- * Function: esp_allocbuffer
+ * Function: wlan_alloc_buffer
  *
  * Description:
- *   Allocate one buffer from the free buffer list.
+ *   Allocate one buffer from the free buffer queue
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv - Reference to the driver state structure
  *
  * Returned Value:
  *   Pointer to the allocated buffer on success; NULL on failure
  *
  ****************************************************************************/
 
-static inline uint8_t *esp_allocbuffer(FAR struct esp_dev_s *priv)
+static inline struct wlan_rxbuf *wlan_alloc_buffer(struct wlan_priv_s *priv)
 {
-  /* Allocate a buffer by returning the head of the free buffer list */
+  sq_entry_t *entry;
+  irqstate_t flags;
+  struct wlan_rxbuf *rxbuf = NULL;
 
-  return (uint8_t *)sq_remfirst(&priv->freeb);
+  flags = enter_critical_section();
+
+  entry = sq_remfirst(&priv->freeb);
+  if (entry)
+    {
+      rxbuf = container_of(entry, struct wlan_rxbuf, entry);
+    }
+
+  leave_critical_section(flags);
+
+  return rxbuf;
 }
 
 /****************************************************************************
- * Function: esp_freebuffer
+ * Function: wlan_free_buffer
  *
  * Description:
- *   Return a buffer to the free buffer list.
+ *   Insert a free Rx buffer into free queue
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv   - Reference to the driver state structure
  *   buffer - A pointer to the buffer to be freed
  *
  * Returned Value:
@@ -262,42 +305,62 @@ static inline uint8_t *esp_allocbuffer(FAR struct esp_dev_s *priv)
  *
  ****************************************************************************/
 
-static inline void esp_freebuffer(FAR struct esp_dev_s *priv,
-                                  uint8_t *buffer)
+static inline void wlan_free_buffer(struct wlan_priv_s *priv,
+                                    uint8_t *buffer)
 {
-  /* Free the buffer by adding it to the end of the free buffer list */
+  struct wlan_rxbuf *rxbuf;
+  irqstate_t flags;
 
-  sq_addlast((FAR sq_entry_t *)buffer, &priv->freeb);
+  flags = enter_critical_section();
+
+  rxbuf = container_of(buffer, struct wlan_rxbuf, buffer);
+  sq_addlast(&rxbuf->entry, &priv->freeb);
+
+  leave_critical_section(flags);
 }
 
 /****************************************************************************
- * Function: esp_isfreebuffer
+ * Name: wifi_tx_available
  *
  * Description:
- *   Return TRUE if the free buffer list is not empty.
+ *   Check if WiFi can send data. This function will re-send rest data
+ *   which was sent failed.
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv - Reference to the driver state structure
  *
  * Returned Value:
- *   True if there are one or more buffers in the free buffer list;
- *   false if the free buffer list is empty
+ *   true if available or false if unavailable
  *
  ****************************************************************************/
 
-static inline bool esp_isfreebuffer(FAR struct esp_dev_s *priv)
+static bool wifi_tx_available(FAR struct wlan_priv_s *priv)
 {
-  /* Return TRUE if the free buffer list is not empty */
+  int ret;
 
-  return !sq_empty(&priv->freeb);
+  if (priv->txrst)
+    {
+      ret = esp_wifi_sta_send_data(priv->txbuf, priv->txrst);
+      if (ret)
+        {
+          ninfo("ERROR: Failed to transmit rest frame\n");
+          return false;
+        }
+      else
+        {
+          priv->txrst = 0;
+        }
+    }
+
+  return true;
 }
 
 /****************************************************************************
- * Name: esp_transmit
+ * Name: wlan_transmit
  *
  * Description:
- *   Start hardware transmission.  Called either from TX process or
- *   from watchdog based polling.
+ *   Send the data to WiFi driver. If this sending fails, cache the data
+ *   and re-send it when TX done callback or timer poll function triggers.
  *
  * Input Parameters:
  *   priv - Reference to the driver state structure
@@ -307,120 +370,229 @@ static inline bool esp_isfreebuffer(FAR struct esp_dev_s *priv)
  *
  ****************************************************************************/
 
-static int esp_transmit(FAR struct esp_dev_s *priv)
+static int wlan_transmit(FAR struct wlan_priv_s *priv)
 {
-  int ret = 0;
-  uint8_t *buffer;
-  uint32_t buffer_len;
-
-  /* Set up all but the last TX descriptor */
+  int ret;
+  struct net_driver_s *dev = &priv->dev;
+  void *buffer = dev->d_buf;
+  uint32_t len = dev->d_len;
 
-  buffer = priv->esp_dev.d_buf;
-  buffer_len = priv->esp_dev.d_len;
-  ret = esp_wifi_sta_send_data(buffer, buffer_len);
+  if (!wifi_tx_available(priv))
+    {
+      return -ENOBUFS;
+    }
 
-  if (ret != 0)
+  ret = esp_wifi_sta_send_data(buffer, len);
+  if (ret)
     {
-      wlerr("ERROR: Failed to transmit frame\n");
-      (void)wd_start(&priv->esp_txtimeout, ESP_TXTIMEOUT,
-                     esp_txtimeout_expiry, (uint32_t)priv);
+      priv->txrst = len;
+      if (buffer != priv->txbuf)
+        {
+          memcpy(priv->txbuf, buffer, len);
+        }
+
+      wd_start(&priv->txtimeout, WLAN_TXTOUT,
+               wlan_txtimeout_expiry, (uint32_t)priv);
+
       return -EIO;
     }
+  else
+    {
+      priv->txrst = 0;
+    }
 
   return OK;
 }
 
 /****************************************************************************
- * Function: esp_recvframe
+ * Function: wlan_recvframe
  *
  * Description:
- *   It scans the RX descriptors of the received frame.
+ *   Try to receive RX buffer from RX done buffer queue.
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
  *
- *   NOTE: This function will silently discard any packets containing errors.
+ * Returned Value:
+ *   RX buffer if success or NULl if no buffer in queue.
+ *
+ ****************************************************************************/
+
+static struct wlan_rxbuf *wlan_recvframe(FAR struct wlan_priv_s *priv)
+{
+  irqstate_t flags;
+  sq_entry_t *entry;
+  struct wlan_rxbuf *rxbuf = NULL;
+
+  flags = enter_critical_section();
+
+  entry = sq_remfirst(&priv->rxb);
+  if (entry)
+    {
+      rxbuf = container_of(entry, struct wlan_rxbuf, entry);
+    }
+
+  leave_critical_section(flags);
+
+  return rxbuf;
+}
+
+/****************************************************************************
+ * Name: wlan_tx_done
+ *
+ * Description:
+ *   WiFi TX done callback function. If this is called, it means sending
+ *   next packet.
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   ifidx  - The interface id that the tx callback has been triggered from.
+ *   data   - Pointer to the data transmitted.
+ *   len    - Length of the data transmitted.
+ *   status - True if data was transmitted sucessfully or false if failed.
  *
  * Returned Value:
- *   OK if a packet was successfully returned; -EAGAIN if there are no
- *   further packets available
+ *   None
  *
  ****************************************************************************/
 
-static int esp_recvframe(FAR struct esp_dev_s *priv)
+static void wlan_tx_done(uint8_t ifidx, uint8_t *data,
+                         uint16_t *len, bool status)
 {
-  struct net_driver_s *dev = &priv->esp_dev;
-  uint8_t *buffer;
-  uint32_t buffer_len = 0;
-  buffer = dev->d_buf;
-  buffer_len = dev->d_len;
-
-  /* Check if there are free buffers.  We cannot receive new frames in this
-   * design unless there is at least one free buffer.
-   */
+  FAR struct wlan_priv_s *priv = &g_wlan_priv;
 
-  if (!esp_isfreebuffer(priv))
+  wd_cancel(&priv->txtimeout);
+
+  wlan_txavail(&priv->dev);
+}
+
+/****************************************************************************
+ * Function: wlan_rx_done
+ *
+ * Description:
+ *   WiFi RX done callback function. If this is called, it means receiveing
+ *   packet.
+ *
+ * Input Parameters:
+ *   buffer - WiFi received packet buffer
+ *   len    - Length of received packet
+ *   eb     - WiFi receive callback input eb pointer
+ *
+ * Returned Value:
+ *   0 on success or a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int wlan_rx_done(void *buffer, uint16_t len, void *eb)
+{
+  struct wlan_rxbuf *rxbuf;
+  irqstate_t flags;
+  FAR struct wlan_priv_s *priv = &g_wlan_priv;
+
+  if (!priv->ifup)
+    {
+      return 0;
+    }
+
+  if (len > WLAN_BUF_SIZE)
+    {
+      nwarn("ERROR: Wlan receive %d larger than %d\n",
+             len, WLAN_BUF_SIZE);
+      return -EINVAL;
+    }
+
+  rxbuf = wlan_alloc_buffer(priv);
+  if (!rxbuf)
+    {
+      if (eb)
+        {
+          esp_wifi_free_eb(eb);
+        }
+
+      return -ENOBUFS;
+    }
+
+  memcpy(rxbuf->buffer, buffer, len);
+  rxbuf->len = len;
+
+  if (eb)
     {
-      wlerr("ERROR: No free buffers\n");
-      return -ENOMEM;
+      esp_wifi_free_eb(eb);
     }
 
-  /* Check if any errors are reported in the frame */
+  flags = enter_critical_section();
+  sq_addlast(&rxbuf->entry, &priv->rxb);
+  leave_critical_section(flags);
 
-  if (buffer == NULL || buffer_len == 0)
+  if (work_available(&priv->rxwork))
     {
-      return -EAGAIN;
+      work_queue(WLAN_WORK, &priv->rxwork, wlan_rxpoll, priv, 0);
     }
 
-  return OK;
+  return 0;
 }
 
 /****************************************************************************
- * Function: esp_receive
+ * Function: wlan_rxpoll
  *
  * Description:
- *   An event was received indicating the availability of a new RX packet
+ *   Try to receive packets from RX done queue and pass packets into IP
+ *   stack and send packets which is from IP stack if necessary.
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv - Reference to the driver state structure
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_receive(FAR struct esp_dev_s *priv)
+static void wlan_rxpoll(FAR void *arg)
 {
-  struct net_driver_s *dev = &priv->esp_dev;
+  struct wlan_rxbuf *rxbuf;
+  struct eth_hdr_s *eth_hdr;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg;
+  FAR struct net_driver_s *dev = &priv->dev;
+#ifdef WLAN_RX_THRESHOLD
+  uint32_t rbytes = 0;
+#endif
 
-  /* Loop while while esp_recvframe() successfully retrieves valid
+  /* Loop while while wlan_recvframe() successfully retrieves valid
    * Ethernet frames.
    */
 
-  while (esp_recvframe(priv) == OK)
+  net_lock();
+
+  while ((rxbuf = wlan_recvframe(priv)) != NULL)
     {
+      dev->d_buf = rxbuf->buffer;
+      dev->d_len = rxbuf->len;
+
+#ifdef WLAN_RX_THRESHOLD
+      rbytes += rxbuf->len;
+#endif
+
 #ifdef CONFIG_NET_PKT
 
       /* When packet sockets are enabled,
        * feed the frame into the packet tap.
        */
 
-      pkt_input(&priv->esp_dev);
+      pkt_input(&priv->dev);
 #endif
 
       /* Check if the packet is a valid size for the network
        * buffer configuration (this should not happen)
        */
 
-      if (dev->d_len > CONFIG_NET_ETH_PKTSIZE)
+      if (dev->d_len > WLAN_BUF_SIZE)
         {
-          wlwarn("WARNING: DROPPED Too big: %d\n", dev->d_len);
+          nwarn("WARNING: DROPPED Too big: %d\n", dev->d_len);
 
           /* Free dropped packet buffer */
 
           if (dev->d_buf)
             {
-              esp_freebuffer(priv, dev->d_buf);
+              wlan_free_buffer(priv, dev->d_buf);
               dev->d_buf = NULL;
               dev->d_len = 0;
             }
@@ -428,110 +600,112 @@ static void esp_receive(FAR struct esp_dev_s *priv)
           continue;
         }
 
+      eth_hdr = (struct eth_hdr_s *)dev->d_buf;
+
       /* We only accept IP packets of the configured type and ARP packets */
 
 #ifdef CONFIG_NET_IPv4
-      if (BUF->type == HTONS(ETHTYPE_IP))
+      if (eth_hdr->type == HTONS(ETHTYPE_IP))
         {
-          wlinfo("IPv4 frame\n");
+          ninfo("IPv4 frame\n");
 
           /* Handle ARP on input then give the IPv4 packet to the network
            * layer
            */
 
-          arp_ipin(&priv->esp_dev);
-          ipv4_input(&priv->esp_dev);
+          arp_ipin(&priv->dev);
+          ipv4_input(&priv->dev);
 
           /* If the above function invocation resulted in data
            * that should be sent out on the network,
            * the field  d_len will set to a value > 0.
            */
 
-          if (priv->esp_dev.d_len > 0)
+          if (priv->dev.d_len > 0)
             {
               /* Update the Ethernet header with the correct MAC address */
 
 #ifdef CONFIG_NET_IPv6
-              if (IFF_IS_IPv4(priv->esp_dev.d_flags))
+              if (IFF_IS_IPv4(priv->dev.d_flags))
 #endif
                 {
-                  arp_out(&priv->esp_dev);
+                  arp_out(&priv->dev);
                 }
 #ifdef CONFIG_NET_IPv6
               else
                 {
-                  neighbor_out(&priv->esp_dev);
+                  neighbor_out(&priv->dev);
                 }
 #endif
 
               /* And send the packet */
 
-              esp_transmit(priv);
+              wlan_transmit(priv);
             }
         }
       else
 #endif
 #ifdef CONFIG_NET_IPv6
-      if (BUF->type == HTONS(ETHTYPE_IP6))
+      if (eth_hdr->type == HTONS(ETHTYPE_IP6))
         {
-          wlinfo("Iv6 frame\n");
+          ninfo("IPv6 frame\n");
 
           /* Give the IPv6 packet to the network layer */
 
-          ipv6_input(&priv->esp_dev);
+          ipv6_input(&priv->dev);
 
           /* If the above function invocation resulted in data
            * that should be sent out on the network, the field
            * d_len will set to a value > 0.
            */
 
-          if (priv->esp_dev.d_len > 0)
+          if (priv->dev.d_len > 0)
             {
               /* Update the Ethernet header with the correct MAC address */
 
 #ifdef CONFIG_NET_IPv4
-              if (IFF_IS_IPv4(priv->esp_dev.d_flags))
+              if (IFF_IS_IPv4(priv->dev.d_flags))
                 {
-                  arp_out(&priv->esp_dev);
+                  arp_out(&priv->dev);
                 }
               else
 #endif
 #ifdef CONFIG_NET_IPv6
                 {
-                  neighbor_out(&priv->esp_dev);
+                  neighbor_out(&priv->dev);
                 }
 #endif
 
               /* And send the packet */
 
-              esp_transmit(priv);
+              wlan_transmit(priv);
             }
         }
       else
 #endif
 #ifdef CONFIG_NET_ARP
-      if (BUF->type == htons(ETHTYPE_ARP))
+      if (eth_hdr->type == htons(ETHTYPE_ARP))
         {
-          wlinfo("ARP frame\n");
+          ninfo("ARP frame\n");
 
           /* Handle ARP packet */
 
-          arp_arpin(&priv->esp_dev);
+          arp_arpin(&priv->dev);
 
           /* If the above function invocation resulted in data
            * that should be sent out on the network, the field
            * d_len will set to a value > 0.
            */
 
-          if (priv->esp_dev.d_len > 0)
+          if (priv->dev.d_len > 0)
             {
-              esp_transmit(priv);
+              wlan_transmit(priv);
             }
         }
       else
 #endif
         {
-          wlinfo("INFO: Dropped, Unknown type: %04x\n", BUF->type);
+          ninfo("INFO: Dropped, Unknown type: %04x\n", eth_hdr->type);
         }
 
       /* We are finished with the RX buffer.  NOTE:  If the buffer is
@@ -543,15 +717,32 @@ static void esp_receive(FAR struct esp_dev_s *priv)
         {
           /* Free the receive packet buffer */
 
-          esp_freebuffer(priv, dev->d_buf);
+          wlan_free_buffer(priv, dev->d_buf);
           dev->d_buf = NULL;
           dev->d_len = 0;
         }
+
+#ifdef WLAN_RX_THRESHOLD
+      /**
+       * If received total bytes is larger than receive threshold,
+       * then do "unlock" to try to active applicantion to receive
+       * data from low-level buffer of IP stack.
+       */
+
+      if (rbytes >= WLAN_RX_THRESHOLD)
+        {
+          net_unlock();
+          rbytes = 0;
+          net_lock();
+        }
+#endif
     }
+
+    net_unlock();
 }
 
 /****************************************************************************
- * Name: esp_txpoll
+ * Name: wlan_txpoll
  *
  * Description:
  *   The transmitter is available, check if the network has any outgoing
@@ -570,17 +761,17 @@ static void esp_receive(FAR struct esp_dev_s *priv)
  *
  ****************************************************************************/
 
-static int esp_txpoll(FAR struct net_driver_s *dev)
+static int wlan_txpoll(FAR struct net_driver_s *dev)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
-  DEBUGASSERT(priv->esp_dev.d_buf != NULL);
+  DEBUGASSERT(dev->d_buf != NULL);
 
   /* If the polling resulted in data that should be sent out on the network,
    * the field d_len is set to a value > 0.
    */
 
-  if (priv->esp_dev.d_len > 0)
+  if (dev->d_len > 0)
     {
       /* Look up the destination MAC address and add it to the Ethernet
        * header.
@@ -588,10 +779,10 @@ static int esp_txpoll(FAR struct net_driver_s *dev)
 
 #ifdef CONFIG_NET_IPv4
 #ifdef CONFIG_NET_IPv6
-      if (IFF_IS_IPv4(priv->esp_dev.d_flags))
+      if (IFF_IS_IPv4(dev->d_flags))
 #endif
         {
-          arp_out(&priv->esp_dev);
+          arp_out(dev);
         }
 #endif /* CONFIG_NET_IPv4 */
 
@@ -600,20 +791,14 @@ static int esp_txpoll(FAR struct net_driver_s *dev)
       else
 #endif
         {
-          neighbor_out(&priv->esp_dev);
+          neighbor_out(dev);
         }
 #endif /* CONFIG_NET_IPv6 */
 
-      if (!devif_loopback(&priv->esp_dev))
+      int ret = wlan_transmit(priv);
+      if (ret)
         {
-          /* Send the packet */
-
-          int ret = esp_transmit(priv);
-          if (ret != OK)
-            {
-              wlerr("TX failed\r\n");
-              return -EBUSY;
-            }
+          return -EBUSY;
         }
     }
 
@@ -625,187 +810,44 @@ static int esp_txpoll(FAR struct net_driver_s *dev)
 }
 
 /****************************************************************************
- * Name: esp_rxpoll
- *
- * Description:
- *   Process RX frames
- *
- * Input Parameters:
- *   arg - context of device to use
- *
- * Returned Value:
- *   OK on success
- *
- * Assumptions:
- *   The network is locked.
- *
- ****************************************************************************/
-
-static void esp_rxpoll(FAR void *arg)
-{
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)arg;
-
-  if (priv->esp_dev.d_buf == NULL)
-    {
-      priv->esp_dev.d_buf = priv->rxbuf;
-      priv->esp_dev.d_len = priv->rx_len;
-    }
-  else
-    {
-      wlinfo("priv->esp_dev.d_buf != NULL");
-      return;
-    }
-
-  /* Lock the network and serialize driver operations if necessary.
-   * NOTE: Serialization is only required in the case where the driver work
-   * is performed on an LP worker thread and where more than one LP worker
-   * thread has been configured.
-   */
-
-  net_lock();
-
-  esp_receive(priv);
-
-  if (priv->esp_dev.d_buf)
-    {
-      priv->esp_dev.d_buf = NULL;
-      memset(priv->rxbuf, 0x0, sizeof(priv->rxbuf));
-      priv->rx_len = 0;
-    }
-
-  net_unlock();
-}
-
-/****************************************************************************
- * Function: esp_dopoll
+ * Function: wlan_dopoll
  *
  * Description:
  *   The function is called in order to perform an out-of-sequence TX poll.
  *   This is done:
  *
- *   1. When new TX data is available (esp_txavail), and
+ *   1. When new TX data is available (wlan_txavail)
  *   2. After a TX timeout to restart the sending process
- *      (esp_txtimeout_expiry).
+ *      (wlan_txtimeout_expiry).
  *
  * Input Parameters:
- *   priv  - Reference to the driver state structure
+ *   priv - Reference to the driver state structure
  *
  * Returned Value:
  *   None
  *
  ****************************************************************************/
 
-static void esp_dopoll(FAR struct esp_dev_s *priv)
+static void wlan_dopoll(FAR struct wlan_priv_s *priv)
 {
-  FAR struct net_driver_s *dev = &priv->esp_dev;
+  FAR struct net_driver_s *dev = &priv->dev;
 
-  if (g_tx_ready == true)
-    {
-      /* Check if there is room in the hardware to
-       * hold another outgoing packet.
-       */
-
-      dev->d_buf = esp_allocbuffer(priv);
-
-      /* We can't poll if we have no buffers */
-
-      if (dev->d_buf)
-        {
-          /* If so, then poll the network for new XMIT data */
-
-          (void)devif_poll(dev, esp_txpoll);
-
-          /* We will, most likely end up with a buffer to be freed.
-           * But it might not be the same one that we allocated above.
-           */
-
-          if (dev->d_buf)
-            {
-              esp_freebuffer(priv, dev->d_buf);
-              dev->d_buf = NULL;
-            }
-        }
-      else
-        {
-          wlerr("Alloc buffer error");
-        }
-    }
-  else
+  if (!wifi_tx_available(priv))
     {
-      wlwarn("Tx is not ready");
+      return ;
     }
-}
 
-/****************************************************************************
- * Name: esp_netdev_notify_rx
- *
- * Description:
- *   Notify callback called when RX frame is available
- *
- * Input Parameters:
- *   priv   - Reference to the driver state structure
- *   buffer - Receive buffer
- *   len    - Length of receive buffer
- *
- * Returned Value:
- *   None
- *
- ****************************************************************************/
+  dev->d_buf = priv->txbuf;
 
-static void esp_netdev_notify_rx(FAR struct esp_dev_s *priv,
-                                 void *buffer, uint16_t len)
-{
-  struct esp_dev_s *priv_dev = priv;
+  /* If so, then poll the network for new XMIT data */
 
-  memcpy(priv_dev->rxbuf, buffer, len);
-  priv_dev->rx_len = len;
-  work_queue(ESPWORK, &priv_dev->esp_irqwork, esp_rxpoll, priv_dev, 0);
-}
+  devif_poll(dev, wlan_txpoll);
 
-/****************************************************************************
- * Function: esp_sta_input
- *
- * Description:
- *   This function should be called when a packet is ready to be read
- *   from the interface. It uses the function low_level_input() that
- *   should handle the actual reception of bytes from the network
- *   interface. Then the type of the received packet is determined and
- *   the appropriate input function is called.
- *
- * Input Parameters:
- *   buffer - WiFi receive buffer
- *   len    - Length of receive buffer
- *   eb     - WiFi receive callback input eb pointer
- *
- * Returned Value:
- *   OK on success; a negated errno on failure
- *
- ****************************************************************************/
-
-static int esp_sta_input(void *buffer, uint16_t len, void *eb)
-{
-  FAR struct esp_dev_s *priv = &s_esp32_dev;
-
-  if (!buffer || (priv->ifup == false))
-    {
-      if (eb)
-        {
-          esp_wifi_free_eb(eb);
-        }
-
-      return -1;
-    }
-  else
-    {
-      esp_netdev_notify_rx(priv, buffer, len);
-    }
-
-  esp_wifi_free_eb(eb);
-  return 0;
+  dev->d_buf = NULL;
 }
 
 /****************************************************************************
- * Function: esp_txtimeout_work
+ * Function: wlan_txtimeout_work
  *
  * Description:
  *   Perform TX timeout related work from the worker thread
@@ -818,24 +860,24 @@ static int esp_sta_input(void *buffer, uint16_t len, void *eb)
  *
  ****************************************************************************/
 
-static void esp_txtimeout_work(void *arg)
+static void wlan_txtimeout_work(void *arg)
 {
-  struct esp_dev_s *priv = (struct esp_dev_s *)arg;
-
-  /* Reset the hardware.  Just take the interface down, then back up again. */
+  struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
 
   net_lock();
-  esp_ifdown(&priv->esp_dev);
-  esp_ifup(&priv->esp_dev);
+
+  wlan_ifdown(&priv->dev);
+  wlan_ifup(&priv->dev);
 
   /* Then poll for new XMIT data */
 
-  esp_dopoll(priv);
+  wlan_dopoll(priv);
+
   net_unlock();
 }
 
 /****************************************************************************
- * Function: esp_txtimeout_expiry
+ * Function: wlan_txtimeout_expiry
  *
  * Description:
  *   Our TX watchdog timed out.  Called from the timer callback handler.
@@ -850,19 +892,20 @@ static void esp_txtimeout_work(void *arg)
  *
  ****************************************************************************/
 
-static void esp_txtimeout_expiry(wdparm_t arg)
+static void wlan_txtimeout_expiry(wdparm_t arg)
 {
-  struct esp_dev_s *priv = (struct esp_dev_s *)arg;
-  wlinfo("Timeout!\n");
+  struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
 
   /* Schedule to perform the TX timeout processing on the worker thread. */
 
-  DEBUGASSERT(work_available(&priv->esp_irqwork));
-  work_queue(ESPWORK, &priv->esp_irqwork, esp_txtimeout_work, priv, 0);
+  if (work_available(&priv->toutwork))
+    {
+      work_queue(WLAN_WORK, &priv->toutwork, wlan_txtimeout_work, priv, 0);
+    }
 }
 
 /****************************************************************************
- * Name: esp_poll_work
+ * Name: wlan_poll_work
  *
  * Description:
  *   Perform periodic polling from the worker thread
@@ -878,10 +921,11 @@ static void esp_txtimeout_expiry(wdparm_t arg)
  *
  ****************************************************************************/
 
-static void esp_poll_work(FAR void *arg)
+static void wlan_poll_work(FAR void *arg)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)arg;
-  struct net_driver_s *dev  = &priv->esp_dev;
+  int32_t delay = WLAN_WDDELAY;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg;
+  struct net_driver_s *dev = &priv->dev;
 
   /* Lock the network and serialize driver operations if necessary.
    * NOTE: Serialization is only required in the case where the driver work
@@ -893,45 +937,33 @@ static void esp_poll_work(FAR void *arg)
 
   /* Check if there is room in the send another TX packet.  We cannot perform
    * the TX poll if he are unable to accept another packet for transmission.
+   *
+   * If there is no room, we should reset the timeout value to be 1 to
+   * trigger the timer as soon as possible.
    */
 
-  if (g_tx_ready == true)
+  if (!wifi_tx_available(priv))
     {
-      dev->d_buf = esp_allocbuffer(priv);
+      delay = 1;
+      goto exit;
+    }
 
-      /* We can't poll if we have no buffers */
+  dev->d_buf = priv->txbuf;
 
-      if (dev->d_buf)
-        {
-          /* Update TCP timing states and poll
-           * the network for new XMIT data.
-           */
+  /* Update TCP timing states and poll the network for new XMIT data. */
 
-          (void)devif_timer(&priv->esp_dev, ESP_WDDELAY, esp_txpoll);
+  devif_timer(&priv->dev, delay, wlan_txpoll);
 
-          /* We will, most likely end up with a buffer to be freed.
-           * But it might not be the same one that we allocated above.
-           */
+  dev->d_buf = NULL;
 
-          if (dev->d_buf)
-            {
-              esp_freebuffer(priv, dev->d_buf);
-              dev->d_buf = NULL;
-            }
-        }
-      else
-        {
-          wlerr("ERROR: Failed to TX pkt");
-        }
-    }
+exit:
+  wd_start(&priv->txpoll, delay, wlan_poll_expiry, (wdparm_t)priv);
 
-  wd_start(&priv->esp_txpoll, ESP_WDDELAY, esp_poll_expiry,
-          (wdparm_t)priv);
   net_unlock();
 }
 
 /****************************************************************************
- * Name: esp_poll_expiry
+ * Name: wlan_poll_expiry
  *
  * Description:
  *   Periodic timer handler.  Called from the timer callback handler.
@@ -945,15 +977,59 @@ static void esp_poll_work(FAR void *arg)
  *
  ****************************************************************************/
 
-static void esp_poll_expiry(wdparm_t arg)
+static void wlan_poll_expiry(wdparm_t arg)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)arg;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg;
 
-  work_queue(ESPWORK, &priv->esp_pollwork, esp_poll_work, priv, 0);
+  if (priv->ifup)
+    {
+      work_queue(WLAN_WORK, &priv->pollwork, wlan_poll_work, priv, 0);
+    }
 }
 
 /****************************************************************************
- * Name: esp_ifup
+ * Name: wlan_txavail_work
+ *
+ * Description:
+ *   Perform an out-of-cycle poll on the worker thread.
+ *
+ * Input Parameters:
+ *   arg - Reference to the NuttX driver state structure (cast to void*)
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called on the higher priority worker thread.
+ *
+ ****************************************************************************/
+
+static void wlan_txavail_work(FAR void *arg)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg;
+
+  /* Lock the network and serialize driver operations if necessary.
+   * NOTE: Serialization is only required in the case where the driver work
+   * is performed on an LP worker thread and where more than one LP worker
+   * thread has been configured.
+   */
+
+  net_lock();
+
+  /* Ignore the notification if the interface is not yet up */
+
+  if (priv->ifup)
+    {
+      /* Poll the network for new XMIT data */
+
+      wlan_dopoll(priv);
+    }
+
+  net_unlock();
+}
+
+/****************************************************************************
+ * Name: wlan_ifup
  *
  * Description:
  *   NuttX Callback: Bring up the Ethernet interface when an IP address is
@@ -967,12 +1043,12 @@ static void esp_poll_expiry(wdparm_t arg)
  *
  ****************************************************************************/
 
-static int esp_ifup(FAR struct net_driver_s *dev)
+static int wlan_ifup(FAR struct net_driver_s *dev)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
 #ifdef CONFIG_NET_IPv4
-  wlinfo("Bringing up: %d.%d.%d.%d\n",
+  ninfo("Bringing up: %d.%d.%d.%d\n",
         dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
         (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24);
 #endif
@@ -983,29 +1059,36 @@ static int esp_ifup(FAR struct net_driver_s *dev)
         dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
 #endif
 
+  net_lock();
+
+  if (priv->ifup)
+    {
+      net_unlock();
+      return OK;
+    }
+
 #ifdef CONFIG_NET_ICMPv6
 
   /* Set up IPv6 multicast address filtering */
 
-  esp_ipv6multicast(priv);
+  wlan_ipv6multicast(priv);
 #endif
 
-  /* Initialize the free buffer list */
-
-  esp_initbuffer(priv);
+  wlan_init_buffer(priv);
 
   /* Set and activate a timer process */
 
-  (void)wd_start(&priv->esp_txpoll, ESP_WDDELAY, esp_poll_expiry,
-                (wdparm_t)priv);
+  wd_start(&priv->txpoll, WLAN_WDDELAY, wlan_poll_expiry, (wdparm_t)priv);
 
   priv->ifup = true;
 
+  net_unlock();
+
   return OK;
 }
 
 /****************************************************************************
- * Name: esp_ifdown
+ * Name: wlan_ifdown
  *
  * Description:
  *   NuttX Callback: Stop the interface.
@@ -1018,69 +1101,34 @@ static int esp_ifup(FAR struct net_driver_s *dev)
  *
  ****************************************************************************/
 
-static int esp_ifdown(FAR struct net_driver_s *dev)
+static int wlan_ifdown(FAR struct net_driver_s *dev)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
-  irqstate_t flags;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
-  flags = enter_critical_section();
+  net_lock();
+
+  if (!priv->ifup)
+    {
+      net_unlock();
+      return OK;
+    }
 
   /* Cancel the TX poll timer and TX timeout timers */
 
-  wd_cancel(&priv->esp_txpoll);
-  wd_cancel(&priv->esp_txtimeout);
+  wd_cancel(&priv->txpoll);
+  wd_cancel(&priv->txtimeout);
 
   /* Mark the device "down" */
 
   priv->ifup = false;
-  leave_critical_section(flags);
-
-  return OK;
-}
-
-/****************************************************************************
- * Name: esp_txavail_work
- *
- * Description:
- *   Perform an out-of-cycle poll on the worker thread.
- *
- * Input Parameters:
- *   arg - Reference to the NuttX driver state structure (cast to void*)
- *
- * Returned Value:
- *   None
- *
- * Assumptions:
- *   Called on the higher priority worker thread.
- *
- ****************************************************************************/
-
-static void esp_txavail_work(FAR void *arg)
-{
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)arg;
-
-  /* Lock the network and serialize driver operations if necessary.
-   * NOTE: Serialization is only required in the case where the driver work
-   * is performed on an LP worker thread and where more than one LP worker
-   * thread has been configured.
-   */
-
-  net_lock();
-
-  /* Ignore the notification if the interface is not yet up */
-
-  if (priv->ifup)
-    {
-      /* Poll the network for new XMIT data */
-
-      esp_dopoll(priv);
-    }
 
   net_unlock();
+
+  return OK;
 }
 
 /****************************************************************************
- * Name: esp_txavail
+ * Name: wlan_txavail
  *
  * Description:
  *   Driver callback invoked when new TX data is available.  This is a
@@ -1098,22 +1146,22 @@ static void esp_txavail_work(FAR void *arg)
  *
  ****************************************************************************/
 
-static int esp_txavail(FAR struct net_driver_s *dev)
+static int wlan_txavail(FAR struct net_driver_s *dev)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
-  if (work_available(&priv->esp_pollwork))
+  if (work_available(&priv->txwork))
     {
       /* Schedule to serialize the poll on the worker thread. */
 
-      work_queue(ESPWORK, &priv->esp_pollwork, esp_txavail_work, priv, 0);
+      work_queue(WLAN_WORK, &priv->txwork, wlan_txavail_work, priv, 0);
     }
 
   return OK;
 }
 
 /****************************************************************************
- * Name: esp_addmac
+ * Name: wlan_addmac
  *
  * Description:
  *   NuttX Callback: Add the specified MAC address to the hardware multicast
@@ -1129,9 +1177,9 @@ static int esp_txavail(FAR struct net_driver_s *dev)
  ****************************************************************************/
 
 #if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
-static int esp_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
+static int wlan_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
   /* Add the MAC address to the hardware multicast routing table */
 
@@ -1140,7 +1188,7 @@ static int esp_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
 #endif
 
 /****************************************************************************
- * Name: esp_rmmac
+ * Name: wlan_rmmac
  *
  * Description:
  *   NuttX Callback: Remove the specified MAC address from the
@@ -1156,9 +1204,9 @@ static int esp_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
  ****************************************************************************/
 
 #ifdef CONFIG_NET_MCASTGROUP
-static int esp_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
+static int wlan_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
 {
-  FAR struct esp_dev_s *priv = (FAR struct esp_dev_s *)dev->d_private;
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
 
   /* Add the MAC address to the hardware multicast routing table */
 
@@ -1167,7 +1215,7 @@ static int esp_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
 #endif
 
 /****************************************************************************
- * Name: esp_ipv6multicast
+ * Name: wlan_ipv6multicast
  *
  * Description:
  *   Configure the IPv6 multicast MAC address.
@@ -1181,7 +1229,7 @@ static int esp_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
  ****************************************************************************/
 
 #ifdef CONFIG_NET_ICMPv6
-static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
+static void wlan_ipv6multicast(FAR struct wlan_priv_s *priv)
 {
   FAR struct net_driver_s *dev;
   uint16_t tmp16;
@@ -1202,7 +1250,7 @@ static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
   mac[0] = 0x33;
   mac[1] = 0x33;
 
-  dev    = &priv->esp_dev;
+  dev    = &priv->dev;
   tmp16  = dev->d_ipv6addr[6];
   mac[2] = 0xff;
   mac[3] = tmp16 >> 8;
@@ -1211,10 +1259,10 @@ static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
   mac[4] = tmp16 & 0xff;
   mac[5] = tmp16 >> 8;
 
-  wlinfo("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n",
+  ninfo("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n",
         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
 
-  esp_addmac(dev, mac);
+  wlan_addmac(dev, mac);
 
 #ifdef CONFIG_NET_ICMPv6_AUTOCONF
   /* Add the IPv6 all link-local nodes Ethernet address.  This is the
@@ -1222,7 +1270,7 @@ static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
    * packets.
    */
 
-  esp_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet);
+  wlan_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet);
 #endif /* CONFIG_NET_ICMPv6_AUTOCONF */
 
 #ifdef CONFIG_NET_ICMPv6_ROUTER
@@ -1231,13 +1279,13 @@ static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
    * packets.
    */
 
-  esp_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet);
+  wlan_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet);
 #endif /* CONFIG_NET_ICMPv6_ROUTER */
 }
 #endif /* CONFIG_NET_ICMPv6 */
 
 /****************************************************************************
- * Name: esp_ioctl
+ * Name: wlan_ioctl
  *
  * Description:
  *   Handle network IOCTL commands directed to this device.
@@ -1253,8 +1301,9 @@ static void esp_ipv6multicast(FAR struct esp_dev_s *priv)
  ****************************************************************************/
 
 #ifdef CONFIG_NETDEV_IOCTL
-static int esp_ioctl(FAR struct net_driver_s *dev,
-                     int cmd, unsigned long arg)
+static int wlan_ioctl(FAR struct net_driver_s *dev,
+                      int cmd,
+                      unsigned long arg)
 {
   int ret;
   struct iw_point *essid;
@@ -1273,7 +1322,7 @@ static int esp_ioctl(FAR struct net_driver_s *dev,
           ret = esp_wifi_notify_subscribe(req->pid, &req->event);
           if (ret)
             {
-              wlerr("ERROR: Failed to subscribe event\n");
+              nerr("ERROR: Failed to subscribe event\n");
             }
         }
         break;
@@ -1286,7 +1335,7 @@ static int esp_ioctl(FAR struct net_driver_s *dev,
           ret = esp_wifi_set_password(ext->key, ext->key_len);
           if (ret)
             {
-              wlerr("ERROR: Failed to set password\n");
+              nerr("ERROR: Failed to set password\n");
             }
         }
         break;
@@ -1297,20 +1346,16 @@ static int esp_ioctl(FAR struct net_driver_s *dev,
           ret = esp_wifi_set_ssid(essid->pointer, essid->length);
           if (ret)
             {
-              wlerr("ERROR: Failed to set SSID\n");
+              nerr("ERROR: Failed to set SSID\n");
               break;
             }
 
           ret = esp_wifi_connect_internal();
           if (ret)
             {
-              wlerr("ERROR: Failed to start connecting\n");
+              nerr("ERROR: Failed to start connecting\n");
               break;
             }
-          else
-            {
-              g_tx_ready = true;
-            }
         }
         break;
       case SIOCSIWMODE:
@@ -1319,8 +1364,11 @@ static int esp_ioctl(FAR struct net_driver_s *dev,
       case SIOCSIWAUTH:
         ret = OK;
         break;
+      case SIOCSIWFREQ:
+        ret = OK;
+        break;
       default:
-        wlerr("ERROR: Unrecognized IOCTL command: %d\n", cmd);
+        nerr("ERROR: Unrecognized IOCTL command: %d\n", cmd);
         ret = -ENOTTY;  /* Special return value for this case */
         break;
     }
@@ -1347,59 +1395,71 @@ static int esp32_net_initialize(unsigned int devno)
 {
   int ret;
   uint8_t eth_mac[6];
-  FAR struct esp_dev_s *priv;
+  FAR struct wlan_priv_s *priv;
 
   /* Get the interface structure associated with this interface number. */
 
-  priv = &s_esp32_dev;
+  priv = &g_wlan_priv;
 
   /* Initialize the driver structure */
 
-  memset(priv, 0, sizeof(struct esp_dev_s));
+  memset(priv, 0, sizeof(struct wlan_priv_s));
 
-  priv->esp_dev.d_ifup    = esp_ifup;     /* I/F down callback */
-  priv->esp_dev.d_ifdown  = esp_ifdown;   /* I/F up (new IP address) callback */
-  priv->esp_dev.d_txavail = esp_txavail;  /* New TX data callback */
+  priv->dev.d_ifup    = wlan_ifup;     /* I/F down callback */
+  priv->dev.d_ifdown  = wlan_ifdown;   /* I/F up (new IP address) callback */
+  priv->dev.d_txavail = wlan_txavail;  /* New TX data callback */
 #ifdef CONFIG_NET_MCASTGROUP
-  priv->esp_dev.d_addmac  = esp_addmac;   /* Add multicast MAC address */
-  priv->esp_dev.d_rmmac   = esp_rmmac;    /* Remove multicast MAC address */
+  priv->dev.d_addmac  = wlan_addmac;   /* Add multicast MAC address */
+  priv->dev.d_rmmac   = wlan_rmmac;    /* Remove multicast MAC address */
 #endif
 #ifdef CONFIG_NETDEV_IOCTL
-  priv->esp_dev.d_ioctl   = esp_ioctl;    /* Handle network IOCTL commands */
+  priv->dev.d_ioctl   = wlan_ioctl;    /* Handle network IOCTL commands */
 #endif
 
   /* Used to recover private state from dev */
 
-  priv->esp_dev.d_private = (void *)&s_esp32_dev;
+  priv->dev.d_private = (void *)&g_wlan_priv;
 
   /* Create a watchdog for timing polling for and timing of transmissions */
 
-  /* Initialize network stack interface buffer */
+  esp_wifi_sta_read_mac(eth_mac);
 
-  priv->esp_dev.d_buf     = NULL;
-  g_tx_ready = false;
+  memcpy(priv->dev.d_mac.ether.ether_addr_octet, eth_mac, sizeof(eth_mac));
 
-  assert(esp_wifi_adapter_init() == 0);
-  esp_wifi_sta_register_recv_cb(esp_sta_input);
+  ninfo("%02X:%02X:%02X:%02X:%02X:%02X \r\n",
+        eth_mac[0], eth_mac[1], eth_mac[2],
+        eth_mac[3], eth_mac[4], eth_mac[5]);
 
-  /* Register the device with the OS so that socket IOCTLs can be performed */
+  /* Put the interface in the down state. */
 
-  esp_wifi_sta_read_mac(priv->esp_dev.d_mac.ether.ether_addr_octet);
-  memcpy(eth_mac, priv->esp_dev.d_mac.ether.ether_addr_octet,
-         sizeof(eth_mac));
-  wlinfo("%02X:%02X:%02X:%02X:%02X:%02X \r\n", eth_mac[0], eth_mac[1],
-                       eth_mac[2], eth_mac[3], eth_mac[4], eth_mac[5]);
+  wlan_ifdown(&priv->dev);
 
-  /* Put the interface in the down state. */
+  ret = netdev_register(&priv->dev, NET_LL_IEEE80211);
+  if (ret)
+    {
+      nerr("ERROR: Initialization of Ethernet block failed: %d\n", ret);
+      return ret;
+    }
 
-  ret = esp_ifdown(&priv->esp_dev);
-  if (ret < 0)
+  ret = esp_wifi_adapter_init();
+  if (ret)
     {
-      wlerr("ERROR: Initialization of Ethernet block failed: %d\n", ret);
+      nerr("ERROR: Initialize WiFi adapter error: %d\n", ret);
+      netdev_unregister(&priv->dev);
       return ret;
     }
 
-  (void)netdev_register(&s_esp32_dev.esp_dev, NET_LL_IEEE80211);
+  ret = esp_wifi_sta_register_recv_cb(wlan_rx_done);
+  if (ret)
+    {
+      DEBUGASSERT(0);
+    }
+
+  ret = esp_wifi_sta_register_txdone_cb(wlan_tx_done);
+  if (ret)
+    {
+      DEBUGASSERT(0);
+    }
 
   return OK;
 }
@@ -1409,10 +1469,10 @@ static int esp32_net_initialize(unsigned int devno)
  ****************************************************************************/
 
 /****************************************************************************
- * Name: esp32_wlan_initialize
+ * Name: esp32_wlan_sta_initialize
  *
  * Description:
- *   Initialize the esp32 wlan driver
+ *   Initialize the esp32 WLAN station netcard driver
  *
  * Input Parameters:
  *   None
@@ -1422,9 +1482,9 @@ static int esp32_net_initialize(unsigned int devno)
  *
  ****************************************************************************/
 
-int esp32_wlan_initialize(void)
+int esp32_wlan_sta_initialize(void)
 {
-  return esp32_net_initialize(STA_DEVNO);
+  return esp32_net_initialize(WLAN_STA_DEVNO);
 }
 
 #endif  /* CONFIG_ESP32_WIRELESS */
diff --git a/arch/xtensa/src/esp32/esp32_wlan.h b/arch/xtensa/src/esp32/esp32_wlan.h
index f9633a9..ce49227 100644
--- a/arch/xtensa/src/esp32/esp32_wlan.h
+++ b/arch/xtensa/src/esp32/esp32_wlan.h
@@ -45,10 +45,10 @@ extern "C"
  ****************************************************************************/
 
 /****************************************************************************
- * Name: esp32_wlan_initialize
+ * Name: esp32_wlan_sta_initialize
  *
  * Description:
- *   Initialize the esp32 wlan driver
+ *   Initialize the esp32 WLAN station netcard driver
  *
  * Input Parameters:
  *   None
@@ -56,11 +56,9 @@ extern "C"
  * Returned Value:
  *   OK on success; Negated errno on failure.
  *
- * Assumptions:
- *
  ****************************************************************************/
 
-int esp32_wlan_initialize(void);
+int esp32_wlan_sta_initialize(void);
 
 #endif /* CONFIG_ESP32_WIRELESS */
 #ifdef __cplusplus
diff --git a/arch/xtensa/src/esp32/hardware/esp32_dport.h b/arch/xtensa/src/esp32/hardware/esp32_dport.h
index d5a74be..173c6b0 100644
--- a/arch/xtensa/src/esp32/hardware/esp32_dport.h
+++ b/arch/xtensa/src/esp32/hardware/esp32_dport.h
@@ -1223,6 +1223,7 @@
 /* DPORT_WIFI_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
 
 #define DPORT_EMAC_RST_EN              (BIT(7))
+#define DPORT_MAC_RST_EN               (BIT(2))
 
 #define DPORT_WIFI_RST  0xFFFFFFFF
 #define DPORT_WIFI_RST_M  ((DPORT_WIFI_RST_V)<<(DPORT_WIFI_RST_S))
diff --git a/boards/xtensa/esp32/esp32-core/src/esp32_bringup.c b/boards/xtensa/esp32/esp32-core/src/esp32_bringup.c
index d3caff8..abdbb7c 100644
--- a/boards/xtensa/esp32/esp32-core/src/esp32_bringup.c
+++ b/boards/xtensa/esp32/esp32-core/src/esp32_bringup.c
@@ -207,7 +207,7 @@ int esp32_bringup(void)
 #endif
 
 #ifdef CONFIG_NET
-  ret = esp32_wlan_initialize();
+  ret = esp32_wlan_sta_initialize();
   if (ret)
     {
       syslog(LOG_ERR, "ERROR: Failed to initialize WiFi\n");