diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig
index ce24e1c2e6..914de17ea3 100644
--- a/arch/risc-v/Kconfig
+++ b/arch/risc-v/Kconfig
@@ -45,6 +45,11 @@ config ARCH_CHIP_ESP32C3
 	select RV32IM_HW_MULDIV
 	select ARCH_VECNOTIRQ
 	select ARCH_HAVE_RESET
+	select LIBC_ARCH_MEMCHR
+	select LIBC_ARCH_MEMCMP
+	select LIBC_ARCH_MEMCCMP
+	select LIBC_ARCH_MEMMOVE
+	select LIBC_ARCH_MEMSET
 	---help---
 		Espressif ESP32-C3 (RV32IMC).
 
diff --git a/arch/risc-v/include/esp32c3/irq.h b/arch/risc-v/include/esp32c3/irq.h
index 27a7eb173e..ad6634af63 100644
--- a/arch/risc-v/include/esp32c3/irq.h
+++ b/arch/risc-v/include/esp32c3/irq.h
@@ -127,6 +127,10 @@
 #define ESP32C3_CPUINT_MIN             1
 #define ESP32C3_CPUINT_MAX             31
 
+/* Reserved CPU interrupt for specific drivers */
+
+#define ESP32C3_CPUINT_WMAC            1  /* Wi-Fi MAC */
+
 /* IRQ numbers. */
 
 /* ecall is dispatched like normal interrupts.  It occupies an IRQ number. */
diff --git a/arch/risc-v/src/esp32c3/.gitignore b/arch/risc-v/src/esp32c3/.gitignore
new file mode 100644
index 0000000000..cdf3df5616
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/.gitignore
@@ -0,0 +1,2 @@
+/esp-wireless-drivers-3rdparty
+/*.zip
diff --git a/arch/risc-v/src/esp32c3/Kconfig b/arch/risc-v/src/esp32c3/Kconfig
index cecb296af3..07573882cb 100644
--- a/arch/risc-v/src/esp32c3/Kconfig
+++ b/arch/risc-v/src/esp32c3/Kconfig
@@ -152,6 +152,10 @@ config ESP32C3_CPU_FREQ_MHZ
 	default 80 if ESP32C3_CPU_FREQ_80
 	default 160 if ESP32C3_CPU_FREQ_160
 
+config ESP32C3_RT_TIMER
+	bool "Real-time Timer"
+	default n
+
 menu "ESP32-C3 Peripheral Support"
 
 config ESP32C3_UART
@@ -235,6 +239,16 @@ config ESP32C3_RWDT
 		to have the RTC module reset, please, use the Timers' Module WDTs.
 		They will only reset Main System.
 
+config ESP32C3_WIRELESS
+	bool "Wireless"
+	default n
+	select NET
+	select ARCH_PHY_INTERRUPT
+	select ESP32C3_RT_TIMER
+	select ESP32C3_TIMER0
+	---help---
+		Enable Wireless support
+
 endmenu # ESP32-C3 Peripheral Support
 
 menu "I2C Configuration"
@@ -285,4 +299,84 @@ endif # ESP32C3_UART1
 
 endmenu
 
+menu "Real-Time Timer"
+	depends on ESP32C3_RT_TIMER
+
+config ESP32C3_RT_TIMER_TASK_NAME
+	string "Timer task name"
+	default "rt_timer"
+
+config ESP32C3_RT_TIMER_TASK_PRIORITY
+	int "Timer task priority"
+	default 223 # Lower than high priority workqueue
+
+config ESP32C3_RT_TIMER_TASK_STACK_SIZE
+	int "Timer task stack size"
+	default 2048
+
+endmenu # Real-Time Timer
+
+menu "Wi-Fi configuration"
+	depends on ESP32C3_WIRELESS
+
+config ESP32C3_WIFI_STATIC_RXBUF_NUM
+	int "Wi-Fi static RX buffer number"
+	default 10
+
+config ESP32C3_WIFI_DYNAMIC_RXBUF_NUM
+	int "Wi-Fi dynamic RX buffer number"
+	default 32
+
+config ESP32C3_WIFI_DYNAMIC_TXBUF_NUM
+	int "Wi-Fi dynamic TX buffer number"
+	default 32
+
+config ESP32C3_WIFI_TX_AMPDU
+	bool "Wi-Fi TX AMPDU"
+	default y
+
+config ESP32C3_WIFI_RX_AMPDU
+	bool "Wi-Fi RX AMPDU"
+	default y
+
+config ESP32C3_WIFI_RXBA_AMPDU_WZ
+	int "Wi-Fi RX BA AMPDU windown size"
+	default 6
+
+config ESP32C3_WLAN_RXBUF_NUM
+	int "WLAN netcard RX buffer number"
+	default 16
+
+config ESP32C3_WIFI_CONNECT_TIMEOUT
+	int "Connect timeout by second"
+	default 10
+	help
+		Max waiting time of connecting to AP.
+
+config ESP32C3_WIFI_SAVE_PARAM
+	bool "Save Wi-Fi Parameters"
+	default n
+	depends on !DISABLE_MOUNTPOINT
+	help
+		If you enable this option, Wi-Fi adapter parameters will be saved
+		into the file system instead of computing them each time.
+
+		These parameters mainly contains:
+		  - SSID
+		  - Password
+		  - BSSID
+		  - PMK(compute when connecting)
+		  - Author mode
+		  - MAC address
+		  - Wi-Fi hardware configuration parameters
+
+config ESP32C3_WIFI_FS_MOUNTPT
+	string "Save Wi-Fi Parameters"
+	default "/mnt/esp/wifi"
+	depends on ESP32C3_WIFI_SAVE_PARAM
+	help
+		Mount point of Wi-Fi storage file system.
+
+endmenu # ESP32C3_WIRELESS
+
 endif # ARCH_CHIP_ESP32C3
diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs
index 37f5b2421f..f142c5a61d 100644
--- a/arch/risc-v/src/esp32c3/Make.defs
+++ b/arch/risc-v/src/esp32c3/Make.defs
@@ -75,4 +75,43 @@ CHIP_CSRCS += esp32c3_tim.c
 ifeq ($(CONFIG_TIMER),y)
 CHIP_CSRCS += esp32c3_tim_lowerhalf.c
 endif
-endif
\ No newline at end of file
+endif
+
+ifeq ($(CONFIG_ESP32C3_RT_TIMER),y)
+CHIP_CSRCS += esp32c3_rt_timer.c
+endif
+
+ifeq ($(CONFIG_ESP32C3_WIRELESS),y)
+WIRELESS_DRV_UNPACK  = esp-wireless-drivers-3rdparty
+WIRELESS_DRV_ID      = 3cc7f67
+WIRELESS_DRV_ZIP     = $(WIRELESS_DRV_ID).zip
+WIRELESS_DRV_URL     = https://github.com/espressif/esp-wireless-drivers-3rdparty/archive
+
+$(WIRELESS_DRV_ZIP):
+	$(Q) echo "Downloading: ESP Wireless Drivers"
+	$(Q) curl -L $(WIRELESS_DRV_URL)/$(WIRELESS_DRV_ZIP) -o chip/$(WIRELESS_DRV_ZIP)
+
+chip/$(WIRELESS_DRV_UNPACK): $(WIRELESS_DRV_ZIP)
+	$(Q) echo "Unpacking: ESP Wireless Drivers"
+	$(Q) unzip -oqq chip/$(WIRELESS_DRV_ZIP) -d chip/
+	$(Q) mv chip/$(WIRELESS_DRV_UNPACK)-$(WIRELESS_DRV_ID)* chip/$(WIRELESS_DRV_UNPACK)
+	$(Q) touch chip/$(WIRELESS_DRV_UNPACK)
+
+context:: chip/$(WIRELESS_DRV_UNPACK)
+
+clean_context::
+	$(call DELFILE, chip/$(WIRELESS_DRV_ZIP))
+	$(call DELDIR, chip/$(WIRELESS_DRV_UNPACK))
+
+INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include)
+INCLUDES += $(shell $(INCDIR) "$(CC)" $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)include$(DELIM)esp32c3)
+CHIP_CSRCS += esp32c3_wlan.c esp32c3_wifi_adapter.c
+
+EXTRA_LIBPATHS += -L $(ARCH_SRCDIR)$(DELIM)chip$(DELIM)esp-wireless-drivers-3rdparty$(DELIM)libs$(DELIM)esp32c3
+EXTRA_LIBS += -lcore -lnet80211 -lpp -lsmartconfig -lcoexist -lespnow -lphy -lwpa_supplicant -lwapi
+
+# Due to some Wi-Fi related libraries, the option is need to avoid linking too much
+# unused functions.
+
+LDFLAGS += --gc-sections
+endif
diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.c b/arch/risc-v/src/esp32c3/esp32c3_irq.c
index 0f8ce8b758..b91aff946d 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_irq.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_irq.c
@@ -54,6 +54,18 @@
 
 #define CPUINT_UNASSIGNED 0xff
 
+/* Wi-Fi reserved CPU interrupt bit */
+
+#ifdef CONFIG_ESP32C3_WIRELESS
+#  define CPUINT_WMAC_MAP (1 << ESP32C3_CPUINT_WMAC)
+#else
+#  define CPUINT_WMAC_MAP 0
+#endif
+
+/* Reserved CPU interrupt bits */
+
+#define CPUINT_RESERVED_MAPS (CPUINT_WMAC_MAP)
+
 /****************************************************************************
  * Public Data
  ****************************************************************************/
@@ -82,6 +94,17 @@ void up_irqinitialize(void)
 
   memset(g_cpuint_map, CPUINT_UNASSIGNED, ESP32C3_CPUINT_MAX);
 
+  /**
+   * Initialize specific driver's CPU interrupt ID:
+   *   Object  |  CPU INT  |  Pheripheral
+   *           |           |
+   *    Wi-Fi  |     1     |      1
+   */
+
+#ifdef CONFIG_ESP32C3_WIRELESS
+  g_cpuint_map[ESP32C3_CPUINT_WMAC] = ESP32C3_PERIPH_WIFI_MAC_NMI;
+#endif
+
   /* Clear all peripheral interrupts from "bootloader" */
 
   for (periphid = 0; periphid < ESP32C3_NPERIPHERALS; periphid++)
@@ -166,6 +189,50 @@ void up_disable_irq(int cpuint)
   leave_critical_section(irqstate);
 }
 
+/****************************************************************************
+ * Name: esp32c3_bind_irq
+ *
+ * Description:
+ *   Bind IRQ and resource with given parameters.
+ *
+ * Input Parameters:
+ *   cpuint    - CPU interrupt ID
+ *   periphid  - Peripheral ID
+ *   prio      - Interrupt priority
+ *   flags     - Interrupt flags
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32c3_bind_irq(uint8_t cpuint, uint8_t periphid, uint8_t prio,
+                      uint32_t flags)
+{
+  /* Disable the CPU interrupt. */
+
+  resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
+
+  /* Set the interrupt priority. */
+
+  putreg32(prio, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
+
+  /* Set the interrupt type (Edge or Level). */
+
+  if (flags & ESP32C3_INT_EDGE)
+    {
+      setbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
+    }
+  else
+    {
+      resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
+    }
+
+  /* Map the CPU interrupt ID to the peripheral. */
+
+  putreg32(cpuint, DR_REG_INTERRUPT_BASE + periphid * 4);
+}
+
 /****************************************************************************
  * Name: esp32c3_request_irq
  *
@@ -198,6 +265,11 @@ int esp32c3_request_irq(uint8_t periphid, uint8_t prio, uint32_t flags)
   /* Skip over enabled interrupts.  NOTE: bit 0 is reserved. */
 
   regval = getreg32(INTERRUPT_CPU_INT_ENABLE_REG);
+
+  /* Skip over reserved CPU interrupts */
+
+  regval |= CPUINT_RESERVED_MAPS;
+
   for (cpuint = 1; cpuint <= ESP32C3_CPUINT_MAX; cpuint++)
     {
       if (!(regval & (1 << cpuint)))
@@ -224,28 +296,9 @@ int esp32c3_request_irq(uint8_t periphid, uint8_t prio, uint32_t flags)
 
       g_cpuint_map[cpuint] = periphid;
 
-      /* Set the interrupt priority. */
+      /* Configure IRQ */
 
-      putreg32(prio, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4);
-
-      /* Set the interrupt type (Edge or Level). */
-
-      if (flags & ESP32C3_INT_EDGE)
-        {
-          setbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
-        }
-      else
-        {
-          resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG);
-        }
-
-      /* Map the CPU interrupt ID to the peripheral. */
-
-      putreg32(cpuint, DR_REG_INTERRUPT_BASE + periphid * 4);
-
-      /* Disable the CPU interrupt. */
-
-      resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG);
+      esp32c3_bind_irq(cpuint, periphid, prio, flags);
     }
   else
     {
diff --git a/arch/risc-v/src/esp32c3/esp32c3_irq.h b/arch/risc-v/src/esp32c3/esp32c3_irq.h
index 72d4f8da2b..719d1d5398 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_irq.h
+++ b/arch/risc-v/src/esp32c3/esp32c3_irq.h
@@ -47,6 +47,26 @@
 
 void up_irqinitialize(void);
 
+/****************************************************************************
+ * Name: esp32c3_bind_irq
+ *
+ * Description:
+ *   Bind IRQ and resource with given parameters.
+ *
+ * Input Parameters:
+ *   cpuint    - CPU interrupt ID
+ *   periphid  - Peripheral ID
+ *   prio      - Interrupt priority
+ *   flags     - Interrupt flags
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32c3_bind_irq(uint8_t cpuint, uint8_t periphid, uint8_t prio,
+                      uint32_t flags);
+
 /****************************************************************************
  * Name: esp32c3_request_irq
  *
diff --git a/arch/risc-v/src/esp32c3/esp32c3_rt_timer.c b/arch/risc-v/src/esp32c3/esp32c3_rt_timer.c
new file mode 100644
index 0000000000..97696909b6
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_rt_timer.c
@@ -0,0 +1,678 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_rt_timer.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this args for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <errno.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/kthread.h>
+#include <nuttx/kmalloc.h>
+#include <nuttx/semaphore.h>
+
+#include "hardware/esp32c3_soc.h"
+#include "esp32c3_tim.h"
+#include "esp32c3_rt_timer.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_SCHED_HPWORKPRIORITY
+#  if CONFIG_ESP32C3_RT_TIMER_TASK_PRIORITY >= CONFIG_SCHED_HPWORKPRIORITY
+#    error "RT timer priority should be smaller that high-prio workqueue"
+#  endif
+#endif
+
+#define RT_TIMER_TASK_NAME        CONFIG_ESP32C3_RT_TIMER_TASK_NAME
+#define RT_TIMER_TASK_PRIORITY    CONFIG_ESP32C3_RT_TIMER_TASK_PRIORITY
+#define RT_TIMER_TASK_STACK_SIZE  CONFIG_ESP32C3_RT_TIMER_TASK_STACK_SIZE
+
+#define ESP32C3_TIMER_PRESCALER     (APB_CLK_FREQ / (1000 * 1000))
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static int s_pid;
+
+static sem_t s_toutsem;
+
+static struct list_node s_runlist;
+static struct list_node s_toutlist;
+
+static struct esp32c3_tim_dev_s *s_esp32c3_tim_dev;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: start_rt_timer
+ *
+ * Description:
+ *   Start timer by inserting it into running list and reset hardware timer
+ *   alarm value if this timer in head of list.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *   timeout - Timeout value
+ *   repeat  - If the timer run repeat
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void start_rt_timer(FAR struct rt_timer_s *timer,
+                           uint64_t timeout,
+                           bool repeat)
+{
+  irqstate_t flags;
+  struct rt_timer_s *p;
+  bool inserted = false;
+  uint64_t counter;
+  struct esp32c3_tim_dev_s *tim = s_esp32c3_tim_dev;
+
+  flags = enter_critical_section();
+
+  /* Only idle timer can be started */
+
+  if (timer->state == RT_TIMER_IDLE)
+    {
+      /* Calculate the timer's alarm value */
+
+      ESP32C3_TIM_GETCTR(tim, &counter);
+      timer->timeout = timeout;
+      timer->alarm = timer->timeout + counter;
+
+      if (repeat)
+        {
+          timer->flags |= RT_TIMER_REPEAT;
+        }
+      else
+        {
+          timer->flags &= ~RT_TIMER_REPEAT;
+        }
+
+      /** Scan timer list and insert the new timer into previous
+       *  node of timer whose alarm value is larger than new one
+       */
+
+      list_for_every_entry(&s_runlist, p, struct rt_timer_s, list)
+        {
+          if (p->alarm > timer->alarm)
+            {
+              list_add_before(&p->list, &timer->list);
+              inserted = true;
+              break;
+            }
+        }
+
+      /* If not find a larger one, insert new timer into tail of list */
+
+      if (!inserted)
+        {
+          list_add_tail(&s_runlist, &timer->list);
+        }
+
+      timer->state = RT_TIMER_READY;
+
+      /* If this timer is in head of list */
+
+      if (timer == container_of(s_runlist.next, struct rt_timer_s, list))
+        {
+          /* Reset hardware timer alarm */
+
+          ESP32C3_TIM_SETALRVL(tim, timer->alarm);
+          ESP32C3_TIM_SETALRM(tim, true);
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: stop_rt_timer
+ *
+ * Description:
+ *   Stop timer by removing it from running list and reset hardware timer
+ *   alarm value if this timer is in head of list.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void stop_rt_timer(FAR struct rt_timer_s *timer)
+{
+  irqstate_t flags;
+  bool ishead;
+  struct rt_timer_s *next_timer;
+  uint64_t alarm;
+  struct esp32c3_tim_dev_s *tim = s_esp32c3_tim_dev;
+
+  flags = enter_critical_section();
+
+  /**
+   * Function "start" can set timer to be repeat, and function "stop"
+   * should remove this feature although it is not in ready state.
+   */
+
+  timer->flags &= ~RT_TIMER_REPEAT;
+
+  /* Only ready timer can be stopped */
+
+  if (timer->state == RT_TIMER_READY)
+    {
+      /* Check if timer is in head of list */
+
+      if (timer == container_of(s_runlist.next, struct rt_timer_s, list))
+        {
+          ishead = true;
+        }
+      else
+        {
+          ishead = false;
+        }
+
+      list_delete(&timer->list);
+      timer->state = RT_TIMER_IDLE;
+
+      /* If timer is in in head of list */
+
+      if (ishead)
+        {
+          /* If list is not empty */
+
+          if (!list_is_empty(&s_runlist))
+            {
+              /* Reset hardware timer alarm value to be next timer's */
+
+              next_timer = container_of(s_runlist.next,
+                                        struct rt_timer_s,
+                                        list);
+              alarm = next_timer->alarm;
+
+              ESP32C3_TIM_SETALRVL(tim, alarm);
+              ESP32C3_TIM_SETALRM(tim, true);
+            }
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: delete_rt_timer
+ *
+ * Description:
+ *   Delete timer by removing it from list, then set the timer's state
+ *   to be "RT_TIMER_DELETE", inserting into work list to let rt-timer
+ *   thread to delete it and free resource.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+static void delete_rt_timer(FAR struct rt_timer_s *timer)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  if (timer->state == RT_TIMER_READY)
+    {
+      stop_rt_timer(timer);
+    }
+  else if (timer->state == RT_TIMER_TIMEOUT)
+    {
+      list_delete(&timer->list);
+    }
+  else if (timer->state == RT_TIMER_DELETE)
+    {
+      goto exit;
+    }
+
+  list_add_after(&s_toutlist, &timer->list);
+  timer->state = RT_TIMER_DELETE;
+
+exit:
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: rt_timer_thread
+ *
+ * Description:
+ *   RT timer working thread, it wait for a timeout semaphore, scan
+ *   the timeout list and process all timers in this list.
+ *
+ * Input Parameters:
+ *   argc - Not used
+ *   argv - Not used
+ *
+ * Returned Value:
+ *   0.
+ *
+ ****************************************************************************/
+
+static int rt_timer_thread(int argc, FAR char *argv[])
+{
+  int ret;
+  irqstate_t flags;
+  struct rt_timer_s *timer;
+  enum rt_timer_state_e raw_state;
+
+  while (1)
+    {
+      /* Waiting for timers timeout */
+
+      ret = nxsem_wait(&s_toutsem);
+      if (ret)
+        {
+          tmrerr("ERROR: Wait s_toutsem error=%d\n", ret);
+          assert(0);
+        }
+
+      /* Enter critical to check global timer timeout list */
+
+      flags = enter_critical_section();
+
+      /* Process all timers in list */
+
+      while (!list_is_empty(&s_toutlist))
+        {
+          /* Get first timer in list */
+
+          timer = container_of(s_toutlist.next, struct rt_timer_s, list);
+
+          /* Cache the raw state to decide how to deal with this timer */
+
+          raw_state = timer->state;
+
+          /* Delete timer from list */
+
+          list_delete(&timer->list);
+
+          /* Set timer's state to be let it to able to restart by user */
+
+          timer->state = RT_TIMER_IDLE;
+
+          /* Leave from critical to start to call "callback" function */
+
+          leave_critical_section(flags);
+
+          if (raw_state == RT_TIMER_TIMEOUT)
+            {
+              timer->callback(timer->arg);
+            }
+          else if (raw_state == RT_TIMER_DELETE)
+            {
+              kmm_free(timer);
+            }
+
+          /* Enter critical for next scanning list */
+
+          flags = enter_critical_section();
+
+          if (raw_state == RT_TIMER_TIMEOUT)
+            {
+              /* Check if timer is repeat */
+
+              if (timer->flags & RT_TIMER_REPEAT)
+                {
+                  start_rt_timer(timer, timer->timeout, true);
+                }
+            }
+        }
+
+      leave_critical_section(flags);
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: rt_timer_isr
+ *
+ * Description:
+ *   Hardware timer interrupt service function.
+ *
+ * Input Parameters:
+ *   irq     - Not used
+ *   context - Not used
+ *   arg     - Not used
+ *
+ * Returned Value:
+ *   0.
+ *
+ ****************************************************************************/
+
+static int rt_timer_isr(int irq, void *context, void *arg)
+{
+  irqstate_t flags;
+  struct rt_timer_s *timer;
+  uint64_t alarm;
+  uint64_t counter;
+  struct esp32c3_tim_dev_s *tim = s_esp32c3_tim_dev;
+
+  /* Clear interrupt register status */
+
+  ESP32C3_TIM_ACKINT(tim);
+
+  /* Wake up thread to process timeout timers */
+
+  nxsem_post(&s_toutsem);
+
+  flags = enter_critical_section();
+
+  /* Check if there is timer running */
+
+  if (!list_is_empty(&s_runlist))
+    {
+      /**
+       * When stop/delete timer, in the same time the hardware timer
+       * interrupt triggers, function "stop/delete" remove the timer
+       * from running list, so the 1st timer is not which triggers.
+       */
+
+      timer = container_of(s_runlist.next, struct rt_timer_s, list);
+      ESP32C3_TIM_GETCTR(tim, &counter);
+      if (timer->alarm <= counter)
+        {
+          /**
+           * Remove first timer in running list and add it into
+           * timeout list.
+           *
+           * Set the timer's state to be RT_TIMER_TIMEOUT to avoid
+           * other operation.
+           */
+
+          list_delete(&timer->list);
+          timer->state = RT_TIMER_TIMEOUT;
+          list_add_after(&s_toutlist, &timer->list);
+
+          /* Check if thers is timer running */
+
+          if (!list_is_empty(&s_runlist))
+            {
+              /* Reset hardware timer alarm with next timer's alarm value */
+
+              timer = container_of(s_runlist.next, struct rt_timer_s, list);
+              alarm = timer->alarm;
+
+              ESP32C3_TIM_SETALRVL(tim, alarm);
+              ESP32C3_TIM_SETALRM(tim, true);
+            }
+        }
+    }
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rt_timer_create
+ *
+ * Description:
+ *   Create RT timer by into timer creation arguments
+ *
+ * Input Parameters:
+ *   args         - Input RT timer creation arguments
+ *   timer_handle - Output RT timer handle pointer
+ *
+ * Returned Value:
+ *   0 is returned on success. Otherwise, a negated errno value is returned.
+ *
+ ****************************************************************************/
+
+int rt_timer_create(FAR const struct rt_timer_args_s *args,
+                    FAR struct rt_timer_s **timer_handle)
+{
+  struct rt_timer_s *timer;
+
+  timer = (struct rt_timer_s *)kmm_malloc(sizeof(*timer));
+  if (!timer)
+    {
+      tmrerr("ERROR: Failed to allocate %d bytes\n", sizeof(*timer));
+      return -ENOMEM;
+    }
+
+  timer->callback = args->callback;
+  timer->arg      = args->arg;
+  timer->flags    = RT_TIMER_NOFLAGS;
+  timer->state    = RT_TIMER_IDLE;
+  list_initialize(&timer->list);
+
+  *timer_handle = timer;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: rt_timer_start
+ *
+ * Description:
+ *   Start RT timer.
+ *
+ * Input Parameters:
+ *   timer   - RT timer pointer
+ *   timeout - Timeout value
+ *   repeat  - If the timer run repeat
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_start(FAR struct rt_timer_s *timer,
+                    uint64_t timeout,
+                    bool repeat)
+{
+  stop_rt_timer(timer);
+
+  start_rt_timer(timer, timeout, repeat);
+}
+
+/****************************************************************************
+ * Name: rt_timer_stop
+ *
+ * Description:
+ *   Stop RT timer.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_stop(FAR struct rt_timer_s *timer)
+{
+  stop_rt_timer(timer);
+}
+
+/****************************************************************************
+ * Name: rt_timer_delete
+ *
+ * Description:
+ *   Stop and delete RT timer.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_delete(FAR struct rt_timer_s *timer)
+{
+  delete_rt_timer(timer);
+}
+
+/****************************************************************************
+ * Name: rt_timer_time_us
+ *
+ * Description:
+ *   Get time of RT timer by microsecond.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Time of RT timer by microsecond.
+ *
+ ****************************************************************************/
+
+uint64_t rt_timer_time_us(void)
+{
+  uint64_t counter;
+  struct esp32c3_tim_dev_s *tim = s_esp32c3_tim_dev;
+
+  ESP32C3_TIM_GETCTR(tim, &counter);
+
+  return counter;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rt_timer_init
+ *
+ * Description:
+ *   Initialize ESP32-C3 RT timer.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 is returned on success. Otherwise, a negated errno value is returned.
+ *
+ ****************************************************************************/
+
+int esp32c3_rt_timer_init(void)
+{
+  int pid;
+  irqstate_t flags;
+  struct esp32c3_tim_dev_s *tim;
+
+  tim = esp32c3_tim0_init();
+  if (!tim)
+    {
+      tmrerr("ERROR: Failed to initialize ESP32 timer0\n");
+      return -EINVAL;
+    }
+
+  nxsem_init(&s_toutsem, 0, 0);
+
+  pid = kthread_create(RT_TIMER_TASK_NAME,
+                       RT_TIMER_TASK_PRIORITY,
+                       RT_TIMER_TASK_STACK_SIZE,
+                       rt_timer_thread,
+                       NULL);
+  if (pid < 0)
+    {
+      tmrerr("ERROR: Failed to create RT timer task error=%d\n", pid);
+      esp32c3_tim_deinit(tim);
+      return pid;
+    }
+
+  list_initialize(&s_runlist);
+  list_initialize(&s_toutlist);
+
+  s_esp32c3_tim_dev = tim;
+  s_pid = pid;
+
+  flags = enter_critical_section();
+
+  /**
+   * ESP32 hardware timer configuration:
+   *   - 1 counter = 1us
+   *   - Counter increase mode
+   *   - Non-reload mode
+   */
+
+  ESP32C3_TIM_SETPRE(tim, ESP32C3_TIMER_PRESCALER);
+  ESP32C3_TIM_SETMODE(tim, ESP32C3_TIM_MODE_UP);
+  ESP32C3_TIM_SETARLD(tim, false);
+  ESP32C3_TIM_CLEAR(tim);
+
+  ESP32C3_TIM_SETISR(tim, rt_timer_isr, NULL);
+  ESP32C3_TIM_ENABLEINT(tim);
+
+  ESP32C3_TIM_START(tim);
+
+  leave_critical_section(flags);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rt_timer_deinit
+ *
+ * Description:
+ *   Deinitialize ESP32-C3 RT timer.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32c3_rt_timer_deinit(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  ESP32C3_TIM_STOP(s_esp32c3_tim_dev);
+  s_esp32c3_tim_dev = NULL;
+
+  leave_critical_section(flags);
+
+  kthread_delete(s_pid);
+  nxsem_destroy(&s_toutsem);
+}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_rt_timer.h b/arch/risc-v/src/esp32c3/esp32c3_rt_timer.h
new file mode 100644
index 0000000000..3957483b9d
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_rt_timer.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_rt_timer.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RT_TIMER_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RT_TIMER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <nuttx/list.h>
+
+#define RT_TIMER_NOFLAGS    (0)         /* Timer support no feature */
+#define RT_TIMER_REPEAT     (1 << 0)    /* Timer is repeat */
+
+/**
+ * RT timer state
+ */
+
+enum rt_timer_state_e
+{
+  RT_TIMER_IDLE,            /* Timer is not counting */
+  RT_TIMER_READY,           /* Timer is counting */
+  RT_TIMER_TIMEOUT,         /* Timer is timeout */
+  RT_TIMER_DELETE           /* Timer is to be delete */
+};
+
+/**
+ * RT timer data structure
+ */
+
+struct rt_timer_s
+{
+  uint64_t timeout;             /* Timeout value */
+  uint64_t alarm;               /* Timeout period */
+  void (*callback)(void *arg);  /* Callback function */
+  void *arg;                    /* Private data */
+  uint16_t flags;               /* Support feature */
+  enum rt_timer_state_e state;  /* Mark if timer is started */
+  struct list_node list;        /* Working list */
+};
+
+/**
+ * RT timer creation arguments data structure
+ */
+
+struct rt_timer_args_s
+{
+  void (*callback)(void *arg);  /* Callback function */
+  void *arg;                    /* Private data */
+};
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: rt_timer_create
+ *
+ * Description:
+ *   Create RT timer by into timer creation arguments
+ *
+ * Input Parameters:
+ *   args         - Input RT timer creation arguments
+ *   timer_handle - Output RT timer handle pointer
+ *
+ * Returned Value:
+ *   0 is returned on success. Otherwise, a negated errno value is returned.
+ *
+ ****************************************************************************/
+
+int rt_timer_create(const struct rt_timer_args_s *args,
+                    struct rt_timer_s **timer_handle);
+
+/****************************************************************************
+ * Name: rt_timer_start
+ *
+ * Description:
+ *   Start RT timer.
+ *
+ * Input Parameters:
+ *   timer   - RT timer pointer
+ *   timeout - Timeout value
+ *   repeat  - If the timer run repeat
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_start(struct rt_timer_s *timer,
+                    uint64_t timeout,
+                    bool repeat);
+
+/****************************************************************************
+ * Name: rt_timer_stop
+ *
+ * Description:
+ *   Stop RT timer.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_stop(struct rt_timer_s *timer);
+
+/****************************************************************************
+ * Name: rt_timer_delete
+ *
+ * Description:
+ *   Stop and delete RT timer.
+ *
+ * Input Parameters:
+ *   timer - RT timer pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void rt_timer_delete(struct rt_timer_s *timer);
+
+/****************************************************************************
+ * Name: rt_timer_time_us
+ *
+ * Description:
+ *   Get time of RT timer by microsecond.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Time of RT timer by microsecond.
+ *
+ ****************************************************************************/
+
+uint64_t rt_timer_time_us(void);
+
+/****************************************************************************
+ * Name: esp32c3_rt_timer_init
+ *
+ * Description:
+ *   Initialize ESP32-C3 RT timer.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 is returned on success. Otherwise, a negated errno value is returned.
+ *
+ ****************************************************************************/
+
+int esp32c3_rt_timer_init(void);
+
+/****************************************************************************
+ * Name: esp32c3_rt_timer_deinit
+ *
+ * Description:
+ *   Deinitialize ESP32-C3 RT timer.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void esp32c3_rt_timer_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+#undef EXTERN
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RT_TIMER_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_tim.c b/arch/risc-v/src/esp32c3/esp32c3_tim.c
index f0ce44f329..4ca044d986 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_tim.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_tim.c
@@ -685,7 +685,7 @@ FAR struct esp32c3_tim_dev_s *esp32c3_tim_init(int timer)
 
   switch (timer)
     {
-#if defined(CONFIG_ESP32C3_TIMER0)
+#if defined(CONFIG_ESP32C3_TIMER0) && !defined(CONFIG_ESP32C3_RT_TIMER)
       case 0:
         {
           tim = &g_esp32c3_tim0_priv;
@@ -738,3 +738,37 @@ void esp32c3_tim_deinit(FAR struct esp32c3_tim_dev_s *dev)
   tim = (FAR struct esp32c3_tim_priv_s *)dev;
   tim->inuse = false;
 }
+
+/****************************************************************************
+ * Name: esp32c3_tim0_init
+ *
+ * Description:
+ *   Initialize TIMER0 device, if software real-time timer
+ *   (CONFIG_ESP32C3_RT_TIMER) is enabled.
+ *
+ * Parameters:
+ *   None
+ *
+ * Returned Values:
+ *   If the initialization is successful, return a pointer to the timer
+ *   driver struct associated to that timer instance.
+ *   In case it fails, return NULL.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ESP32C3_RT_TIMER
+
+FAR struct esp32c3_tim_dev_s *esp32c3_tim0_init(void)
+{
+  FAR struct esp32c3_tim_priv_s *tim = &g_esp32c3_tim0_priv;
+
+  if (tim->inuse == true)
+    {
+      tmrerr("ERROR: TIMER0 is already in use\n");
+      tim = NULL;
+    }
+
+  return (FAR struct esp32c3_tim_dev_s *)tim;
+}
+
+#endif
diff --git a/arch/risc-v/src/esp32c3/esp32c3_tim.h b/arch/risc-v/src/esp32c3/esp32c3_tim.h
index 2d427435ae..df5a35792c 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_tim.h
+++ b/arch/risc-v/src/esp32c3/esp32c3_tim.h
@@ -135,4 +135,12 @@ struct esp32c3_tim_ops_s
 FAR struct esp32c3_tim_dev_s *esp32c3_tim_init(int timer);
 void esp32c3_tim_deinit(FAR struct esp32c3_tim_dev_s *dev);
 
+/****************************************************************************
+ * The Timer0 is used by RT-Timer of wireless driver, so please don't use it
+ * in any other components.
+ ****************************************************************************/
+#ifdef CONFIG_ESP32C3_RT_TIMER
+FAR struct esp32c3_tim_dev_s *esp32c3_tim0_init(void);
+#endif
+
 #endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_TIM_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_tim_lowerhalf.c b/arch/risc-v/src/esp32c3/esp32c3_tim_lowerhalf.c
index 8436936b3e..ba6488b5dc 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_tim_lowerhalf.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_tim_lowerhalf.c
@@ -97,7 +97,7 @@ static const struct timer_ops_s g_esp32c3_timer_ops =
   .ioctl       = NULL,
 };
 
-#ifdef CONFIG_ESP32C3_TIMER0
+#if defined(CONFIG_ESP32C3_TIMER0) && !defined(CONFIG_ESP32C3_RT_TIMER)
 /* TIMER0 lower-half */
 
 static struct esp32c3_timer_lowerhalf_s g_esp32c3_timer0_lowerhalf =
@@ -500,7 +500,7 @@ int esp32c3_timer_initialize(FAR const char *devpath, uint8_t timer)
 
   switch (timer)
     {
-#ifdef CONFIG_ESP32C3_TIMER0
+#if defined(CONFIG_ESP32C3_TIMER0) && !defined(CONFIG_ESP32C3_RT_TIMER)
       case 0:
         {
           lower = &g_esp32c3_timer0_lowerhalf;
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
new file mode 100644
index 0000000000..8c5b1bdfe1
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
@@ -0,0 +1,4646 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <inttypes.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <clock/clock.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "nuttx/kmalloc.h"
+#include <nuttx/mqueue.h>
+#include "nuttx/spinlock.h"
+#include <nuttx/irq.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/wqueue.h>
+#include <nuttx/sched.h>
+#include <nuttx/signal.h>
+#include <nuttx/arch.h>
+
+#include "hardware/esp32c3_syscon.h"
+#include "esp32c3.h"
+#include "esp32c3_attr.h"
+#include "esp32c3_irq.h"
+#include "esp32c3_wifi_adapter.h"
+#include "esp32c3_rt_timer.h"
+
+#include "espidf_wifi.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAC_ADDR0_REG (DR_REG_EFUSE_BASE + 0x044)
+#define MAC_ADDR1_REG (DR_REG_EFUSE_BASE + 0x048)
+
+#define PHY_RF_MASK   ((1 << PHY_BT_MODULE) | (1 << PHY_WIFI_MODULE))
+
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+#  define NVS_FS_PREFIX CONFIG_ESP32C3_WIFI_FS_MOUNTPT
+#  define NVS_DIR_BASE  NVS_FS_PREFIX"/wifi."
+#  define NVS_FILE_MODE 0777
+#endif
+
+#ifndef MIN
+#  define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define WIFI_CONNECT_TIMEOUT  CONFIG_ESP32C3_WIFI_CONNECT_TIMEOUT
+
+#define TIMER_INITIALIZED_VAL (0x5aa5a55a)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Wi-Fi interrupt adapter private data */
+
+struct irq_adpt
+{
+  void (*func)(void *arg);  /* Interrupt callback function */
+  void *arg;                /* Interrupt private data */
+};
+
+/* Wi-Fi message queue private data */
+
+struct mq_adpt
+{
+  struct file mq;           /* Message queue handle */
+  uint32_t    msgsize;      /* Message size */
+  char        name[16];     /* Message queue name */
+};
+
+/* Wi-Fi time private data */
+
+struct time_adpt
+{
+  time_t      sec;          /* Second value */
+  suseconds_t usec;         /* Micro second value */
+};
+
+/* Wi-Fi timer private data */
+
+struct timer_adpt
+{
+  struct wdog_s wdog;       /* Timer handle */
+  struct work_s work;       /* Work private data */
+  bool          repeat;     /* Flags indicate if it is cycle */
+  uint32_t      delay;      /* Timeout ticks */
+
+  /* Timer callback function */
+
+  void          (*func)(void *priv);
+  void          *priv;      /* Timer private data */
+};
+
+/* Wi-Fi event private data */
+
+struct evt_adpt
+{
+  sq_entry_t entry;         /* Sequence entry */
+  int32_t id;               /* Event ID */
+  uint8_t buf[0];           /* Event private data */
+};
+
+/* Wi-Fi event notification private data */
+
+struct wifi_notify
+{
+  bool assigned;            /* Flag indicate if it is used */
+  pid_t pid;                /* Signal's target thread PID */
+  struct sigevent event;    /* Signal event private data */
+  struct sigwork_s work;    /* Signal work private data */
+};
+
+/* Wi-Fi NVS private data */
+
+struct nvs_adpt
+{
+  char *index_name;
+};
+
+/****************************************************************************
+ * 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 esp32c3_ints_on(uint32_t mask);
+static void esp32c3_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 esp_task_yield_from_isr(void);
+static void *esp_semphr_create(uint32_t max, uint32_t init);
+static void esp_semphr_delete(void *semphr);
+static int32_t esp_semphr_take(void *semphr, uint32_t block_time_tick);
+static int32_t esp_semphr_give(void *semphr);
+static void *esp_thread_semphr_get(void);
+static void *esp_mutex_create(void);
+static void *esp_recursive_mutex_create(void);
+static void esp_mutex_delete(void *mutex_data);
+static int32_t esp_mutex_lock(void *mutex_data);
+static int32_t esp_mutex_unlock(void *mutex_data);
+static void *esp_queue_create(uint32_t queue_len, uint32_t item_size);
+static void esp_queue_delete(void *queue);
+static int32_t esp_queue_send(void *queue, void *item,
+                              uint32_t block_time_tick);
+static int32_t esp_queue_send_from_isr(void *queue, void *item, void *hptw);
+static int32_t esp_queue_send_to_back(void *queue, void *item,
+                                      uint32_t block_time_tick);
+static int32_t esp_queue_send_to_front(void *queue, void *item,
+                                       uint32_t block_time_tick);
+static int32_t esp_queue_recv(void *queue, void *item,
+                              uint32_t block_time_tick);
+static uint32_t esp_queue_msg_waiting(void *queue);
+static void *esp_event_group_create(void);
+static void esp_event_group_delete(void *event);
+static uint32_t esp_event_group_set_bits(void *event, uint32_t bits);
+static uint32_t esp_event_group_clear_bits(void *event, uint32_t bits);
+static uint32_t esp_event_group_wait_bits(void *event,
+                                          uint32_t bits_to_wait_for,
+                                          int clear_on_exit,
+                                          int wait_for_all_bits,
+                                          uint32_t block_time_tick);
+static int32_t esp_task_create_pinned_to_core(void *task_func,
+                                              const char *name,
+                                              uint32_t stack_depth,
+                                              void *param,
+                                              uint32_t prio,
+                                              void *task_handle,
+                                              uint32_t core_id);
+static int32_t esp_task_create(void *task_func, const char *name,
+                               uint32_t stack_depth, void *param,
+                               uint32_t prio, void *task_handle);
+static void esp_task_delete(void *task_handle);
+static void esp_task_delay(uint32_t tick);
+static int32_t esp_task_ms_to_tick(uint32_t ms);
+static void *esp_task_get_current_task(void);
+static int32_t esp_task_get_max_priority(void);
+static void *esp_malloc(unsigned int size);
+static void esp_free(void *ptr);
+static uint32_t esp_rand(void);
+static int32_t esp_event_post_wrap(esp_event_base_t event_base,
+                                   int32_t event_id,
+                                   void *event_data,
+                                   size_t event_data_size,
+                                   uint32_t ticks);
+static void esp_dport_access_stall_other_cpu_start(void);
+static void esp_dport_access_stall_other_cpu_end(void);
+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 int wifi_phy_update_country_info(const char *country);
+static int esp_wifi_read_mac(uint8_t *mac, uint32_t type);
+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 int esp_nvs_set_i8(uint32_t handle, const char *key,
+                              int8_t value);
+static int esp_nvs_get_i8(uint32_t handle, const char *key,
+                              int8_t *out_value);
+static int esp_nvs_set_u8(uint32_t handle, const char *key,
+                              uint8_t value);
+static int esp_nvs_get_u8(uint32_t handle, const char *key,
+                              uint8_t *out_value);
+static int esp_nvs_set_u16(uint32_t handle, const char *key,
+                               uint16_t value);
+static int esp_nvs_get_u16(uint32_t handle, const char *key,
+                               uint16_t *out_value);
+static int esp_nvs_open(const char *name, uint32_t open_mode,
+                            uint32_t *out_handle);
+static void esp_nvs_close(uint32_t handle);
+static int esp_nvs_commit(uint32_t handle);
+static int esp_nvs_set_blob(uint32_t handle, const char *key,
+                                const void *value, size_t length);
+static int esp_nvs_get_blob(uint32_t handle, const char *key,
+                                void *out_value, size_t *length);
+static int esp_nvs_erase_key(uint32_t handle, const char *key);
+static int esp_get_random(uint8_t *buf, size_t len);
+static int esp_get_time(void *t);
+static uint32_t esp_clk_slowclk_cal_get_wrapper(void);
+static void esp_log_writev(uint32_t level, const char *tag,
+                           const char *format, va_list args);
+static void *esp_malloc_internal(size_t size);
+static void *esp_realloc_internal(void *ptr, size_t size);
+static void *esp_calloc_internal(size_t n, size_t size);
+static void *esp_zalloc_internal(size_t size);
+static void *esp_wifi_malloc(size_t size);
+static void *esp_wifi_realloc(void *ptr, size_t size);
+static void *esp_wifi_calloc(size_t n, size_t size);
+static void *esp_wifi_zalloc(size_t size);
+static void *esp_wifi_create_queue(int queue_len, int 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 int esp_coex_wifi_request(uint32_t event, uint32_t latency,
+                                     uint32_t duration);
+static int 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
+ ****************************************************************************/
+
+void ets_timer_arm(void *timer, uint32_t tmout, bool repeat);
+void ets_timer_disarm(void *timer);
+void ets_timer_done(void *timer);
+void ets_timer_setfn(void *timer, void *pfunction, void *parg);
+void ets_timer_arm_us(void *timer, uint32_t us, bool repeat);
+
+int64_t esp_timer_get_time(void);
+void esp_fill_random(void *buf, size_t len);
+void esp_log_write(uint32_t level, const char *tag, const char *format, ...);
+uint32_t esp_log_timestamp(void);
+uint8_t esp_crc8(const uint8_t *p, uint32_t len);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Wi-Fi interrupt private data */
+
+static bool g_wifi_irq_bind;
+
+/* Wi-Fi thread private data */
+
+static pthread_key_t g_wifi_thread_key;
+static bool g_wifi_tkey_init;
+
+/* Wi-Fi sleep private data */
+
+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;
+
+/* Wi-Fi event private data */
+
+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;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* Wi-Fi OS adapter data */
+
+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 = esp32c3_ints_on,
+  ._ints_off = esp32c3_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,
+  ._wifi_int_restore = esp_wifi_int_restore,
+  ._task_yield_from_isr = esp_task_yield_from_isr,
+  ._semphr_create = esp_semphr_create,
+  ._semphr_delete = esp_semphr_delete,
+  ._semphr_take = esp_semphr_take,
+  ._semphr_give = esp_semphr_give,
+  ._wifi_thread_semphr_get = esp_thread_semphr_get,
+  ._mutex_create = esp_mutex_create,
+  ._recursive_mutex_create = esp_recursive_mutex_create,
+  ._mutex_delete = esp_mutex_delete,
+  ._mutex_lock = esp_mutex_lock,
+  ._mutex_unlock = esp_mutex_unlock,
+  ._queue_create = esp_queue_create,
+  ._queue_delete = esp_queue_delete,
+  ._queue_send = esp_queue_send,
+  ._queue_send_from_isr = esp_queue_send_from_isr,
+  ._queue_send_to_back = esp_queue_send_to_back,
+  ._queue_send_to_front = esp_queue_send_to_front,
+  ._queue_recv = esp_queue_recv,
+  ._queue_msg_waiting = esp_queue_msg_waiting,
+  ._event_group_create = esp_event_group_create,
+  ._event_group_delete = esp_event_group_delete,
+  ._event_group_set_bits = esp_event_group_set_bits,
+  ._event_group_clear_bits = esp_event_group_clear_bits,
+  ._event_group_wait_bits = esp_event_group_wait_bits,
+  ._task_create_pinned_to_core = esp_task_create_pinned_to_core,
+  ._task_create = esp_task_create,
+  ._task_delete = esp_task_delete,
+  ._task_delay = esp_task_delay,
+  ._task_ms_to_tick = esp_task_ms_to_tick,
+  ._task_get_current_task = esp_task_get_current_task,
+  ._task_get_max_priority = esp_task_get_max_priority,
+  ._malloc = esp_malloc,
+  ._free = esp_free,
+  ._event_post = esp_event_post_wrap,
+  ._get_free_heap_size = esp_get_free_heap_size,
+  ._rand = esp_rand,
+  ._dport_access_stall_other_cpu_start_wrap =
+      esp_dport_access_stall_other_cpu_start,
+  ._dport_access_stall_other_cpu_end_wrap =
+      esp_dport_access_stall_other_cpu_end,
+  ._wifi_apb80m_request = wifi_apb80m_request,
+  ._wifi_apb80m_release = wifi_apb80m_release,
+  ._phy_disable = wifi_phy_disable,
+  ._phy_enable = wifi_phy_enable,
+  ._phy_update_country_info = wifi_phy_update_country_info,
+  ._read_mac = esp_wifi_read_mac,
+  ._timer_arm = ets_timer_arm,
+  ._timer_disarm = ets_timer_disarm,
+  ._timer_done = ets_timer_done,
+  ._timer_setfn = ets_timer_setfn,
+  ._timer_arm_us = ets_timer_arm_us,
+  ._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,
+  ._nvs_set_u8 = esp_nvs_set_u8,
+  ._nvs_get_u8 = esp_nvs_get_u8,
+  ._nvs_set_u16 = esp_nvs_set_u16,
+  ._nvs_get_u16 = esp_nvs_get_u16,
+  ._nvs_open = esp_nvs_open,
+  ._nvs_close = esp_nvs_close,
+  ._nvs_commit = esp_nvs_commit,
+  ._nvs_set_blob = esp_nvs_set_blob,
+  ._nvs_get_blob = esp_nvs_get_blob,
+  ._nvs_erase_key = esp_nvs_erase_key,
+  ._get_random = esp_get_random,
+  ._get_time = esp_get_time,
+  ._slowclk_cal_get = esp_clk_slowclk_cal_get_wrapper,
+  ._random = esp_random_ulong,
+  ._log_write = esp_log_write,
+  ._log_writev = esp_log_writev,
+  ._log_timestamp = esp_log_timestamp,
+  ._malloc_internal =  esp_malloc_internal,
+  ._realloc_internal = esp_realloc_internal,
+  ._calloc_internal = esp_calloc_internal,
+  ._zalloc_internal = esp_zalloc_internal,
+  ._wifi_malloc = esp_wifi_malloc,
+  ._wifi_realloc = esp_wifi_realloc,
+  ._wifi_calloc = esp_wifi_calloc,
+  ._wifi_zalloc = esp_wifi_zalloc,
+  ._wifi_create_queue = esp_wifi_create_queue,
+  ._wifi_delete_queue = esp_wifi_delete_queue,
+  ._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,
+};
+
+/* Wi-Fi feature capacity data */
+
+uint64_t g_wifi_feature_caps = CONFIG_FEATURE_WPA3_SAE_BIT;
+
+/* Wi-Fi TAG string data */
+
+ESP_EVENT_DEFINE_BASE(WIFI_EVENT);
+
+/****************************************************************************
+ * Private Functions and Public Functions only used by libraries
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_errno_trans
+ *
+ * Description:
+ *   Transform from nuttx error code to Wi-Fi adapter error code
+ *
+ * Input Parameters:
+ *   ret - NuttX error code
+ *
+ * Returned Value:
+ *   Wi-Fi adapter error code
+ *
+ ****************************************************************************/
+
+static inline int32_t esp_errno_trans(int ret)
+{
+  if (!ret)
+    {
+      return true;
+    }
+  else
+    {
+      return false;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_int_adpt_cb
+ *
+ * Description:
+ *   Wi-Fi interrupt adapter callback function
+ *
+ * Input Parameters:
+ *   arg - interrupt adapter private data
+ *
+ * Returned Value:
+ *   0 on success
+ *
+ ****************************************************************************/
+
+static int esp_int_adpt_cb(int irq, void *context, FAR void *arg)
+{
+  struct irq_adpt *adapter = (struct irq_adpt *)arg;
+
+  adapter->func(adapter->arg);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_thread_semphr_free
+ *
+ * Description:
+ *   Delete thread self's semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_thread_semphr_free(void *semphr)
+{
+  if (semphr)
+    {
+      esp_semphr_delete(semphr);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_update_time
+ *
+ * Description:
+ *   Transform ticks to time and add this time to timespec value
+ *
+ * Input Parameters:
+ *   timespec - Input timespec data pointer
+ *   ticks    - System ticks
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_update_time(struct timespec *timespec, uint32_t ticks)
+{
+  uint32_t tmp;
+
+  tmp = TICK2SEC(ticks);
+  timespec->tv_sec += tmp;
+
+  ticks -= SEC2TICK(tmp);
+  tmp = TICK2NSEC(ticks);
+
+  timespec->tv_nsec += tmp;
+}
+
+/****************************************************************************
+ * Name: esp_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:
+ *   Register interrupt function
+ *
+ * Input Parameters:
+ *   n   - Interrupt ID
+ *   f   - Interrupt function
+ *   arg - Function private data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_set_isr(int32_t n, void *f, void *arg)
+{
+  int ret;
+  struct irq_adpt *adapter;
+
+  wlinfo("INFO: n=%ld f=%p arg=%p\n", n, f, arg);
+
+  if (g_wifi_irq_bind)
+    {
+      return ;
+    }
+
+  adapter = kmm_malloc(sizeof(struct irq_adpt));
+  if (!adapter)
+    {
+      DEBUGASSERT(0);
+    }
+
+  adapter->func = f;
+  adapter->arg = arg;
+
+  ret = irq_attach(n + ESP32C3_IRQ_FIRSTPERIPH, esp_int_adpt_cb, adapter);
+  if (ret != OK)
+    {
+      DEBUGASSERT(0);
+    }
+
+  g_wifi_irq_bind = true;
+}
+
+/****************************************************************************
+ * Name: esp32c3_ints_on
+ *
+ * Description:
+ *   Enable Wi-Fi interrupt
+ *
+ * Input Parameters:
+ *   mask - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32c3_ints_on(uint32_t mask)
+{
+  int n = __builtin_ffs(mask) - 1;
+
+  up_enable_irq(n);
+}
+
+/****************************************************************************
+ * Name: esp32c3_ints_off
+ *
+ * Description:
+ *   Disable Wi-Fi interrupt
+ *
+ * Input Parameters:
+ *   mask - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp32c3_ints_off(uint32_t mask)
+{
+  int n = __builtin_ffs(mask) - 1;
+
+  up_disable_irq(n);
+}
+
+/****************************************************************************
+ * 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();
+}
+
+/****************************************************************************
+ * Name: esp_spin_lock_create
+ *
+ * Description:
+ *   Create spin lock in SMP mode
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Spin lock data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_spin_lock_create(void)
+{
+  return (void *)1;
+}
+
+/****************************************************************************
+ * Name: esp_spin_lock_delete
+ *
+ * Description:
+ *   Delete spin lock
+ *
+ * Input Parameters:
+ *   lock - Spin lock data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_spin_lock_delete(void *lock)
+{
+  DEBUGASSERT((int)lock == 1);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_int_disable
+ *
+ * Description:
+ *   Enter critical section by disabling interrupts and taking the spin lock
+ *   if in SMP mode.
+ *
+ * Input Parameters:
+ *   wifi_int_mux - Spin lock data pointer
+ *
+ * Returned Value:
+ *   CPU PS value.
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp_wifi_int_disable(void *wifi_int_mux)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  return (uint32_t)flags;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_int_restore
+ *
+ * Description:
+ *   Exit from critical section by enabling interrupts and releasing the spin
+ *   lock if in SMP mode.
+ *
+ * Input Parameters:
+ *   wifi_int_mux - Spin lock data pointer
+ *   tmp          - CPU PS value.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp_wifi_int_restore(void *wifi_int_mux, uint32_t tmp)
+{
+  irqstate_t flags = (irqstate_t)tmp;
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: esp_task_yield_from_isr
+ *
+ * Description:
+ *   Do nothing in NuttX
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp_task_yield_from_isr(void)
+{
+  /* Do nothing */
+}
+
+/****************************************************************************
+ * Name: esp_semphr_create
+ *
+ * Description:
+ *   Create and initialize semaphore
+ *
+ * Input Parameters:
+ *   max  - No mean
+ *   init - semaphore initialization value
+ *
+ * Returned Value:
+ *   Semaphore data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_semphr_create(uint32_t max, uint32_t init)
+{
+  int ret;
+  sem_t *sem;
+  int tmp;
+
+  tmp = sizeof(sem_t);
+  sem = kmm_malloc(tmp);
+  if (!sem)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = nxsem_init(sem, 0, init);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize sem error=%d\n", ret);
+      kmm_free(sem);
+      return NULL;
+    }
+
+  return sem;
+}
+
+/****************************************************************************
+ * Name: esp_semphr_delete
+ *
+ * Description:
+ *   Delete semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_semphr_delete(void *semphr)
+{
+  sem_t *sem = (sem_t *)semphr;
+
+  nxsem_destroy(sem);
+  kmm_free(sem);
+}
+
+/****************************************************************************
+ * Name: esp_semphr_take
+ *
+ * Description:
+ *   Wait semaphore within a certain period of time
+ *
+ * Input Parameters:
+ *   semphr - Semaphore data pointer
+ *   ticks  - Wait system ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_semphr_take(void *semphr, uint32_t ticks)
+{
+  int ret;
+  struct timespec timeout;
+  sem_t *sem = (sem_t *)semphr;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING)
+    {
+      ret = nxsem_wait(sem);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to wait sem\n");
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = nxsem_timedwait(sem, &timeout);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to wait sem in %lu ticks\n", ticks);
+        }
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_semphr_give
+ *
+ * Description:
+ *   Post semaphore
+ *
+ * Input Parameters:
+ *   semphr - Semaphore data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_semphr_give(void *semphr)
+{
+  int ret;
+  sem_t *sem = (sem_t *)semphr;
+
+  ret = nxsem_post(sem);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to post sem error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_thread_semphr_get
+ *
+ * Description:
+ *   Get thread self's semaphore
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Semaphore data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_thread_semphr_get(void)
+{
+  int ret;
+  void *sem;
+
+  if (g_wifi_tkey_init)
+  {
+    ret = pthread_key_create(&g_wifi_thread_key, esp_thread_semphr_free);
+    if (ret)
+      {
+        wlerr("ERROR: Failed to create pthread key\n");
+        return NULL;
+      }
+
+    g_wifi_tkey_init = true;
+  }
+
+  sem = pthread_getspecific(g_wifi_thread_key);
+  if (!sem)
+    {
+      sem = esp_semphr_create(1, 0);
+      if (!sem)
+        {
+          wlerr("ERROR: Failed to create semaphore\n");
+          return NULL;
+        }
+
+      ret = pthread_setspecific(g_wifi_thread_key, sem);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to set specific\n");
+          esp_semphr_delete(sem);
+          return NULL;
+        }
+    }
+
+  return sem;
+}
+
+/****************************************************************************
+ * Name: esp_mutex_create
+ *
+ * Description:
+ *   Create mutex
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Mutex data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_mutex_create(void)
+{
+  int ret;
+  pthread_mutex_t *mutex;
+  int tmp;
+
+  tmp = sizeof(pthread_mutex_t);
+  mutex = kmm_malloc(tmp);
+  if (!mutex)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = pthread_mutex_init(mutex, NULL);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize mutex error=%d\n", ret);
+      kmm_free(mutex);
+      return NULL;
+    }
+
+  return mutex;
+}
+
+/****************************************************************************
+ * Name: esp_recursive_mutex_create
+ *
+ * Description:
+ *   Create recursive mutex
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Recursive mutex data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_recursive_mutex_create(void)
+{
+  int ret;
+  pthread_mutex_t *mutex;
+  pthread_mutexattr_t attr;
+  int tmp;
+
+  ret = pthread_mutexattr_init(&attr);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize attr error=%d\n", ret);
+      return NULL;
+    }
+
+  ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to set attr type error=%d\n", ret);
+      return NULL;
+    }
+
+  tmp = sizeof(pthread_mutex_t);
+  mutex = kmm_malloc(tmp);
+  if (!mutex)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return NULL;
+    }
+
+  ret = pthread_mutex_init(mutex, &attr);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize mutex error=%d\n", ret);
+      kmm_free(mutex);
+      return NULL;
+    }
+
+  return mutex;
+}
+
+/****************************************************************************
+ * Name: esp_mutex_delete
+ *
+ * Description:
+ *   Delete mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_mutex_delete(void *mutex_data)
+{
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  pthread_mutex_destroy(mutex);
+  kmm_free(mutex);
+}
+
+/****************************************************************************
+ * Name: esp_mutex_lock
+ *
+ * Description:
+ *   Lock mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_mutex_lock(void *mutex_data)
+{
+  int ret;
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  ret = pthread_mutex_lock(mutex);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to lock mutex error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_mutex_unlock
+ *
+ * Description:
+ *   Unlock mutex
+ *
+ * Input Parameters:
+ *   mutex_data - mutex data pointer
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_mutex_unlock(void *mutex_data)
+{
+  int ret;
+  pthread_mutex_t *mutex = (pthread_mutex_t *)mutex_data;
+
+  ret = pthread_mutex_unlock(mutex);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to unlock mutex error=%d\n", ret);
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_queue_create
+ *
+ * Description:
+ *   Create message queue
+ *
+ * Input Parameters:
+ *   queue_len - queue message number
+ *   item_size - message size
+ *
+ * Returned Value:
+ *   Message queue data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_queue_create(uint32_t queue_len, uint32_t item_size)
+{
+  struct mq_attr attr;
+  struct mq_adpt *mq_adpt;
+  int ret;
+
+  mq_adpt = kmm_malloc(sizeof(struct mq_adpt));
+  if (!mq_adpt)
+    {
+      wlerr("ERROR: Failed to kmm_malloc\n");
+      return NULL;
+    }
+
+  snprintf(mq_adpt->name, sizeof(mq_adpt->name),
+           "/tmp/%p", mq_adpt);
+
+  attr.mq_maxmsg  = queue_len;
+  attr.mq_msgsize = item_size;
+  attr.mq_curmsgs = 0;
+  attr.mq_flags   = 0;
+
+  ret = file_mq_open(&mq_adpt->mq, mq_adpt->name,
+                     O_RDWR | O_CREAT, 0644, &attr);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create mqueue\n");
+      kmm_free(mq_adpt);
+      return NULL;
+    }
+
+  mq_adpt->msgsize = item_size;
+
+  return (void *)mq_adpt;
+}
+
+/****************************************************************************
+ * Name: esp_queue_delete
+ *
+ * Description:
+ *   Delete message queue
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_queue_delete(void *queue)
+{
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  file_mq_close(&mq_adpt->mq);
+  file_mq_unlink(mq_adpt->name);
+  kmm_free(mq_adpt);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_generic
+ *
+ * Description:
+ *   Generic send message to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *   prio  - Message priority
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_generic(void *queue, void *item,
+                                      uint32_t ticks, int prio)
+{
+  int ret;
+  struct timespec timeout;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING || ticks == 0)
+    {
+      /* Wi-Fi interrupt function will call this adapter function to send
+       * message to message queue, so here we should call kernel API
+       * instead of application API
+       */
+
+      ret = file_mq_send(&mq_adpt->mq, (const char *)item,
+                         mq_adpt->msgsize, prio);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to send message to mqueue error=%d\n",
+               ret);
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = file_mq_timedsend(&mq_adpt->mq, (const char *)item,
+                              mq_adpt->msgsize, prio, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to timedsend message to mqueue error=%d\n",
+               ret);
+        }
+    }
+
+  return esp_errno_trans(ret);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send
+ *
+ * Description:
+ *   Send message of low priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send(void *queue, void *item, uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_from_isr
+ *
+ * Description:
+ *   Send message of low priority to queue in ISR within
+ *   a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   hptw  - No mean
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_from_isr(void *queue, void *item, void *hptw)
+{
+  /* Force to set the value to be false */
+
+  *((int *)hptw) = false;
+
+  return esp_queue_send_generic(queue, item, 0, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_to_back
+ *
+ * Description:
+ *   Send message of low priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_to_back(void *queue, void *item,
+                                      uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 0);
+}
+
+/****************************************************************************
+ * Name: esp_queue_send_from_to_front
+ *
+ * Description:
+ *   Send message of high priority to queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_send_to_front(void *queue, void *item,
+                                       uint32_t ticks)
+{
+  return esp_queue_send_generic(queue, item, ticks, 1);
+}
+
+/****************************************************************************
+ * Name: esp_queue_recv
+ *
+ * Description:
+ *   Receive message from queue within a certain period of time
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *   item  - Message data pointer
+ *   ticks - Wait ticks
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_queue_recv(void *queue, void *item, uint32_t ticks)
+{
+  ssize_t ret;
+  struct timespec timeout;
+  unsigned int prio;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  if (ticks == OSI_FUNCS_TIME_BLOCKING)
+    {
+      ret = file_mq_receive(&mq_adpt->mq, (char *)item,
+                            mq_adpt->msgsize, &prio);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to receive from mqueue error=%d\n", ret);
+        }
+    }
+  else
+    {
+      ret = clock_gettime(CLOCK_REALTIME, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to get time\n");
+          return false;
+        }
+
+      if (ticks)
+        {
+          esp_update_time(&timeout, ticks);
+        }
+
+      ret = file_mq_timedreceive(&mq_adpt->mq, (char *)item,
+                                 mq_adpt->msgsize, &prio, &timeout);
+      if (ret < 0)
+        {
+          wlerr("ERROR: Failed to timedreceive from mqueue error=%d\n",
+               ret);
+        }
+    }
+
+  return ret > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: esp_queue_msg_waiting
+ *
+ * Description:
+ *   Get message number in the message queue
+ *
+ * Input Parameters:
+ *   queue - Message queue data pointer
+ *
+ * Returned Value:
+ *   Message number
+ *
+ ****************************************************************************/
+
+static uint32_t esp_queue_msg_waiting(void *queue)
+{
+  int ret;
+  struct mq_attr attr;
+  struct mq_adpt *mq_adpt = (struct mq_adpt *)queue;
+
+  ret = file_mq_getattr(&mq_adpt->mq, &attr);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to get attr from mqueue error=%d\n", ret);
+      return 0;
+    }
+
+  return attr.mq_curmsgs;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_create
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void *esp_event_group_create(void)
+{
+  DEBUGASSERT(0);
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_delete
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_event_group_delete(void *event)
+{
+  DEBUGASSERT(0);
+}
+
+/****************************************************************************
+ * Name: esp_event_group_set_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_set_bits(void *event, uint32_t bits)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_clear_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_clear_bits(void *event, uint32_t bits)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_event_group_wait_bits
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_event_group_wait_bits(void *event,
+                                          uint32_t bits_to_wait_for,
+                                          int clear_on_exit,
+                                          int wait_for_all_bits,
+                                          uint32_t block_time_tick)
+{
+  DEBUGASSERT(0);
+
+  return false;
+}
+
+/****************************************************************************
+ * Name: esp_task_create_pinned_to_core
+ *
+ * Description:
+ *   Create task and bind it to target CPU, the task will run when it
+ *   is created
+ *
+ * Input Parameters:
+ *   entry       - Task entry
+ *   name        - Task name
+ *   stack_depth - Task stack size
+ *   param       - Task private data
+ *   prio        - Task priority
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *   core_id     - CPU which the task runs in
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_create_pinned_to_core(void *entry,
+                                              const char *name,
+                                              uint32_t stack_depth,
+                                              void *param,
+                                              uint32_t prio,
+                                              void *task_handle,
+                                              uint32_t core_id)
+{
+  int pid;
+
+  pid = kthread_create(name, prio, stack_depth, entry,
+                      (char * const *)param);
+  if (pid > 0)
+    {
+      if (task_handle)
+        {
+          *((int *)task_handle) = pid;
+        }
+    }
+  else
+    {
+      wlerr("ERROR: Failed to create task\n");
+    }
+
+  return pid > 0 ? true : false;
+}
+
+/****************************************************************************
+ * Name: esp_task_create
+ *
+ * Description:
+ *   Create task and the task will run when it is created
+ *
+ * Input Parameters:
+ *   entry       - Task entry
+ *   name        - Task name
+ *   stack_depth - Task stack size
+ *   param       - Task private data
+ *   prio        - Task priority
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *
+ * Returned Value:
+ *   True if success or false if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_create(void *entry, const char *name,
+                               uint32_t stack_depth, void *param,
+                               uint32_t prio, void *task_handle)
+{
+  return esp_task_create_pinned_to_core(entry, name, stack_depth, param,
+                                        prio, task_handle, UINT32_MAX);
+}
+
+/****************************************************************************
+ * Name: esp_task_delete
+ *
+ * Description:
+ *   Delete the target task
+ *
+ * Input Parameters:
+ *   task_handle - Task handle pointer which is used to pause, resume
+ *                 and delete the task
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_task_delete(void *task_handle)
+{
+  pid_t pid = (pid_t)((uintptr_t)task_handle);
+
+  kthread_delete(pid);
+}
+
+/****************************************************************************
+ * Name: esp_task_delay
+ *
+ * Description:
+ *   Current task wait for some ticks
+ *
+ * Input Parameters:
+ *   tick - Waiting ticks
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_task_delay(uint32_t tick)
+{
+  useconds_t us = TICK2USEC(tick);
+
+  nxsig_usleep(us);
+}
+
+/****************************************************************************
+ * Name: esp_task_ms_to_tick
+ *
+ * Description:
+ *   Transform from millim seconds to system ticks
+ *
+ * Input Parameters:
+ *   ms - Millim seconds
+ *
+ * Returned Value:
+ *   System ticks
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_ms_to_tick(uint32_t ms)
+{
+  return MSEC2TICK(ms);
+}
+
+/****************************************************************************
+ * Name: esp_task_get_current_task
+ *
+ * Description:
+ *   Transform from millim seconds to system ticks
+ *
+ * Input Parameters:
+ *   ms - Millim seconds
+ *
+ * Returned Value:
+ *   System ticks
+ *
+ ****************************************************************************/
+
+static void *esp_task_get_current_task(void)
+{
+  pid_t pid = getpid();
+
+  return (void *)((uintptr_t)pid);
+}
+
+/****************************************************************************
+ * Name: esp_task_get_max_priority
+ *
+ * Description:
+ *   Get OS task maximum priority
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Task maximum priority
+ *
+ ****************************************************************************/
+
+static int32_t esp_task_get_max_priority(void)
+{
+  return SCHED_PRIORITY_MAX;
+}
+
+/****************************************************************************
+ * Name: esp_malloc
+ *
+ * Description:
+ *   Allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_malloc(unsigned int size)
+{
+  return kmm_malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_free
+ *
+ * Description:
+ *   Free a block of memory
+ *
+ * Input Parameters:
+ *   ptr - memory block
+ *
+ * Returned Value:
+ *   No
+ *
+ ****************************************************************************/
+
+static void esp_free(void *ptr)
+{
+#ifdef CONFIG_XTENSA_IMEM_USE_SEPARATE_HEAP
+  if (xtensa_imm_heapmember(ptr))
+    {
+      xtensa_imm_free(ptr);
+    }
+  else
+#endif
+    {
+      kmm_free(ptr);
+    }
+}
+
+/****************************************************************************
+ * Name: esp_event_id_map
+ *
+ * Description:
+ *   Transform from esp-idf event ID to Wi-Fi adapter event ID
+ *
+ * Input Parameters:
+ *   event_id - esp-idf event ID
+ *
+ * Returned Value:
+ *   Wi-Fi adapter event ID
+ *
+ ****************************************************************************/
+
+static int esp_event_id_map(int event_id)
+{
+  int id;
+
+  switch (event_id)
+    {
+      case WIFI_EVENT_STA_START:
+        id = WIFI_ADPT_EVT_STA_START;
+        break;
+      case WIFI_EVENT_STA_CONNECTED:
+        id = WIFI_ADPT_EVT_STA_CONNECT;
+        break;
+      case WIFI_EVENT_STA_DISCONNECTED:
+        id = WIFI_ADPT_EVT_STA_DISCONNECT;
+        break;
+      case WIFI_EVENT_STA_AUTHMODE_CHANGE:
+        id = WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE;
+        break;
+      case WIFI_EVENT_STA_STOP:
+        id = WIFI_ADPT_EVT_STA_STOP;
+        break;
+      default:
+        return -1;
+    }
+
+  return id;
+}
+
+/****************************************************************************
+ * Name: esp_evt_work_cb
+ *
+ * Description:
+ *   Process the cached event
+ *
+ * Input Parameters:
+ *   arg - No mean
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_evt_work_cb(FAR void *arg)
+{
+  int ret;
+  irqstate_t flags;
+  struct evt_adpt *evt_adpt;
+  struct wifi_notify *notify;
+
+  while (1)
+    {
+      flags = enter_critical_section();
+      evt_adpt = (struct evt_adpt *)sq_remfirst(&g_wifi_evt_queue);
+      leave_critical_section(flags);
+      if (!evt_adpt)
+        {
+          break;
+        }
+
+      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)
+              {
+                wlerr("ERROR: Failed to connect\n");
+              }
+            break;
+          case WIFI_ADPT_EVT_STA_CONNECT:
+            g_connected = true;
+            ret = nxsem_post(&g_connect_sem);
+            if (ret)
+              {
+                wlerr("ERROR: Failed to post sem error=%d\n", ret);
+              }
+            break;
+          case WIFI_ADPT_EVT_STA_DISCONNECT:
+            g_connected = false;
+            ret = esp_wifi_connect();
+            if (ret)
+              {
+                wlerr("ERROR: Failed to connect\n");
+              }
+            break;
+          default:
+            break;
+        }
+
+      esp_event_lock(true);
+
+      notify = &g_wifi_notify[evt_adpt->id];
+      if (notify->assigned)
+        {
+          notify->event.sigev_value.sival_ptr = evt_adpt->buf;
+
+          ret = nxsig_notification(notify->pid, &notify->event,
+                                   SI_QUEUE, &notify->work);
+          if (ret < 0)
+            {
+              wlwarn("ERROR: nxsig_notification event ID=%ld failed: %d\n",
+                     evt_adpt->id, ret);
+            }
+        }
+
+      esp_event_lock(false);
+
+      kmm_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=%" PRId32 ", intr_source=%" PRIu32
+         ", intr_num=%" PRIu32 ", intr_prio=%" PRId32 "\n",
+         cpu_no, intr_source, intr_num, intr_prio);
+
+  esp32c3_bind_irq(intr_num, intr_source, intr_prio, ESP32C3_INT_LEVEL);
+}
+
+/****************************************************************************
+ * 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:
+ *   Active work queue and let the work to process the cached event
+ *
+ * Input Parameters:
+ *   event_base      - Event set name
+ *   event_id        - Event ID
+ *   event_data      - Event private data
+ *   event_data_size - Event data size
+ *   ticks           - Waiting system ticks
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_event_post(esp_event_base_t event_base,
+                         int32_t event_id,
+                         void *event_data,
+                         size_t event_data_size,
+                         uint32_t ticks)
+{
+  size_t size;
+  int32_t id;
+  irqstate_t flags;
+  struct evt_adpt *evt_adpt;
+
+  wlinfo("Event: base=%s id=%ld data=%p data_size=%u ticks=%lu\n",
+         event_base, event_id, event_data, event_data_size, ticks);
+
+  id = esp_event_id_map(event_id);
+  if (id < 0)
+    {
+      wlerr("ERROR: No process event %ld\n", event_id);
+      return -1;
+    }
+
+  size = event_data_size + sizeof(struct evt_adpt);
+  evt_adpt = kmm_malloc(size);
+  if (!evt_adpt)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", size);
+      return -1;
+    }
+
+  evt_adpt->id = id;
+  memcpy(evt_adpt->buf, event_data, event_data_size);
+
+  flags = enter_critical_section();
+  sq_addlast(&evt_adpt->entry, &g_wifi_evt_queue);
+  leave_critical_section(flags);
+
+  work_queue(LPWORK, &g_wifi_evt_work, esp_evt_work_cb, NULL, 0);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_event_post_wrap
+ *
+ * Description:
+ *   Active work queue and let the work to process the cached event
+ *
+ * Input Parameters:
+ *   event_base      - Event set name
+ *   event_id        - Event ID
+ *   event_data      - Event private data
+ *   event_data_size - Event data size
+ *   ticks           - Waiting system ticks
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int32_t esp_event_post_wrap(esp_event_base_t event_base,
+                                   int32_t event_id,
+                                   void *event_data,
+                                   size_t event_data_size,
+                                   uint32_t ticks)
+{
+  return (int32_t)esp_event_post(event_base, event_id, event_data,
+                                 event_data_size, ticks);
+}
+
+/****************************************************************************
+ * Name: esp_get_free_heap_size
+ *
+ * Description:
+ *   Get free heap size by byte
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Free heap size
+ *
+ ****************************************************************************/
+
+uint32_t esp_get_free_heap_size(void)
+{
+  int ret;
+  struct mallinfo info;
+
+  ret = mm_mallinfo(&g_mmheap, &info);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to create task\n");
+      return 0;
+    }
+
+  return info.fordblks;
+}
+
+/****************************************************************************
+ * Name: esp_dport_access_stall_other_cpu_start
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_dport_access_stall_other_cpu_start(void)
+{
+}
+
+/****************************************************************************
+ * Name: esp_dport_access_stall_other_cpu_end
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_dport_access_stall_other_cpu_end(void)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_apb80m_request
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_apb80m_request(void)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_apb80m_release
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_apb80m_release(void)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_phy_disable
+ *
+ * Description:
+ *   Deinitialize PHY hardware
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_phy_disable(void)
+{
+  irqstate_t flags;
+  flags = enter_critical_section();
+
+  g_phy_access_ref--;
+
+  if (g_phy_access_ref == 0)
+    {
+      /* Disable PHY and RF. */
+
+      phy_close_rf();
+
+      /* Disable Wi-Fi/BT common peripheral clock.
+       * Do not disable clock for hardware RNG.
+       */
+
+      esp_phy_disable_clock();
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: wifi_phy_enable
+ *
+ * Description:
+ *   Initialize PHY hardware
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_phy_enable(void)
+{
+  irqstate_t flags;
+  esp_phy_calibration_data_t *cal_data;
+
+  cal_data = kmm_zalloc(sizeof(esp_phy_calibration_data_t));
+  if (!cal_data)
+    {
+      wlerr("ERROR: Failed to kmm_zalloc");
+      DEBUGASSERT(0);
+    }
+
+  flags = enter_critical_section();
+
+  if (g_phy_access_ref == 0)
+    {
+      /* Update time stamp */
+
+      g_phy_rf_en_ts = esp_timer_get_time();
+
+      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);
+}
+
+/****************************************************************************
+ * Name: esp_phy_enable_clock
+ *
+ * Description:
+ *   Enable PHY hardware clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_phy_enable_clock(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  if (g_phy_clk_en_cnt == 0)
+    {
+      modifyreg32(SYSTEM_WIFI_CLK_EN_REG, 0,
+                  SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M);
+    }
+
+  g_phy_clk_en_cnt++;
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: esp_phy_disable_clock
+ *
+ * Description:
+ *   Disable PHY hardware clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_phy_disable_clock(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  if (g_phy_clk_en_cnt)
+    {
+      g_phy_clk_en_cnt--;
+      if (!g_phy_clk_en_cnt)
+        {
+          modifyreg32(SYSTEM_WIFI_CLK_EN_REG,
+                      SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M,
+                      0);
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: wifi_phy_update_country_info
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_phy_update_country_info(const char *country)
+{
+  return -1;
+}
+
+/****************************************************************************
+ * Name: esp_read_mac
+ *
+ * Description:
+ *   Read MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *   type - MAC address type
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_read_mac(uint8_t *mac, esp_mac_type_t type)
+{
+  uint32_t regval[2];
+  uint8_t tmp;
+  uint8_t *data = (uint8_t *)regval;
+  int i;
+
+  if (type > ESP_MAC_WIFI_SOFTAP)
+    {
+      wlerr("ERROR: Input type is error=%d\n", type);
+      return -1;
+    }
+
+  regval[0] = getreg32(MAC_ADDR0_REG);
+  regval[1] = getreg32(MAC_ADDR1_REG);
+
+  for (i = 0; i < 6; i++)
+    {
+      mac[i] = data[5 - i];
+    }
+
+  if (type == ESP_MAC_WIFI_SOFTAP)
+    {
+      tmp = mac[0];
+      for (i = 0; i < 64; i++)
+        {
+          mac[0] = tmp | 0x02;
+          mac[0] ^= i << 2;
+
+          if (mac[0] != tmp)
+            {
+              break;
+            }
+        }
+
+      if (i >= 64)
+        {
+          wlerr("ERROR: Failed to generate softAP MAC\n");
+          return -1;
+        }
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_read_mac
+ *
+ * Description:
+ *   Read MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *   type - MAC address type
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_wifi_read_mac(uint8_t *mac, uint32_t type)
+{
+  return esp_read_mac(mac, type);
+}
+
+/****************************************************************************
+ * Name: ets_timer_arm
+ *
+ * Description:
+ *   Set timer timeout period and repeat flag
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *   ms     - millim seconds
+ *   repeat - true: run cycle, false: run once
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void ets_timer_arm(void *ptimer, uint32_t ms, bool repeat)
+{
+  ets_timer_arm_us(ptimer, ms * 1000, repeat);
+}
+
+/****************************************************************************
+ * Name: ets_timer_disarm
+ *
+ * Description:
+ *   Disable timer
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void ets_timer_disarm(void *ptimer)
+{
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+  esp_timer_handle_t esp_timer = (esp_timer_handle_t)ets_timer->priv;
+
+  if (ets_timer->expire == TIMER_INITIALIZED_VAL)
+    {
+      esp_timer_stop(esp_timer);
+    }
+}
+
+/****************************************************************************
+ * Name: ets_timer_done
+ *
+ * Description:
+ *   Disable and free timer
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void ets_timer_done(void *ptimer)
+{
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+  esp_timer_handle_t esp_timer = (esp_timer_handle_t)ets_timer->priv;
+
+  if (ets_timer->expire == TIMER_INITIALIZED_VAL)
+    {
+      ets_timer->expire = 0;
+      esp_timer_delete(esp_timer);
+      ets_timer->priv = NULL;
+    }
+}
+
+/****************************************************************************
+ * Name: ets_timer_setfn
+ *
+ * Description:
+ *   Set timer callback function and private data
+ *
+ * Input Parameters:
+ *   ptimer    - Timer data pointer
+ *   pfunction - Callback function
+ *   parg      - Callback function private data
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void ets_timer_setfn(void *ptimer, void *pfunction, void *parg)
+{
+  int ret;
+  esp_timer_handle_t esp_timer;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+
+  if (ets_timer->expire != TIMER_INITIALIZED_VAL)
+    {
+      ets_timer->priv = NULL;
+    }
+
+  if (ets_timer->priv == NULL)
+    {
+      const esp_timer_create_args_t create_args =
+        {
+          .callback = pfunction,
+          .arg = parg,
+          .name = "ETSTimer",
+          .dispatch_method = ESP_TIMER_TASK
+        };
+
+      ret = esp_timer_create(&create_args, &esp_timer);
+      if (ret)
+        {
+          wlerr("ERROR: Failed to create ets_timer error=%d\n", ret);
+        }
+      else
+        {
+          ets_timer->priv = esp_timer;
+          ets_timer->expire = TIMER_INITIALIZED_VAL;
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: ets_timer_arm_us
+ *
+ * Description:
+ *   Set timer timeout period and repeat flag
+ *
+ * Input Parameters:
+ *   ptimer - timer data pointer
+ *   us     - micro seconds
+ *   repeat - true: run cycle, false: run once
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void ets_timer_arm_us(void *ptimer, uint32_t us, bool repeat)
+{
+  int ret;
+  struct ets_timer *ets_timer = (struct ets_timer *)ptimer;
+  esp_timer_handle_t esp_timer = (esp_timer_handle_t)ets_timer->priv;
+
+  if (ets_timer->expire == TIMER_INITIALIZED_VAL)
+    {
+      esp_timer_stop(esp_timer);
+      if (!repeat)
+        {
+          ret = esp_timer_start_once(esp_timer, us);
+        }
+      else
+        {
+          ret = esp_timer_start_periodic(esp_timer, us);
+        }
+
+      if (ret)
+        {
+          wlerr("ERROR: Fail to start %s timer error%d\n",
+                repeat ? "periodic" : "once",
+                ret);
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: wifi_reset_mac
+ *
+ * Description:
+ *   Reset Wi-Fi hardware MAC
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_reset_mac(void)
+{
+  modifyreg32(SYSCON_WIFI_RST_EN_REG, 0, SYSTEM_MAC_RST);
+  modifyreg32(SYSCON_WIFI_RST_EN_REG, SYSTEM_MAC_RST, 0);
+}
+
+/****************************************************************************
+ * Name: wifi_clock_enable
+ *
+ * Description:
+ *   Enable Wi-Fi clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_clock_enable(void)
+{
+  modifyreg32(SYSTEM_WIFI_CLK_EN_REG, 0, SYSTEM_WIFI_CLK_WIFI_EN_M);
+}
+
+/****************************************************************************
+ * Name: wifi_clock_disable
+ *
+ * Description:
+ *   Disable Wi-Fi clock
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wifi_clock_disable(void)
+{
+  modifyreg32(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_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:
+ *   Get system time of type int64_t
+ *
+ * Input Parameters:
+ *   periph - No mean
+ *
+ * Returned Value:
+ *   System time
+ *
+ ****************************************************************************/
+
+int64_t esp_timer_get_time(void)
+{
+  return (int64_t)rt_timer_time_us();
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_i8
+ *
+ * Description:
+ *   Save data of type int8_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_set_i8(uint32_t handle,
+                              const char *key,
+                              int8_t value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(int8_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_i8
+ *
+ * Description:
+ *   Read data of type int8_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_get_i8(uint32_t handle,
+                              const char *key,
+                              int8_t *out_value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  size_t len = sizeof(int8_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_u8
+ *
+ * Description:
+ *   Save data of type uint8_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_set_u8(uint32_t handle,
+                              const char *key,
+                              uint8_t value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(uint8_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_u8
+ *
+ * Description:
+ *   Read data of type uint8_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_get_u8(uint32_t handle,
+                              const char *key,
+                              uint8_t *out_value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  size_t len = sizeof(uint8_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_u16
+ *
+ * Description:
+ *   Save data of type uint16_t into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored data
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_set_u16(uint32_t handle,
+                               const char *key,
+                               uint16_t value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  return esp_nvs_set_blob(handle, key, &value, sizeof(uint16_t));
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_u16
+ *
+ * Description:
+ *   Read data of type uint16_t from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_get_u16(uint32_t handle,
+                               const char *key,
+                               uint16_t *out_value)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  size_t len = sizeof(uint16_t);
+
+  return esp_nvs_get_blob(handle, key, out_value, &len);
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_open
+ *
+ * Description:
+ *   Create a file system storage data object
+ *
+ * Input Parameters:
+ *   name       - Storage index
+ *   open_mode  - Storage mode
+ *   out_handle - Storage handle
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_open(const char *name,
+                            uint32_t open_mode,
+                            uint32_t *out_handle)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  int ret;
+  struct nvs_adpt *nvs_adpt;
+  int tmp;
+  char *index_name;
+
+  tmp = sizeof(struct nvs_adpt);
+  nvs_adpt = kmm_malloc(tmp);
+  if (!nvs_adpt)
+    {
+      wlerr("ERROR: Failed to alloc %d memory\n", tmp);
+      return -1;
+    }
+
+  ret = asprintf(&index_name, "%s", name);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS index_name string\n");
+      kmm_free(nvs_adpt);
+      return -1;
+    }
+
+  nvs_adpt->index_name = index_name;
+  *out_handle = (uint32_t)nvs_adpt;
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_close
+ *
+ * Description:
+ *   Close storage data object and free resource
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static void esp_nvs_close(uint32_t handle)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+
+  kmm_free(nvs_adpt->index_name);
+  kmm_free(nvs_adpt);
+#else
+  DEBUGASSERT(0);
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_commit
+ *
+ * Description:
+ *   This function has no practical effect
+ *
+ ****************************************************************************/
+
+static int esp_nvs_commit(uint32_t handle)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_nvs_set_blob
+ *
+ * Description:
+ *   Save a block of data into file system
+ *
+ * Input Parameters:
+ *   handle - NVS handle
+ *   key    - Data index
+ *   value  - Stored buffer pointer
+ *   length - Buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_set_blob(uint32_t handle,
+                                const char *key,
+                                const void *value,
+                                size_t length)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  struct file file;
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  ret = nx_unlink(dir);
+  if (ret)
+    {
+      if (ret != -ENOENT)
+        {
+          wlerr("ERROR: Failed to unlink %s error=%d\n", dir, ret);
+          kmm_free(dir);
+          return -1;
+        }
+    }
+
+  ret = file_open(&file, dir, O_WRONLY | O_CREAT, NVS_FILE_MODE);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to set open %s\n", dir);
+      kmm_free(dir);
+      return -1;
+    }
+
+  ret = file_write(&file, value, length);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to write to %s\n", dir);
+      kmm_free(dir);
+      file_close(&file);
+      return -1;
+    }
+
+  kmm_free(dir);
+  file_close(&file);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_get_blob
+ *
+ * Description:
+ *   Read a block of data from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *   out_value - Read buffer pointer
+ *   length    - Buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_get_blob(uint32_t handle,
+                                const char *key,
+                                void *out_value,
+                                size_t *length)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  struct file file;
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  ret = file_open(&file, dir, O_RDONLY);
+  if (ret < 0)
+    {
+      if (ret == -ENOENT)
+        {
+          wlinfo("INFO: No file %s\n", dir);
+          kmm_free(dir);
+          return ESP_ERR_NVS_NOT_FOUND;
+        }
+      wlerr("ERROR: Failed to get open %s\n", dir);
+      kmm_free(dir);
+      return -1;
+    }
+
+  ret = file_read(&file, out_value, *length);
+  if (ret <= 0)
+    {
+      wlerr("ERROR: Failed to write to %s\n", dir);
+      kmm_free(dir);
+      file_close(&file);
+      return -1;
+    }
+  else
+    {
+      *length = ret;
+    }
+
+  kmm_free(dir);
+  file_close(&file);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_nvs_erase_key
+ *
+ * Description:
+ *   Read a block of data from file system
+ *
+ * Input Parameters:
+ *   handle    - NVS handle
+ *   key       - Data index
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_nvs_erase_key(uint32_t handle, const char *key)
+{
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  int ret;
+  char *dir;
+  struct nvs_adpt *nvs_adpt = (struct nvs_adpt *)handle;
+  char *index_name = nvs_adpt->index_name;
+
+  ret = asprintf(&dir, NVS_DIR_BASE"%s.%s", index_name, key);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to create NVS dir string\n");
+      return -1;
+    }
+
+  ret = nx_unlink(dir);
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to delete NVS file %s\n", dir);
+      kmm_free(dir);
+      return -1;
+    }
+
+  kmm_free(dir);
+
+  return 0;
+#else
+  DEBUGASSERT(0);
+
+  return -1;
+#endif
+}
+
+/****************************************************************************
+ * Name: esp_fill_random
+ *
+ * Description:
+ *   Fill random data int given buffer of given length
+ *
+ * Input Parameters:
+ *   buf - buffer pointer
+ *   len - buffer length
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+void esp_fill_random(void *buf, size_t len)
+{
+  uint8_t *p = (uint8_t *)buf;
+  uint32_t tmp;
+  uint32_t n;
+
+  while (len > 0)
+    {
+      tmp = random();
+      n = len < 4 ? len : 4;
+
+      memcpy(p, &tmp, n);
+
+      p += n;
+      len -= n;
+    }
+}
+
+/****************************************************************************
+ * Name: esp_get_random
+ *
+ * Description:
+ *   Fill random data int given buffer of given length
+ *
+ * Input Parameters:
+ *   buf - buffer pointer
+ *   len - buffer length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_get_random(uint8_t *buf, size_t len)
+{
+  esp_fill_random(buf, len);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_get_time
+ *
+ * Description:
+ *   Get std C time
+ *
+ * Input Parameters:
+ *   t - buffer to store time of type timeval
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+static int esp_get_time(void *t)
+{
+  int ret;
+  struct timeval tv;
+  struct time_adpt *time_adpt = (struct time_adpt *)t;
+
+  ret = gettimeofday(&tv, NULL);
+  if (!ret)
+    {
+      time_adpt->sec  = (time_t)tv.tv_sec;
+      time_adpt->usec = (suseconds_t)tv.tv_usec;
+    }
+  else
+    {
+      wlerr("ERROR: Failed to get time of day\n");
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_clk_slowclk_cal_get_wrapper
+ ****************************************************************************/
+
+static uint32_t esp_clk_slowclk_cal_get_wrapper(void)
+{
+    return 28639;
+}
+
+/****************************************************************************
+ * Name: esp_rand
+ *
+ * Description:
+ *   Get random data of type uint32_t
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Random data
+ *
+ ****************************************************************************/
+
+static uint32_t esp_rand(void)
+{
+  return random();
+}
+
+/****************************************************************************
+ * Name: esp_log_writev
+ *
+ * Description:
+ *   Output log with by format string and its arguments
+ *
+ * Input Parameters:
+ *   level  - log level, no mean here
+ *   tag    - log TAG, no mean here
+ *   format - format string
+ *   args   - arguments list
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_log_writev(uint32_t level, const char *tag,
+                           const char *format, va_list args)
+{
+  switch (level)
+    {
+#ifdef CONFIG_DEBUG_WIRELESS_ERROR
+      case ESP_LOG_ERROR:
+        vsyslog(LOG_ERR, format, args);
+        break;
+#endif
+#ifdef CONFIG_DEBUG_WIRELESS_WARN
+      case ESP_LOG_WARN:
+        vsyslog(LOG_WARNING, format, args);
+        break;
+#endif
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+      case ESP_LOG_INFO:
+        vsyslog(LOG_INFO, format, args);
+        break;
+      default:
+        vsyslog(LOG_DEBUG, format, args);
+        break;
+#endif
+    }
+}
+
+/****************************************************************************
+ * Name: esp_log_write
+ *
+ * Description:
+ *   Output log with by format string and its arguments
+ *
+ * Input Parameters:
+ *   level  - log level, no mean here
+ *   tag    - log TAG, no mean here
+ *   format - format string
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_log_write(uint32_t level,
+                   const char *tag,
+                   const char *format, ...)
+{
+  va_list list;
+  va_start(list, format);
+  esp_log_writev(level, tag, format, list);
+  va_end(list);
+}
+
+/****************************************************************************
+ * Name: esp_log_timestamp
+ *
+ * Description:
+ *   Get system time by millim second
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   System time
+ *
+ ****************************************************************************/
+
+uint32_t esp_log_timestamp(void)
+{
+  return (uint32_t)(esp_timer_get_time() / 1000);
+}
+
+/****************************************************************************
+ * Name: esp_malloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_malloc_internal(size_t size)
+{
+  return kmm_malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_realloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory by old memory block
+ *
+ * Input Parameters:
+ *   ptr  - old memory pointer
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_realloc_internal(void *ptr, size_t size)
+{
+  return kmm_realloc(ptr, size);
+}
+
+/****************************************************************************
+ * Name: esp_calloc_internal
+ *
+ * Description:
+ *   Drivers allocate some continuous blocks of memory
+ *
+ * Input Parameters:
+ *   n    - memory block number
+ *   size - memory block size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_calloc_internal(size_t n, size_t size)
+{
+  return kmm_calloc(n, size);
+}
+
+/****************************************************************************
+ * Name: esp_zalloc_internal
+ *
+ * Description:
+ *   Drivers allocate a block of memory and clear it with 0
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_zalloc_internal(size_t size)
+{
+  return kmm_zalloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_malloc
+ *
+ * Description:
+ *   Applications allocate a block of memory
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   Memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_malloc(size_t size)
+{
+  return kmm_malloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_realloc
+ *
+ * Description:
+ *   Applications allocate a block of memory by old memory block
+ *
+ * Input Parameters:
+ *   ptr  - old memory pointer
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_realloc(void *ptr, size_t size)
+{
+  return kmm_realloc(ptr, size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_calloc
+ *
+ * Description:
+ *   Applications allocate some continuous blocks of memory
+ *
+ * Input Parameters:
+ *   n    - memory block number
+ *   size - memory block size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_calloc(size_t n, size_t size)
+{
+  return kmm_calloc(n, size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_zalloc
+ *
+ * Description:
+ *   Applications allocate a block of memory and clear it with 0
+ *
+ * Input Parameters:
+ *   size - memory size
+ *
+ * Returned Value:
+ *   New memory pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_zalloc(size_t size)
+{
+  return kmm_zalloc(size);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_create_queue
+ *
+ * Description:
+ *   Create Wi-Fi static message queue
+ *
+ * Input Parameters:
+ *   queue_len - queue message number
+ *   item_size - message size
+ *
+ * Returned Value:
+ *   Wi-Fi static message queue data pointer
+ *
+ ****************************************************************************/
+
+static void *esp_wifi_create_queue(int queue_len, int item_size)
+{
+  wifi_static_queue_t *wifi_queue;
+
+  wifi_queue = kmm_malloc(sizeof(wifi_static_queue_t));
+  if (!wifi_queue)
+    {
+      wlerr("ERROR: Failed to kmm_malloc\n");
+      return NULL;
+    }
+
+  wifi_queue->handle = esp_queue_create(queue_len, item_size);
+  if (!wifi_queue->handle)
+    {
+      wlerr("ERROR: Failed to create queue\n");
+      kmm_free(wifi_queue);
+      return NULL;
+    }
+
+  return wifi_queue;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_delete_queue
+ *
+ * Description:
+ *   Delete Wi-Fi static message queue
+ *
+ * Input Parameters:
+ *   queue - Wi-Fi static message queue data pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void esp_wifi_delete_queue(void *queue)
+{
+  wifi_static_queue_t *wifi_queue = (wifi_static_queue_t *)queue;
+
+  esp_queue_delete(wifi_queue->handle);
+  kmm_free(wifi_queue);
+}
+
+/****************************************************************************
+ * Name: wifi_coex_init
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_init(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_deinit
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_coex_deinit(void)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_coex_enable
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_enable(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_disable
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_coex_disable(void)
+{
+}
+
+/****************************************************************************
+ * Name: esp_coex_status_get
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t esp_coex_status_get(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_coex_condition_set
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void esp_coex_condition_set(uint32_t type, bool dissatisfy)
+{
+}
+
+/****************************************************************************
+ * Name: esp_coex_wifi_request
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int esp_coex_wifi_request(uint32_t event, uint32_t latency,
+                                     uint32_t duration)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_coex_wifi_release
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int esp_coex_wifi_release(uint32_t event)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * 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: wifi_coex_get_event_duration
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_get_event_duration(uint32_t event, uint32_t *duration)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_pti
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_get_pti(uint32_t event, uint8_t *pti)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_clear_schm_status_bit
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_coex_clear_schm_status_bit(uint32_t type, uint32_t status)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_coex_set_schm_status_bit
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void wifi_coex_set_schm_status_bit(uint32_t type, uint32_t status)
+{
+}
+
+/****************************************************************************
+ * Name: wifi_coex_set_schm_interval
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_set_schm_interval(uint32_t interval)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_schm_interval
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint32_t wifi_coex_get_schm_interval(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_schm_curr_period
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static uint8_t wifi_coex_get_schm_curr_period(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_schm_curr_phase
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static void *wifi_coex_get_schm_curr_phase(void)
+{
+  return NULL;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_set_schm_curr_phase_idx
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_set_schm_curr_phase_idx(int idx)
+{
+  return -1;
+}
+
+/****************************************************************************
+ * Name: wifi_coex_get_schm_curr_phase_idx
+ *
+ * Description:
+ *   Don't support
+ *
+ ****************************************************************************/
+
+static int wifi_coex_get_schm_curr_phase_idx(void)
+{
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_random_ulong
+ ****************************************************************************/
+
+static unsigned long esp_random_ulong(void)
+{
+  return random();
+}
+
+/****************************************************************************
+ * Functions needed by libphy.a
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_dport_access_reg_read
+ *
+ * Description:
+ *   Read regitser value safely in SMP
+ *
+ * Input Parameters:
+ *   reg - Register address
+ *
+ * Returned Value:
+ *   Register value
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR esp_dport_access_reg_read(uint32_t reg)
+{
+  return getreg32(reg);
+}
+
+/****************************************************************************
+ * Name: phy_enter_critical
+ *
+ * Description:
+ *   Enter critical state
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   CPU PS value
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR phy_enter_critical(void)
+{
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  return flags;
+}
+
+/****************************************************************************
+ * Name: phy_exit_critical
+ *
+ * Description:
+ *   Exit from critical state
+ *
+ * Input Parameters:
+ *   level - CPU PS value
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR phy_exit_critical(uint32_t level)
+{
+  leave_critical_section(level);
+}
+
+/****************************************************************************
+ * Name: phy_printf
+ *
+ * Description:
+ *   Output format string and its arguments
+ *
+ * Input Parameters:
+ *   format - format string
+ *
+ * Returned Value:
+ *   0
+ *
+ ****************************************************************************/
+
+int phy_printf(const char *format, ...)
+{
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+  va_list arg;
+
+  va_start(arg, format);
+  vsyslog(LOG_INFO, format, arg);
+  va_end(arg);
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: pp_printf
+ *
+ * Description:
+ *   Output format string and its arguments
+ *
+ * Input Parameters:
+ *   format - format string
+ *
+ * Returned Value:
+ *   0
+ *
+ ****************************************************************************/
+
+int pp_printf(const char *format, ...)
+{
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+  va_list arg;
+
+  va_start(arg, format);
+  vsyslog(LOG_INFO, format, arg);
+  va_end(arg);
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * Functions needed by libnet80211.a
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: net80211_printf
+ *
+ * Description:
+ *   Output format string and its arguments
+ *
+ * Input Parameters:
+ *   format - format string
+ *
+ * Returned Value:
+ *   0
+ *
+ ****************************************************************************/
+
+int net80211_printf(const char *format, ...)
+{
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+  va_list arg;
+
+  va_start(arg, format);
+  vsyslog(LOG_INFO, format, arg);
+  va_end(arg);
+#endif
+
+  return 0;
+}
+
+/****************************************************************************
+ * Functions needed by libmesh.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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_timer_create
+ *
+ * Description:
+ *   Create timer with given arguments
+ *
+ * Input Parameters:
+ *   create_args - Timer arguments data pointer
+ *   out_handle  - Timer handle pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_timer_create(const esp_timer_create_args_t *create_args,
+                           esp_timer_handle_t *out_handle)
+{
+  int ret;
+  struct rt_timer_args_s rt_timer_args;
+  struct rt_timer_s *rt_timer;
+
+  rt_timer_args.arg = create_args->arg;
+  rt_timer_args.callback = create_args->callback;
+
+  ret = rt_timer_create(&rt_timer_args, &rt_timer);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to create rt_timer error=%d\n", ret);
+      return ret;
+    }
+
+  *out_handle = (esp_timer_handle_t)rt_timer;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_timer_start_once
+ *
+ * Description:
+ *   Start timer with one shot mode
+ *
+ * Input Parameters:
+ *   timer      - Timer handle pointer
+ *   timeout_us - Timeout value by micro second
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_timer_start_once(esp_timer_handle_t timer, uint64_t timeout_us)
+{
+  struct rt_timer_s *rt_timer = (struct rt_timer_s *)timer;
+
+  DEBUGASSERT(timeout_us <= UINT32_MAX);
+
+  rt_timer_start(rt_timer, timeout_us, false);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_timer_start_periodic
+ *
+ * Description:
+ *   Start timer with periodic mode
+ *
+ * Input Parameters:
+ *   timer  - Timer handle pointer
+ *   period - Timeout value by micro second
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
+{
+  struct rt_timer_s *rt_timer = (struct rt_timer_s *)timer;
+
+  DEBUGASSERT(period <= UINT32_MAX);
+
+  rt_timer_start(rt_timer, period, true);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_timer_stop
+ *
+ * Description:
+ *   Stop timer
+ *
+ * Input Parameters:
+ *   timer  - Timer handle pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_timer_stop(esp_timer_handle_t timer)
+{
+  struct rt_timer_s *rt_timer = (struct rt_timer_s *)timer;
+
+  rt_timer_stop(rt_timer);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_timer_delete
+ *
+ * Description:
+ *   Delete timer and free resource
+ *
+ * Input Parameters:
+ *   timer  - Timer handle pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_timer_delete(esp_timer_handle_t timer)
+{
+  struct rt_timer_s *rt_timer = (struct rt_timer_s *)timer;
+
+  rt_timer_delete(rt_timer);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: __assert_func
+ *
+ * Description:
+ *   Delete timer and free resource
+ *
+ * Input Parameters:
+ *   file  - assert file
+ *   line  - assert line
+ *   func  - assert function
+ *   expr  - assert condition
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+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();
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_event_send_internal
+ *
+ * Description:
+ *   Post event message to queue
+ *
+ * Input Parameters:
+ *   event_base      - Event set name
+ *   event_id        - Event ID
+ *   event_data      - Event private data
+ *   event_data_size - Event data size
+ *   ticks_to_wait   - Waiting system ticks
+ *
+ * Returned Value:
+ *   Task maximum priority
+ *
+ ****************************************************************************/
+
+esp_err_t esp_event_send_internal(esp_event_base_t event_base,
+                                  int32_t event_id,
+                                  void *event_data,
+                                  size_t event_data_size,
+                                  uint32_t ticks_to_wait)
+{
+  int32_t ret;
+
+  ret = esp_event_post(event_base, event_id, event_data,
+                       event_data_size, ticks_to_wait);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_init
+ *
+ * Description:
+ *   Initialize Wi-Fi
+ *
+ * Input Parameters:
+ *   config - Initialization config parameters
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_wifi_init(const wifi_init_config_t *config)
+{
+  esp_err_t ret;
+
+  ret = esp_wifi_init_internal(config);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize Wi-Fi error=%d\n", ret);
+      return -1;
+    }
+
+  ret = esp_supplicant_init();
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize WPA supplicant error=%d\n", ret);
+      esp_wifi_deinit_internal();
+      return -1;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_deinit
+ *
+ * Description:
+ *   Deinitialize Wi-Fi and free resource
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+esp_err_t esp_wifi_deinit(void)
+{
+  int ret;
+
+  ret = esp_supplicant_deinit();
+  if (ret)
+    {
+      wlerr("ERROR: Failed to deinitialize supplicant\n");
+      return ret;
+    }
+
+  ret = esp_wifi_deinit_internal();
+  if (ret != 0)
+    {
+      wlerr("ERROR: Failed to deinitialize Wi-Fi\n");
+      return ret;
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_sta_send_data
+ *
+ * Description:
+ *   Use Wi-Fi station interface to send 802.3 frame
+ *
+ * Input Parameters:
+ *   pbuf - Packet buffer pointer
+ *   len  - Packet length
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_send_data(void *pbuf, uint32_t len)
+{
+  int ret;
+
+  ret = esp_wifi_internal_tx(WIFI_IF_STA, pbuf, len);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_sta_register_recv_cb
+ *
+ * Description:
+ *   Register Wi-Fi receive packet callback function
+ *
+ * Input Parameters:
+ *   input_cb - Receive callback function
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_register_recv_cb(int (*recv_cb)(void *buffer,
+                                                 uint16_t len,
+                                                 void *eb))
+{
+  int ret;
+
+  ret = esp_wifi_internal_reg_rxcb(ESP_IF_WIFI_STA, (wifi_rxcb_t)recv_cb);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_sta_read_mac
+ *
+ * Description:
+ *   Read station interface MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_read_mac(uint8_t *mac)
+{
+  return esp_read_mac(mac, ESP_MAC_WIFI_STA);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_free_eb
+ *
+ * Description:
+ *   Free Wi-Fi receive callback input eb pointer
+ *
+ * Input Parameters:
+ *   eb - Wi-Fi receive callback input eb pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_wifi_free_eb(void *eb)
+{
+  esp_wifi_internal_free_rx_buffer(eb);
+}
+
+/****************************************************************************
+ * Name: esp_wifi_notify_subscribe
+ *
+ * Description:
+ *   Enable event notification
+ *
+ * Input Parameters:
+ *   pid   - Task PID
+ *   event - Signal event data pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_notify_subscribe(pid_t pid, FAR struct sigevent *event)
+{
+  int id;
+  struct wifi_notify *notify;
+  int ret = -1;
+
+  wlinfo("PID=%d event=%p\n", pid, event);
+
+  esp_event_lock(true);
+
+  if (event->sigev_notify == SIGEV_SIGNAL)
+    {
+      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 if (event->sigev_notify == SIGEV_NONE)
+    {
+      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 not subscribed\n",
+                    event->sigev_signo);
+            }
+          else
+            {
+              notify->assigned = false;
+
+              ret = 0;
+            }
+        }
+    }
+  else
+    {
+      wlerr("ERROR: sigev_notify %d is invalid\n", event->sigev_signo);
+    }
+
+  esp_event_lock(false);
+
+  return ret;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_adapter_init
+ *
+ * Description:
+ *   Initialize ESP32C3 Wi-Fi adapter
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_adapter_init(void)
+{
+  int ret;
+  wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
+
+  ret = esp32c3_rt_timer_init();
+  if (ret < 0)
+    {
+      wlerr("ERROR: Failed to initialize RT timer error=%d\n", ret);
+      return -1;
+    }
+
+#ifdef CONFIG_ESP32C3_WIFI_SAVE_PARAM
+  wifi_cfg.nvs_enable = 1;
+#else
+  wifi_cfg.nvs_enable = 0;
+#endif
+
+#ifdef CONFIG_ESP32C3_WIFI_TX_AMPDU
+  wifi_cfg.ampdu_tx_enable = 1;
+#else
+  wifi_cfg.ampdu_tx_enable = 0;
+#endif
+
+#ifdef CONFIG_ESP32C3_WIFI_RX_AMPDU
+  wifi_cfg.ampdu_rx_enable = 1;
+#else
+  wifi_cfg.ampdu_rx_enable = 0;
+#endif
+
+  wifi_cfg.rx_ba_win          = CONFIG_ESP32C3_WIFI_RXBA_AMPDU_WZ;
+  wifi_cfg.static_rx_buf_num  = CONFIG_ESP32C3_WIFI_STATIC_RXBUF_NUM;
+  wifi_cfg.dynamic_rx_buf_num = CONFIG_ESP32C3_WIFI_DYNAMIC_RXBUF_NUM;
+  wifi_cfg.dynamic_tx_buf_num = CONFIG_ESP32C3_WIFI_DYNAMIC_TXBUF_NUM;
+
+  modifyreg32(SYSTEM_WIFI_CLK_EN_REG, 0, UINT32_MAX);
+
+  ret = esp_wifi_init(&wifi_cfg);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to initialize Wi-Fi error=%d\n", ret);
+      esp32c3_rt_timer_deinit();
+      return -1;
+    }
+
+  sq_init(&g_wifi_evt_queue);
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_set_password
+ *
+ * Description:
+ *   Set Wi-Fi password
+ *
+ * Input Parameters:
+ *   pdata - Password buffer pointer
+ *   len   - Password length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_set_password(const uint8_t *pdata, uint8_t len)
+{
+  memcpy(g_password, pdata, len);
+  g_password_len = len;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_set_ssid
+ *
+ * Description:
+ *   Set Wi-Fi SSID
+ *
+ * Input Parameters:
+ *   pdata - SSID buffer pointer
+ *   len   - SSID length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_set_ssid(const uint8_t *pdata, uint8_t len)
+{
+  memcpy(g_ssid, pdata, len);
+  g_ssid_len = len;
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: esp_wifi_connect_internal
+ *
+ * Description:
+ *   Trigger Wi-Fi connection action
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_connect_internal(void)
+{
+  int ret;
+  wifi_config_t wifi_cfg;
+  struct timespec timeout;
+
+  if (g_connected)
+    {
+      wlinfo("INFO: Wi-Fi has connected AP\n");
+      return 0;
+    }
+
+  ret = esp_wifi_set_mode(WIFI_MODE_STA);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to set station mode error=%d\n", ret);
+      esp_wifi_deinit();
+      return -1;
+    }
+
+  memset(&wifi_cfg, 0, sizeof(wifi_config_t));
+  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)
+    {
+      wlerr("ERROR: Failed to set Wi-Fi config error=%d\n", ret);
+      return -1;
+    }
+
+  ret = esp_wifi_start();
+  if (ret)
+    {
+      wlerr("ERROR: Failed to set start config error=%d\n", ret);
+      return -1;
+    }
+
+  clock_gettime(CLOCK_REALTIME, &timeout);
+  timeout.tv_sec += WIFI_CONNECT_TIMEOUT;
+  ret = nxsem_timedwait(&g_connect_sem, &timeout);
+  if (ret)
+    {
+      wlerr("ERROR: Failed to wait sem error=%d\n", ret);
+      esp_wifi_stop();
+      return -1;
+    }
+
+  if (!g_connected)
+    {
+      wlerr("ERROR: Process connection error\n");
+      esp_wifi_stop();
+      return -1;
+    }
+
+  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/risc-v/src/esp32c3/esp32c3_wifi_adapter.h b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
new file mode 100644
index 0000000000..a1bd411b7b
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
@@ -0,0 +1,242 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_wifi_adapter.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WIFI_ADAPTER_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WIFI_ADAPTER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Wi-Fi event ID */
+
+enum wifi_adpt_evt_e
+{
+  WIFI_ADPT_EVT_STA_START = 0,
+  WIFI_ADPT_EVT_STA_CONNECT,
+  WIFI_ADPT_EVT_STA_DISCONNECT,
+  WIFI_ADPT_EVT_STA_AUTHMODE_CHANGE,
+  WIFI_ADPT_EVT_STA_STOP,
+  WIFI_ADPT_EVT_MAX,
+};
+
+/* Wi-Fi event callback function */
+
+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
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp_wifi_adapter_init
+ *
+ * Description:
+ *   Initialize ESP32 Wi-Fi adapter
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_adapter_init(void);
+
+/****************************************************************************
+ * Name: esp_wifi_notify_subscribe
+ *
+ * Description:
+ *   Enable event notification
+ *
+ * Input Parameters:
+ *   pid   - Task PID
+ *   event - Signal event data pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_notify_subscribe(pid_t pid, FAR struct sigevent *event);
+
+/****************************************************************************
+ * Name: esp_wifi_sta_send_data
+ *
+ * Description:
+ *   Use Wi-Fi station interface to send 802.3 frame
+ *
+ * Input Parameters:
+ *   pbuf - Packet buffer pointer
+ *   len  - Packet length
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_send_data(void *pbuf, uint32_t len);
+
+/****************************************************************************
+ * Name: esp_wifi_sta_register_recv_cb
+ *
+ * Description:
+ *   Register Wi-Fi receive packet callback function
+ *
+ * Input Parameters:
+ *   input_cb - Receive callback function
+ *
+ * Returned Value:
+ *   0 if success or others if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_register_recv_cb(int (*recv_cb)(void *buffer,
+                                                 uint16_t len,
+                                                 void *eb));
+
+/****************************************************************************
+ * Name: esp_wifi_sta_read_mac
+ *
+ * Description:
+ *   Read station interface MAC address from efuse
+ *
+ * Input Parameters:
+ *   mac  - MAC address buffer pointer
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_sta_read_mac(uint8_t *mac);
+
+/****************************************************************************
+ * Name: esp_wifi_free_eb
+ *
+ * Description:
+ *   Free Wi-Fi receive callback input eb pointer
+ *
+ * Input Parameters:
+ *   eb - Wi-Fi receive callback input eb pointer
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+void esp_wifi_free_eb(void *eb);
+
+/****************************************************************************
+ * Name: esp_wifi_set_password
+ *
+ * Description:
+ *   Set Wi-Fi password
+ *
+ * Input Parameters:
+ *   pdata - Password buffer pointer
+ *   len   - Password length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_set_password(const uint8_t *pdata, uint8_t len);
+
+/****************************************************************************
+ * Name: esp_wifi_set_ssid
+ *
+ * Description:
+ *   Set Wi-Fi SSID
+ *
+ * Input Parameters:
+ *   pdata - SSID buffer pointer
+ *   len   - SSID length
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+int esp_wifi_set_ssid(const uint8_t *pdata, uint8_t len);
+
+/****************************************************************************
+ * Name: esp_wifi_connect_internal
+ *
+ * Description:
+ *   Trigger Wi-Fi connection action
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   0 if success or -1 if fail
+ *
+ ****************************************************************************/
+
+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
+#undef EXTERN
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WIFI_ADAPTER_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.c b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
new file mode 100644
index 0000000000..50d1306634
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.c
@@ -0,0 +1,1487 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_wlan.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#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/arp.h>
+#include <nuttx/net/netdev.h>
+#if defined(CONFIG_NET_PKT)
+#  include <nuttx/net/pkt.h>
+#endif
+
+#include "esp32c3_wifi_adapter.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* WLAN station device ID */
+
+#define WLAN_STA_DEVNO            (0)
+
+/* TX poll delay = 1 seconds.
+ * CLK_TCK is the number of clock ticks per second
+ */
+
+#define WLAN_WDDELAY              (1 * CLK_TCK)
+
+/* TX timeout = 1 minute */
+
+#define WLAN_TXTOUT               (60 * CLK_TCK)
+
+/* Low-priority work queue processes RX/TX */
+
+#define WLAN_WORK                 LPWORK
+
+/* Ethernet frame:
+ *     Resource address   :   6 bytes
+ *     Destination address:   6 bytes
+ *     Type               :   2 bytes
+ *     Payload            :   MAX 1500
+ *     Checksum           :   Ignore
+ *
+ *     Total size         :   1514
+ */
+
+#define WLAN_BUF_SIZE             (CONFIG_NET_ETH_PKTSIZE)
+
+/* Wi-Fi receive buffer number */
+
+#define WLAN_RXBUF_NUM            (CONFIG_ESP32C3_WLAN_RXBUF_NUM)
+
+/* Receive threshold which allows the receive function to trigger a scheduler
+ * to activate the application if possible.
+ */
+
+#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
+ ****************************************************************************/
+
+/* 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 wlan_priv_s
+{
+  bool   ifup;                  /* true:ifup false:ifdown */
+
+  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 dev;
+
+  /* TX buffer */
+
+  uint8_t       txbuf[WLAN_BUF_SIZE];
+
+  /* Rest of the data in the TX buffer that need to be sent */
+
+  uint8_t       txrst;
+
+  /* RX buffer cache */
+
+  struct wlan_rxbuf  rxbuf[WLAN_RXBUF_NUM];
+
+  /* RX buffer queue */
+
+  sq_queue_t    rxb;
+
+  /* Free buffer queue */
+
+  sq_queue_t    freeb;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct wlan_priv_s g_wlan_priv;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Common TX logic */
+
+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 wlan_txtimeout_work(FAR void *arg);
+static void wlan_txtimeout_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 wlan_ifup(struct net_driver_s *dev);
+static int wlan_ifdown(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 wlan_addmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+#ifdef CONFIG_NET_MCASTGROUP
+static int wlan_rmmac(struct net_driver_s *dev, FAR const uint8_t *mac);
+#endif
+
+#ifdef CONFIG_NETDEV_IOCTL
+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);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Note:
+ *     All TX done/RX done/Error trigger functions are not called from
+ *     interrupts, this is much different from ethernet driver, including:
+ *       * wlan_rx_done
+ *       * wlan_tx_done
+ *
+ *     These functions are called in a Wi-Fi private thread. So we just use
+ *     mutex/semaphore instead of disable interrupt, if necessary.
+ */
+
+/****************************************************************************
+ * Function: wlan_init_buffer
+ *
+ * Description:
+ *   Initialize the free buffer list
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void wlan_init_buffer(struct wlan_priv_s *priv)
+{
+  int i;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  priv->txrst = 0;
+
+  priv->dev.d_buf = NULL;
+  priv->dev.d_len = 0;
+
+  sq_init(&priv->freeb);
+  sq_init(&priv->rxb);
+
+  for (i = 0; i < WLAN_RXBUF_NUM; i++)
+    {
+      sq_addlast(&priv->rxbuf[i].entry, &priv->freeb);
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Function: wlan_alloc_buffer
+ *
+ * Description:
+ *   Allocate one buffer from the free buffer queue
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   Pointer to the allocated buffer on success; NULL on failure
+ *
+ ****************************************************************************/
+
+static inline struct wlan_rxbuf *wlan_alloc_buffer(struct wlan_priv_s *priv)
+{
+  sq_entry_t *entry;
+  irqstate_t flags;
+  struct wlan_rxbuf *rxbuf = NULL;
+
+  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: wlan_free_buffer
+ *
+ * Description:
+ *   Insert a free Rx buffer into the free queue
+ *
+ * Input Parameters:
+ *   priv   - Reference to the driver state structure
+ *   buffer - A pointer to the buffer to be freed
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static inline void wlan_free_buffer(struct wlan_priv_s *priv,
+                                    uint8_t *buffer)
+{
+  struct wlan_rxbuf *rxbuf;
+  irqstate_t flags;
+
+  flags = enter_critical_section();
+
+  rxbuf = container_of(buffer, struct wlan_rxbuf, buffer);
+  sq_addlast(&rxbuf->entry, &priv->freeb);
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: wifi_tx_available
+ *
+ * Description:
+ *   Check if Wi-Fi can send data. This function will re-send the rest of the
+ *   data that we failed to send.
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   true if available or false if unavailable
+ *
+ ****************************************************************************/
+
+static bool wifi_tx_available(FAR struct wlan_priv_s *priv)
+{
+  int ret;
+
+  if (priv->txrst)
+    {
+      ret = esp_wifi_sta_send_data(priv->txbuf, priv->txrst);
+      if (ret)
+        {
+          ninfo("ERROR: Failed to transmit the rest of the frame\n");
+          return false;
+        }
+      else
+        {
+          priv->txrst = 0;
+        }
+    }
+
+  return true;
+}
+
+/****************************************************************************
+ * Name: wlan_transmit
+ *
+ * Description:
+ *   Send the data to Wi-Fi 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
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int wlan_transmit(FAR struct wlan_priv_s *priv)
+{
+  int ret;
+  struct net_driver_s *dev = &priv->dev;
+  void *buffer = dev->d_buf;
+  uint32_t len = dev->d_len;
+
+  if (!wifi_tx_available(priv))
+    {
+      return -ENOBUFS;
+    }
+
+  ret = esp_wifi_sta_send_data(buffer, len);
+  if (ret)
+    {
+      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: wlan_recvframe
+ *
+ * Description:
+ *   Try to receive RX buffer from RX done buffer queue.
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
+ *
+ * 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:
+ *   Wi-Fi TX done callback function. If this is called, it means sending
+ *   next packet.
+ *
+ * Input Parameters:
+ *   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 successfully or false if failed.
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wlan_tx_done(uint8_t ifidx, uint8_t *data,
+                         uint16_t *len, bool status)
+{
+  FAR struct wlan_priv_s *priv = &g_wlan_priv;
+
+  wd_cancel(&priv->txtimeout);
+
+  wlan_txavail(&priv->dev);
+}
+
+/****************************************************************************
+ * Function: wlan_rx_done
+ *
+ * Description:
+ *   Wi-Fi RX done callback function. If this is called, it means receiving
+ *   packet.
+ *
+ * Input Parameters:
+ *   buffer - Wi-Fi received packet buffer
+ *   len    - Length of received packet
+ *   eb     - Wi-Fi 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;
+  int ret = 0;
+
+  if (!priv->ifup)
+    {
+      goto out;
+    }
+
+  if (len > WLAN_BUF_SIZE)
+    {
+      nwarn("ERROR: Wlan receive %d larger than %d\n",
+             len, WLAN_BUF_SIZE);
+      ret = -EINVAL;
+      goto out;
+    }
+
+  rxbuf = wlan_alloc_buffer(priv);
+  if (!rxbuf)
+    {
+      ret = -ENOBUFS;
+      goto out;
+    }
+
+  memcpy(rxbuf->buffer, buffer, len);
+  rxbuf->len = len;
+
+  if (eb)
+    {
+      esp_wifi_free_eb(eb);
+    }
+
+  flags = enter_critical_section();
+  sq_addlast(&rxbuf->entry, &priv->rxb);
+  leave_critical_section(flags);
+
+  if (work_available(&priv->rxwork))
+    {
+      work_queue(WLAN_WORK, &priv->rxwork, wlan_rxpoll, priv, 0);
+    }
+
+  return 0;
+
+out:
+  if (eb)
+    {
+      esp_wifi_free_eb(eb);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Function: wlan_rxpoll
+ *
+ * Description:
+ *   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
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wlan_rxpoll(FAR void *arg)
+{
+  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 wlan_recvframe() successfully retrieves valid
+   * Ethernet frames.
+   */
+
+  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->dev);
+#endif
+
+      /* Check if the packet is a valid size for the network
+       * buffer configuration (this should not happen)
+       */
+
+      if (dev->d_len > WLAN_BUF_SIZE)
+        {
+          nwarn("WARNING: DROPPED Too big: %d\n", dev->d_len);
+
+          /* Free dropped packet buffer */
+
+          if (dev->d_buf)
+            {
+              wlan_free_buffer(priv, dev->d_buf);
+              dev->d_buf = NULL;
+              dev->d_len = 0;
+            }
+
+          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 (eth_hdr->type == HTONS(ETHTYPE_IP))
+        {
+          ninfo("IPv4 frame\n");
+
+          /* Handle ARP on input then give the IPv4 packet to the network
+           * layer
+           */
+
+          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->dev.d_len > 0)
+            {
+              /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv6
+              if (IFF_IS_IPv4(priv->dev.d_flags))
+#endif
+                {
+                  arp_out(&priv->dev);
+                }
+#ifdef CONFIG_NET_IPv6
+              else
+                {
+                  neighbor_out(&priv->dev);
+                }
+#endif
+
+              /* And send the packet */
+
+              wlan_transmit(priv);
+            }
+        }
+      else
+#endif
+#ifdef CONFIG_NET_IPv6
+      if (eth_hdr->type == HTONS(ETHTYPE_IP6))
+        {
+          ninfo("IPv6 frame\n");
+
+          /* Give the IPv6 packet to the network layer */
+
+          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->dev.d_len > 0)
+            {
+              /* Update the Ethernet header with the correct MAC address */
+
+#ifdef CONFIG_NET_IPv4
+              if (IFF_IS_IPv4(priv->dev.d_flags))
+                {
+                  arp_out(&priv->dev);
+                }
+              else
+#endif
+#ifdef CONFIG_NET_IPv6
+                {
+                  neighbor_out(&priv->dev);
+                }
+#endif
+
+              /* And send the packet */
+
+              wlan_transmit(priv);
+            }
+        }
+      else
+#endif
+#ifdef CONFIG_NET_ARP
+      if (eth_hdr->type == htons(ETHTYPE_ARP))
+        {
+          ninfo("ARP frame\n");
+
+          /* Handle ARP packet */
+
+          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->dev.d_len > 0)
+            {
+              wlan_transmit(priv);
+            }
+        }
+      else
+#endif
+        {
+          ninfo("INFO: Dropped, Unknown type: %04x\n", eth_hdr->type);
+        }
+
+      /* We are finished with the RX buffer.  NOTE:  If the buffer is
+       * re-used for transmission, the dev->d_buf field will have been
+       * nullified.
+       */
+
+      if (dev->d_buf)
+        {
+          /* Free the receive packet buffer */
+
+          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: wlan_txpoll
+ *
+ * Description:
+ *   The transmitter is available, check if the network has any outgoing
+ *   packets ready to send.  This is a callback from devif_poll().
+ *   devif_poll() may be called:
+ *
+ *   1. When the preceding TX packet send times out and the interface is
+ *      reset
+ *   2. During normal TX polling
+ *
+ * Input Parameters:
+ *   dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int wlan_txpoll(FAR struct net_driver_s *dev)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+  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 (dev->d_len > 0)
+    {
+      /* Look up the destination MAC address and add it to the Ethernet
+       * header.
+       */
+
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+      if (IFF_IS_IPv4(dev->d_flags))
+#endif
+        {
+          arp_out(dev);
+        }
+#endif /* CONFIG_NET_IPv4 */
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+      else
+#endif
+        {
+          neighbor_out(dev);
+        }
+#endif /* CONFIG_NET_IPv6 */
+
+      int ret = wlan_transmit(priv);
+      if (ret)
+        {
+          return -EBUSY;
+        }
+    }
+
+  /* If zero is returned, the polling will continue until
+   * all connections have been examined.
+   */
+
+  return OK;
+}
+
+/****************************************************************************
+ * 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 (wlan_txavail)
+ *   2. After a TX timeout to restart the sending process
+ *      (wlan_txtimeout_expiry).
+ *
+ * Input Parameters:
+ *   priv - Reference to the driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wlan_dopoll(FAR struct wlan_priv_s *priv)
+{
+  FAR struct net_driver_s *dev = &priv->dev;
+
+  if (!wifi_tx_available(priv))
+    {
+      return ;
+    }
+
+  dev->d_buf = priv->txbuf;
+
+  /* If so, then poll the network for new XMIT data */
+
+  devif_timer(dev, 0, wlan_txpoll);
+
+  dev->d_buf = NULL;
+}
+
+/****************************************************************************
+ * Function: wlan_txtimeout_work
+ *
+ * Description:
+ *   Perform TX timeout related work from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ ****************************************************************************/
+
+static void wlan_txtimeout_work(void *arg)
+{
+  struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
+
+  net_lock();
+
+  wlan_ifdown(&priv->dev);
+  wlan_ifup(&priv->dev);
+
+  /* Then poll for new XMIT data */
+
+  wlan_dopoll(priv);
+
+  net_unlock();
+}
+
+/****************************************************************************
+ * Function: wlan_txtimeout_expiry
+ *
+ * Description:
+ *   Our TX watchdog timed out.  Called from the timer callback handler.
+ *   The last TX never completed.  Reset the hardware and start again.
+ *
+ * Input Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wlan_txtimeout_expiry(wdparm_t arg)
+{
+  struct wlan_priv_s *priv = (struct wlan_priv_s *)arg;
+
+  /* Schedule to perform the TX timeout processing on the worker thread. */
+
+  if (work_available(&priv->toutwork))
+    {
+      work_queue(WLAN_WORK, &priv->toutwork, wlan_txtimeout_work, priv, 0);
+    }
+}
+
+/****************************************************************************
+ * Name: wlan_poll_work
+ *
+ * Description:
+ *   Perform periodic polling from the worker thread
+ *
+ * Input Parameters:
+ *   arg - The argument passed when work_queue() as called.
+ *
+ * Returned Value:
+ *   OK on success
+ *
+ * Assumptions:
+ *   The network is locked.
+ *
+ ****************************************************************************/
+
+static void wlan_poll_work(FAR void *arg)
+{
+  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
+   * is performed on an LP worker thread and where more than one LP worker
+   * thread has been configured.
+   */
+
+  net_lock();
+
+  /* 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 (!wifi_tx_available(priv))
+    {
+      delay = 1;
+      goto exit;
+    }
+
+  dev->d_buf = priv->txbuf;
+
+  /* Update TCP timing states and poll the network for new XMIT data. */
+
+  devif_timer(&priv->dev, delay, wlan_txpoll);
+
+  dev->d_buf = NULL;
+
+exit:
+  wd_start(&priv->txpoll, delay, wlan_poll_expiry, (wdparm_t)priv);
+
+  net_unlock();
+}
+
+/****************************************************************************
+ * Name: wlan_poll_expiry
+ *
+ * Description:
+ *   Periodic timer handler.  Called from the timer callback handler.
+ *
+ * Input Parameters:
+ *   argc - The number of available arguments
+ *   arg  - The first argument
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static void wlan_poll_expiry(wdparm_t arg)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)arg;
+
+  if (priv->ifup)
+    {
+      work_queue(WLAN_WORK, &priv->pollwork, wlan_poll_work, priv, 0);
+    }
+}
+
+/****************************************************************************
+ * 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
+ *   provided
+ *
+ * Input Parameters:
+ *   dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static int wlan_ifup(FAR struct net_driver_s *dev)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+#ifdef CONFIG_NET_IPv4
+  ninfo("Bringing up: %d.%d.%d.%d\n",
+        (uint8_t)(dev->d_ipaddr), (uint8_t)(dev->d_ipaddr >> 8),
+        (uint8_t)(dev->d_ipaddr >> 16), (uint8_t)(dev->d_ipaddr >> 24));
+#endif
+#ifdef CONFIG_NET_IPv6
+  winfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+        dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
+        dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
+        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 */
+
+  wlan_ipv6multicast(priv);
+#endif
+
+  wlan_init_buffer(priv);
+
+  /* Set and activate a timer process */
+
+  wd_start(&priv->txpoll, WLAN_WDDELAY, wlan_poll_expiry, (wdparm_t)priv);
+
+  priv->ifup = true;
+
+  net_unlock();
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wlan_ifdown
+ *
+ * Description:
+ *   NuttX Callback: Stop the interface.
+ *
+ * Input Parameters:
+ *   dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+static int wlan_ifdown(FAR struct net_driver_s *dev)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+  net_lock();
+
+  if (!priv->ifup)
+    {
+      net_unlock();
+      return OK;
+    }
+
+  /* Cancel the TX poll timer and TX timeout timers */
+
+  wd_cancel(&priv->txpoll);
+  wd_cancel(&priv->txtimeout);
+
+  /* Mark the device "down" */
+
+  priv->ifup = false;
+
+  net_unlock();
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wlan_txavail
+ *
+ * Description:
+ *   Driver callback invoked when new TX data is available.  This is a
+ *   stimulus perform an out-of-cycle poll and, thereby, reduce the TX
+ *   latency.
+ *
+ * Input Parameters:
+ *   dev - Reference to the NuttX driver state structure
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Called in normal user mode
+ *
+ ****************************************************************************/
+
+static int wlan_txavail(FAR struct net_driver_s *dev)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+  if (work_available(&priv->txwork))
+    {
+      /* Schedule to serialize the poll on the worker thread. */
+
+      work_queue(WLAN_WORK, &priv->txwork, wlan_txavail_work, priv, 0);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wlan_addmac
+ *
+ * Description:
+ *   NuttX Callback: Add the specified MAC address to the hardware multicast
+ *   address filtering
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *   mac  - The MAC address to be added
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_NET_MCASTGROUP) || defined(CONFIG_NET_ICMPv6)
+static int wlan_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+  /* Add the MAC address to the hardware multicast routing table */
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: wlan_rmmac
+ *
+ * Description:
+ *   NuttX Callback: Remove the specified MAC address from the
+ *   hardware multicast address filtering
+ *
+ * Input Parameters:
+ *   dev  - Reference to the NuttX driver state structure
+ *   mac  - The MAC address to be removed
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_MCASTGROUP
+static int wlan_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac)
+{
+  FAR struct wlan_priv_s *priv = (FAR struct wlan_priv_s *)dev->d_private;
+
+  /* Add the MAC address to the hardware multicast routing table */
+
+  return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: wlan_ipv6multicast
+ *
+ * Description:
+ *   Configure the IPv6 multicast MAC address.
+ *
+ * Input Parameters:
+ *   priv - A reference to the private driver state structure
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_ICMPv6
+static void wlan_ipv6multicast(FAR struct wlan_priv_s *priv)
+{
+  FAR struct net_driver_s *dev;
+  uint16_t tmp16;
+  uint8_t mac[6];
+
+  /* For ICMPv6, we need to add the IPv6 multicast address
+   *
+   * For IPv6 multicast addresses, the Ethernet MAC is derived by
+   * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00,
+   * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map
+   * to the Ethernet MAC address 33:33:00:01:00:03.
+   *
+   * NOTES:  This appears correct for the ICMPv6 Router Solicitation
+   * Message, but the ICMPv6 Neighbor Solicitation message seems to
+   * use 33:33:ff:01:00:03.
+   */
+
+  mac[0] = 0x33;
+  mac[1] = 0x33;
+
+  dev    = &priv->dev;
+  tmp16  = dev->d_ipv6addr[6];
+  mac[2] = 0xff;
+  mac[3] = tmp16 >> 8;
+
+  tmp16  = dev->d_ipv6addr[7];
+  mac[4] = tmp16 & 0xff;
+  mac[5] = tmp16 >> 8;
+
+  ninfo("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n",
+        mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+  wlan_addmac(dev, mac);
+
+#ifdef CONFIG_NET_ICMPv6_AUTOCONF
+  /* Add the IPv6 all link-local nodes Ethernet address.  This is the
+   * address that we expect to receive ICMPv6 Router Advertisement
+   * packets.
+   */
+
+  wlan_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet);
+#endif /* CONFIG_NET_ICMPv6_AUTOCONF */
+
+#ifdef CONFIG_NET_ICMPv6_ROUTER
+  /* Add the IPv6 all link-local routers Ethernet address.  This is the
+   * address that we expect to receive ICMPv6 Router Solicitation
+   * packets.
+   */
+
+  wlan_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet);
+#endif /* CONFIG_NET_ICMPv6_ROUTER */
+}
+#endif /* CONFIG_NET_ICMPv6 */
+
+/****************************************************************************
+ * Name: wlan_ioctl
+ *
+ * Description:
+ *   Handle network IOCTL commands directed to this device.
+ *
+ * Input Parameters:
+ *   dev - Reference to the NuttX driver state structure
+ *   cmd - The IOCTL command
+ *   arg - The argument for the IOCTL command
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NETDEV_IOCTL
+static int wlan_ioctl(FAR struct net_driver_s *dev,
+                      int cmd,
+                      unsigned long arg)
+{
+  int ret;
+  struct iw_point *essid;
+  struct iw_encode_ext *ext;
+  struct iwreq *iwr = (struct iwreq *)arg;
+
+  /* Decode and dispatch the driver-specific IOCTL command */
+
+  switch (cmd)
+    {
+#ifdef CONFIG_NETDEV_PHY_IOCTL
+#ifdef CONFIG_ARCH_PHY_INTERRUPT
+      case SIOCMIINOTIFY: /* Set up for PHY event notifications */
+        {
+          struct mii_ioctl_notify_s *req = (struct mii_ioctl_notify_s *)arg;
+          ret = esp_wifi_notify_subscribe(req->pid, &req->event);
+          if (ret)
+            {
+              nerr("ERROR: Failed to subscribe event\n");
+            }
+        }
+        break;
+#endif
+#endif
+
+      case SIOCSIWENCODEEXT:
+        {
+          ext = iwr->u.encoding.pointer;
+          ret = esp_wifi_set_password(ext->key, ext->key_len);
+          if (ret)
+            {
+              nerr("ERROR: Failed to set password\n");
+            }
+        }
+        break;
+      case SIOCSIWESSID:
+        {
+          iwr = (struct iwreq *)arg;
+          essid = &iwr->u.essid;
+          ret = esp_wifi_set_ssid(essid->pointer, essid->length);
+          if (ret)
+            {
+              nerr("ERROR: Failed to set SSID\n");
+              break;
+            }
+
+          ret = esp_wifi_connect_internal();
+          if (ret)
+            {
+              nerr("ERROR: Failed to start connecting\n");
+              break;
+            }
+        }
+        break;
+      case SIOCSIWMODE:
+        ret = OK;
+        break;
+      case SIOCSIWAUTH:
+        ret = OK;
+        break;
+      case SIOCSIWFREQ:
+        ret = OK;
+        break;
+      default:
+        nerr("ERROR: Unrecognized IOCTL command: %d\n", cmd);
+        ret = -ENOTTY;  /* Special return value for this case */
+        break;
+    }
+
+  return ret;
+}
+#endif  /* CONFIG_NETDEV_IOCTL */
+
+/****************************************************************************
+ * Name: esp32c3_net_initialize
+ *
+ * Description:
+ *   Initialize the ESP32-C3 driver
+ *
+ * Input Parameters:
+ *   devno - The device number.
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+static int esp32c3_net_initialize(unsigned int devno)
+{
+  int ret;
+  uint8_t eth_mac[6];
+  FAR struct wlan_priv_s *priv;
+
+  /* Get the interface structure associated with this interface number. */
+
+  priv = &g_wlan_priv;
+
+  /* Initialize the driver structure */
+
+  memset(priv, 0, sizeof(struct wlan_priv_s));
+
+  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->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->dev.d_ioctl   = wlan_ioctl;    /* Handle network IOCTL commands */
+#endif
+
+  /* Used to recover private state from dev */
+
+  priv->dev.d_private = (void *)&g_wlan_priv;
+
+  /* Create a watchdog for timing polling for and timing of transmissions */
+
+  esp_wifi_sta_read_mac(eth_mac);
+
+  memcpy(priv->dev.d_mac.ether.ether_addr_octet, eth_mac, sizeof(eth_mac));
+
+  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]);
+
+  /* Put the interface in the down state. */
+
+  wlan_ifdown(&priv->dev);
+
+  ret = netdev_register(&priv->dev, NET_LL_IEEE80211);
+  if (ret)
+    {
+      nerr("ERROR: Initialization of Ethernet block failed: %d\n", ret);
+      return ret;
+    }
+
+  ret = esp_wifi_adapter_init();
+  if (ret)
+    {
+      nerr("ERROR: Initialize Wi-Fi adapter error: %d\n", ret);
+      netdev_unregister(&priv->dev);
+      return ret;
+    }
+
+  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;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_wlan_sta_initialize
+ *
+ * Description:
+ *   Initialize the ESP32-C3 WLAN station netcard driver
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int esp32c3_wlan_sta_initialize(void)
+{
+  return esp32c3_net_initialize(WLAN_STA_DEVNO);
+}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_wlan.h b/arch/risc-v/src/esp32c3/esp32c3_wlan.h
new file mode 100644
index 0000000000..de93c468a1
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_wlan.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_wlan.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_wlan_sta_initialize
+ *
+ * Description:
+ *   Initialize the ESP32-C3 WLAN station netcard driver
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   OK on success; Negated errno on failure.
+ *
+ ****************************************************************************/
+
+int esp32c3_wlan_sta_initialize(void);
+
+#ifdef __cplusplus
+}
+#endif
+#undef EXTERN
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_WLAN_H */
diff --git a/arch/risc-v/src/esp32c3/hardware/esp32c3_syscon.h b/arch/risc-v/src/esp32c3/hardware/esp32c3_syscon.h
new file mode 100644
index 0000000000..568271cc33
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/esp32c3_syscon.h
@@ -0,0 +1,644 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/esp32c3_syscon.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_SYSCON_H
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_SYSCON_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_memorymap.h"
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SYSCON_SYSCLK_CONF_REG (DR_REG_SYSCON_BASE + 0x000)
+
+/* SYSCON_SOC_CLK_SEL : R/W ;bitpos:[15:14] ;default: 2'd0 ; */
+
+#define SYSCON_SOC_CLK_SEL 0x00000003
+#define SYSCON_SOC_CLK_SEL_M ((SYSCON_SOC_CLK_SEL_V) << (SYSCON_SOC_CLK_SEL_S))
+#define SYSCON_SOC_CLK_SEL_V 0x3
+#define SYSCON_SOC_CLK_SEL_S 14
+
+/* SYSCON_RST_TICK_CNT : R/W ;bitpos:[12] ;default: 1'b0 ; */
+
+#define SYSCON_RST_TICK_CNT (BIT(12))
+#define SYSCON_RST_TICK_CNT_M (BIT(12))
+#define SYSCON_RST_TICK_CNT_V 0x1
+#define SYSCON_RST_TICK_CNT_S 12
+
+/* SYSCON_CLK_EN : R/W ;bitpos:[11] ;default: 1'b0 ; */
+
+#define SYSCON_CLK_EN (BIT(11))
+#define SYSCON_CLK_EN_M (BIT(11))
+#define SYSCON_CLK_EN_V 0x1
+#define SYSCON_CLK_EN_S 11
+
+/* SYSCON_CLK_320M_EN : R/W ;bitpos:[10] ;default: 1'b0 ; */
+
+#define SYSCON_CLK_320M_EN (BIT(10))
+#define SYSCON_CLK_320M_EN_M (BIT(10))
+#define SYSCON_CLK_320M_EN_V 0x1
+#define SYSCON_CLK_320M_EN_S 10
+
+/* SYSCON_PRE_DIV_CNT : R/W ;bitpos:[9:0] ;default: 10'h1 ; */
+
+#define SYSCON_PRE_DIV_CNT 0x000003FF
+#define SYSCON_PRE_DIV_CNT_M ((SYSCON_PRE_DIV_CNT_V) << (SYSCON_PRE_DIV_CNT_S))
+#define SYSCON_PRE_DIV_CNT_V 0x3FF
+#define SYSCON_PRE_DIV_CNT_S 0
+
+#define SYSCON_TICK_CONF_REG (DR_REG_SYSCON_BASE + 0x004)
+
+/* SYSCON_TICK_ENABLE : R/W ;bitpos:[16] ;default: 1'd1 ; */
+
+#define SYSCON_TICK_ENABLE (BIT(16))
+#define SYSCON_TICK_ENABLE_M (BIT(16))
+#define SYSCON_TICK_ENABLE_V 0x1
+#define SYSCON_TICK_ENABLE_S 16
+
+/* SYSCON_CK8M_TICK_NUM : R/W ;bitpos:[15:8] ;default: 8'd7 ; */
+
+#define SYSCON_CK8M_TICK_NUM 0x000000FF
+#define SYSCON_CK8M_TICK_NUM_M ((SYSCON_CK8M_TICK_NUM_V) << (SYSCON_CK8M_TICK_NUM_S))
+#define SYSCON_CK8M_TICK_NUM_V 0xFF
+#define SYSCON_CK8M_TICK_NUM_S 8
+
+/* SYSCON_XTAL_TICK_NUM : R/W ;bitpos:[7:0] ;default: 8'd39 ; */
+
+#define SYSCON_XTAL_TICK_NUM 0x000000FF
+#define SYSCON_XTAL_TICK_NUM_M ((SYSCON_XTAL_TICK_NUM_V) << (SYSCON_XTAL_TICK_NUM_S))
+#define SYSCON_XTAL_TICK_NUM_V 0xFF
+#define SYSCON_XTAL_TICK_NUM_S 0
+
+#define SYSCON_CLK_OUT_EN_REG (DR_REG_SYSCON_BASE + 0x008)
+
+/* SYSCON_CLK_XTAL_OEN : R/W ;bitpos:[10] ;default: 1'b1 ; */
+
+#define SYSCON_CLK_XTAL_OEN (BIT(10))
+#define SYSCON_CLK_XTAL_OEN_M (BIT(10))
+#define SYSCON_CLK_XTAL_OEN_V 0x1
+#define SYSCON_CLK_XTAL_OEN_S 10
+
+/* SYSCON_CLK40X_BB_OEN : R/W ;bitpos:[9] ;default: 1'b1 ; */
+
+#define SYSCON_CLK40X_BB_OEN (BIT(9))
+#define SYSCON_CLK40X_BB_OEN_M (BIT(9))
+#define SYSCON_CLK40X_BB_OEN_V 0x1
+#define SYSCON_CLK40X_BB_OEN_S 9
+
+/* SYSCON_CLK_DAC_CPU_OEN : R/W ;bitpos:[8] ;default: 1'b1 ; */
+
+#define SYSCON_CLK_DAC_CPU_OEN (BIT(8))
+#define SYSCON_CLK_DAC_CPU_OEN_M (BIT(8))
+#define SYSCON_CLK_DAC_CPU_OEN_V 0x1
+#define SYSCON_CLK_DAC_CPU_OEN_S 8
+
+/* SYSCON_CLK_ADC_INF_OEN : R/W ;bitpos:[7] ;default: 1'b1 ; */
+
+#define SYSCON_CLK_ADC_INF_OEN (BIT(7))
+#define SYSCON_CLK_ADC_INF_OEN_M (BIT(7))
+#define SYSCON_CLK_ADC_INF_OEN_V 0x1
+#define SYSCON_CLK_ADC_INF_OEN_S 7
+
+/* SYSCON_CLK_320M_OEN : R/W ;bitpos:[6] ;default: 1'b1 ; */
+
+#define SYSCON_CLK_320M_OEN (BIT(6))
+#define SYSCON_CLK_320M_OEN_M (BIT(6))
+#define SYSCON_CLK_320M_OEN_V 0x1
+#define SYSCON_CLK_320M_OEN_S 6
+
+/* SYSCON_CLK160_OEN : R/W ;bitpos:[5] ;default: 1'b1 ; */
+
+#define SYSCON_CLK160_OEN (BIT(5))
+#define SYSCON_CLK160_OEN_M (BIT(5))
+#define SYSCON_CLK160_OEN_V 0x1
+#define SYSCON_CLK160_OEN_S 5
+
+/* SYSCON_CLK80_OEN : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+#define SYSCON_CLK80_OEN (BIT(4))
+#define SYSCON_CLK80_OEN_M (BIT(4))
+#define SYSCON_CLK80_OEN_V 0x1
+#define SYSCON_CLK80_OEN_S 4
+
+/* SYSCON_CLK_BB_OEN : R/W ;bitpos:[3] ;default: 1'b1 ; */
+
+#define SYSCON_CLK_BB_OEN (BIT(3))
+#define SYSCON_CLK_BB_OEN_M (BIT(3))
+#define SYSCON_CLK_BB_OEN_V 0x1
+#define SYSCON_CLK_BB_OEN_S 3
+
+/* SYSCON_CLK44_OEN : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+#define SYSCON_CLK44_OEN (BIT(2))
+#define SYSCON_CLK44_OEN_M (BIT(2))
+#define SYSCON_CLK44_OEN_V 0x1
+#define SYSCON_CLK44_OEN_S 2
+
+/* SYSCON_CLK22_OEN : R/W ;bitpos:[1] ;default: 1'b1 ; */
+
+#define SYSCON_CLK22_OEN (BIT(1))
+#define SYSCON_CLK22_OEN_M (BIT(1))
+#define SYSCON_CLK22_OEN_V 0x1
+#define SYSCON_CLK22_OEN_S 1
+
+/* SYSCON_CLK20_OEN : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+#define SYSCON_CLK20_OEN (BIT(0))
+#define SYSCON_CLK20_OEN_M (BIT(0))
+#define SYSCON_CLK20_OEN_V 0x1
+#define SYSCON_CLK20_OEN_S 0
+
+#define SYSCON_WIFI_BB_CFG_REG (DR_REG_SYSCON_BASE + 0x00C)
+
+/* SYSCON_WIFI_BB_CFG : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_WIFI_BB_CFG 0xFFFFFFFF
+#define SYSCON_WIFI_BB_CFG_M ((SYSCON_WIFI_BB_CFG_V) << (SYSCON_WIFI_BB_CFG_S))
+#define SYSCON_WIFI_BB_CFG_V 0xFFFFFFFF
+#define SYSCON_WIFI_BB_CFG_S 0
+
+#define SYSCON_WIFI_BB_CFG_2_REG (DR_REG_SYSCON_BASE + 0x010)
+
+/* SYSCON_WIFI_BB_CFG_2 : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_WIFI_BB_CFG_2 0xFFFFFFFF
+#define SYSCON_WIFI_BB_CFG_2_M ((SYSCON_WIFI_BB_CFG_2_V) << (SYSCON_WIFI_BB_CFG_2_S))
+#define SYSCON_WIFI_BB_CFG_2_V 0xFFFFFFFF
+#define SYSCON_WIFI_BB_CFG_2_S 0
+
+#define SYSCON_WIFI_CLK_EN_REG (DR_REG_SYSCON_BASE + 0x014)
+
+/* SYSCON_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define SYSCON_WIFI_CLK_EN 0xFFFFFFFF
+#define SYSCON_WIFI_CLK_EN_M ((SYSCON_WIFI_CLK_EN_V) << (SYSCON_WIFI_CLK_EN_S))
+#define SYSCON_WIFI_CLK_EN_V 0xFFFFFFFF
+#define SYSCON_WIFI_CLK_EN_S 0
+
+#define SYSCON_WIFI_RST_EN_REG (DR_REG_SYSCON_BASE + 0x018)
+
+/* SYSCON_WIFI_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_WIFI_RST 0xFFFFFFFF
+#define SYSCON_WIFI_RST_M ((SYSCON_WIFI_RST_V) << (SYSCON_WIFI_RST_S))
+#define SYSCON_WIFI_RST_V 0xFFFFFFFF
+#define SYSCON_WIFI_RST_S 0
+
+#define SYSTEM_WIFI_CLK_EN_REG SYSCON_WIFI_CLK_EN_REG
+
+/* SYSTEM_WIFI_CLK_EN : R/W ;bitpos:[31:0] ;default: 32'hfffce030 ; */
+
+#define SYSTEM_WIFI_CLK_EN 0x00FB9FCF
+#define SYSTEM_WIFI_CLK_EN_M ((SYSTEM_WIFI_CLK_EN_V) << (SYSTEM_WIFI_CLK_EN_S))
+#define SYSTEM_WIFI_CLK_EN_V 0x00FB9FCF
+#define SYSTEM_WIFI_CLK_EN_S 0
+
+/**
+ * Mask for all Wifi clock bits - 0, 1, 2, 3, 6, 7, 8, 9, 10, 15, 19, 20, 21
+ * Bit15 not included here because of the bit now can't be cleared
+ */
+
+#define SYSTEM_WIFI_CLK_WIFI_EN 0x0
+#define SYSTEM_WIFI_CLK_WIFI_EN_M ((SYSTEM_WIFI_CLK_WIFI_EN_V) << (SYSTEM_WIFI_CLK_WIFI_EN_S))
+#define SYSTEM_WIFI_CLK_WIFI_EN_V 0x0
+#define SYSTEM_WIFI_CLK_WIFI_EN_S 0
+
+/* Mask for all Bluetooth clock bits - 11, 16, 17 */
+
+#define SYSTEM_WIFI_CLK_BT_EN 0x0
+#define SYSTEM_WIFI_CLK_BT_EN_M ((SYSTEM_WIFI_CLK_BT_EN_V) << (SYSTEM_WIFI_CLK_BT_EN_S))
+#define SYSTEM_WIFI_CLK_BT_EN_V 0x0
+#define SYSTEM_WIFI_CLK_BT_EN_S 0
+
+/**
+ * Mask for clock bits used by both WIFI and Bluetooth,
+ * bit 0, 3, 6, 7, 8, 9
+ */
+
+#define SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M 0x78078F
+
+/* Digital team to check */
+
+/* bluetooth baseband bit11 */
+
+#define SYSTEM_BT_BASEBAND_EN BIT(11)
+
+/* bluetooth LC bit16 and bit17 */
+
+#define SYSTEM_BT_LC_EN (BIT(16) | BIT(17))
+
+/* Remaining single bit clock masks */
+
+#define SYSTEM_WIFI_CLK_UNUSED_BIT5 BIT(5)
+#define SYSTEM_WIFI_CLK_UNUSED_BIT12 BIT(12)
+#define SYSTEM_WIFI_CLK_SDIO_HOST_EN BIT(13)
+#define SYSTEM_WIFI_CLK_EMAC_EN BIT(14)
+#define SYSTEM_WIFI_CLK_RNG_EN BIT(15)
+
+#define SYSTEM_CORE_RST_EN_REG SYSTEM_WIFI_RST_EN_REG
+#define SYSTEM_WIFI_RST_EN_REG SYSCON_WIFI_RST_EN_REG
+
+/* SYSTEM_WIFI_RST : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSTEM_WIFI_RST 0xFFFFFFFF
+#define SYSTEM_WIFI_RST_M ((SYSTEM_WIFI_RST_V) << (SYSTEM_WIFI_RST_S))
+#define SYSTEM_WIFI_RST_V 0xFFFFFFFF
+#define SYSTEM_WIFI_RST_S 0
+#define SYSTEM_BB_REG_RST (BIT(13))
+#define SYSTEM_PWR_REG_RST (BIT(12))
+#define SYSTEM_BLE_REG_RST (BIT(11))
+#define SYSTEM_RW_BTLP_RST (BIT(10))
+#define SYSTEM_RW_BTMAC_RST (BIT(9))
+#define SYSTEM_MACPWR_RST (BIT(8))
+#define SYSTEM_EMAC_RST (BIT(7))
+#define SYSTEM_SDIO_RST (BIT(5))
+#define SYSTEM_BTMAC_RST (BIT(4))
+#define SYSTEM_BT_RST (BIT(3))
+#define SYSTEM_MAC_RST (BIT(2))
+#define SYSTEM_FE_RST (BIT(1))
+#define SYSTEM_BB_RST (BIT(0))
+
+#define SYSCON_HOST_INF_SEL_REG (DR_REG_SYSCON_BASE + 0x01C)
+
+/* SYSCON_PERI_IO_SWAP : R/W ;bitpos:[7:0] ;default: 8'h0 ; */
+
+#define SYSCON_PERI_IO_SWAP 0x000000FF
+#define SYSCON_PERI_IO_SWAP_M ((SYSCON_PERI_IO_SWAP_V) << (SYSCON_PERI_IO_SWAP_S))
+#define SYSCON_PERI_IO_SWAP_V 0xFF
+#define SYSCON_PERI_IO_SWAP_S 0
+
+#define SYSCON_EXT_MEM_PMS_LOCK_REG (DR_REG_SYSCON_BASE + 0x020)
+
+/* SYSCON_EXT_MEM_PMS_LOCK : R/W ;bitpos:[0] ;default: 1'b0 ; */
+
+#define SYSCON_EXT_MEM_PMS_LOCK (BIT(0))
+#define SYSCON_EXT_MEM_PMS_LOCK_M (BIT(0))
+#define SYSCON_EXT_MEM_PMS_LOCK_V 0x1
+#define SYSCON_EXT_MEM_PMS_LOCK_S 0
+
+#define SYSCON_FLASH_ACE0_ATTR_REG (DR_REG_SYSCON_BASE + 0x024)
+
+/* SYSCON_FLASH_ACE0_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_FLASH_ACE0_ATTR 0x000000FF
+#define SYSCON_FLASH_ACE0_ATTR_M ((SYSCON_FLASH_ACE0_ATTR_V) << (SYSCON_FLASH_ACE0_ATTR_S))
+#define SYSCON_FLASH_ACE0_ATTR_V 0xFF
+#define SYSCON_FLASH_ACE0_ATTR_S 0
+
+#define SYSCON_FLASH_ACE1_ATTR_REG (DR_REG_SYSCON_BASE + 0x028)
+
+/* SYSCON_FLASH_ACE1_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_FLASH_ACE1_ATTR 0x000000FF
+#define SYSCON_FLASH_ACE1_ATTR_M ((SYSCON_FLASH_ACE1_ATTR_V) << (SYSCON_FLASH_ACE1_ATTR_S))
+#define SYSCON_FLASH_ACE1_ATTR_V 0xFF
+#define SYSCON_FLASH_ACE1_ATTR_S 0
+
+#define SYSCON_FLASH_ACE2_ATTR_REG (DR_REG_SYSCON_BASE + 0x02C)
+
+/* SYSCON_FLASH_ACE2_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_FLASH_ACE2_ATTR 0x000000FF
+#define SYSCON_FLASH_ACE2_ATTR_M ((SYSCON_FLASH_ACE2_ATTR_V) << (SYSCON_FLASH_ACE2_ATTR_S))
+#define SYSCON_FLASH_ACE2_ATTR_V 0xFF
+#define SYSCON_FLASH_ACE2_ATTR_S 0
+
+#define SYSCON_FLASH_ACE3_ATTR_REG (DR_REG_SYSCON_BASE + 0x030)
+
+/* SYSCON_FLASH_ACE3_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_FLASH_ACE3_ATTR 0x000000FF
+#define SYSCON_FLASH_ACE3_ATTR_M ((SYSCON_FLASH_ACE3_ATTR_V) << (SYSCON_FLASH_ACE3_ATTR_S))
+#define SYSCON_FLASH_ACE3_ATTR_V 0xFF
+#define SYSCON_FLASH_ACE3_ATTR_S 0
+
+#define SYSCON_FLASH_ACE0_ADDR_REG (DR_REG_SYSCON_BASE + 0x034)
+
+/* SYSCON_FLASH_ACE0_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_FLASH_ACE0_ADDR_S 0xFFFFFFFF
+#define SYSCON_FLASH_ACE0_ADDR_S_M ((SYSCON_FLASH_ACE0_ADDR_S_V) << (SYSCON_FLASH_ACE0_ADDR_S_S))
+#define SYSCON_FLASH_ACE0_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_FLASH_ACE0_ADDR_S_S 0
+
+#define SYSCON_FLASH_ACE1_ADDR_REG (DR_REG_SYSCON_BASE + 0x038)
+
+/* SYSCON_FLASH_ACE1_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h10000000 ; */
+
+#define SYSCON_FLASH_ACE1_ADDR_S 0xFFFFFFFF
+#define SYSCON_FLASH_ACE1_ADDR_S_M ((SYSCON_FLASH_ACE1_ADDR_S_V) << (SYSCON_FLASH_ACE1_ADDR_S_S))
+#define SYSCON_FLASH_ACE1_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_FLASH_ACE1_ADDR_S_S 0
+
+#define SYSCON_FLASH_ACE2_ADDR_REG (DR_REG_SYSCON_BASE + 0x03C)
+
+/* SYSCON_FLASH_ACE2_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h20000000 ; */
+
+#define SYSCON_FLASH_ACE2_ADDR_S 0xFFFFFFFF
+#define SYSCON_FLASH_ACE2_ADDR_S_M ((SYSCON_FLASH_ACE2_ADDR_S_V) << (SYSCON_FLASH_ACE2_ADDR_S_S))
+#define SYSCON_FLASH_ACE2_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_FLASH_ACE2_ADDR_S_S 0
+
+#define SYSCON_FLASH_ACE3_ADDR_REG (DR_REG_SYSCON_BASE + 0x040)
+
+/* SYSCON_FLASH_ACE3_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h30000000 ; */
+
+#define SYSCON_FLASH_ACE3_ADDR_S 0xFFFFFFFF
+#define SYSCON_FLASH_ACE3_ADDR_S_M ((SYSCON_FLASH_ACE3_ADDR_S_V) << (SYSCON_FLASH_ACE3_ADDR_S_S))
+#define SYSCON_FLASH_ACE3_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_FLASH_ACE3_ADDR_S_S 0
+
+#define SYSCON_FLASH_ACE0_SIZE_REG (DR_REG_SYSCON_BASE + 0x044)
+
+/* SYSCON_FLASH_ACE0_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_FLASH_ACE0_SIZE 0x0000FFFF
+#define SYSCON_FLASH_ACE0_SIZE_M ((SYSCON_FLASH_ACE0_SIZE_V) << (SYSCON_FLASH_ACE0_SIZE_S))
+#define SYSCON_FLASH_ACE0_SIZE_V 0xFFFF
+#define SYSCON_FLASH_ACE0_SIZE_S 0
+
+#define SYSCON_FLASH_ACE1_SIZE_REG (DR_REG_SYSCON_BASE + 0x048)
+
+/* SYSCON_FLASH_ACE1_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_FLASH_ACE1_SIZE 0x0000FFFF
+#define SYSCON_FLASH_ACE1_SIZE_M ((SYSCON_FLASH_ACE1_SIZE_V) << (SYSCON_FLASH_ACE1_SIZE_S))
+#define SYSCON_FLASH_ACE1_SIZE_V 0xFFFF
+#define SYSCON_FLASH_ACE1_SIZE_S 0
+
+#define SYSCON_FLASH_ACE2_SIZE_REG (DR_REG_SYSCON_BASE + 0x04C)
+
+/* SYSCON_FLASH_ACE2_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_FLASH_ACE2_SIZE 0x0000FFFF
+#define SYSCON_FLASH_ACE2_SIZE_M ((SYSCON_FLASH_ACE2_SIZE_V) << (SYSCON_FLASH_ACE2_SIZE_S))
+#define SYSCON_FLASH_ACE2_SIZE_V 0xFFFF
+#define SYSCON_FLASH_ACE2_SIZE_S 0
+
+#define SYSCON_FLASH_ACE3_SIZE_REG (DR_REG_SYSCON_BASE + 0x050)
+
+/* SYSCON_FLASH_ACE3_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_FLASH_ACE3_SIZE 0x0000FFFF
+#define SYSCON_FLASH_ACE3_SIZE_M ((SYSCON_FLASH_ACE3_SIZE_V) << (SYSCON_FLASH_ACE3_SIZE_S))
+#define SYSCON_FLASH_ACE3_SIZE_V 0xFFFF
+#define SYSCON_FLASH_ACE3_SIZE_S 0
+
+#define SYSCON_SRAM_ACE0_ATTR_REG (DR_REG_SYSCON_BASE + 0x054)
+
+/* SYSCON_SRAM_ACE0_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_SRAM_ACE0_ATTR 0x000000FF
+#define SYSCON_SRAM_ACE0_ATTR_M ((SYSCON_SRAM_ACE0_ATTR_V) << (SYSCON_SRAM_ACE0_ATTR_S))
+#define SYSCON_SRAM_ACE0_ATTR_V 0xFF
+#define SYSCON_SRAM_ACE0_ATTR_S 0
+
+#define SYSCON_SRAM_ACE1_ATTR_REG (DR_REG_SYSCON_BASE + 0x058)
+
+/* SYSCON_SRAM_ACE1_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_SRAM_ACE1_ATTR 0x000000FF
+#define SYSCON_SRAM_ACE1_ATTR_M ((SYSCON_SRAM_ACE1_ATTR_V) << (SYSCON_SRAM_ACE1_ATTR_S))
+#define SYSCON_SRAM_ACE1_ATTR_V 0xFF
+#define SYSCON_SRAM_ACE1_ATTR_S 0
+
+#define SYSCON_SRAM_ACE2_ATTR_REG (DR_REG_SYSCON_BASE + 0x05C)
+
+/* SYSCON_SRAM_ACE2_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_SRAM_ACE2_ATTR 0x000000FF
+#define SYSCON_SRAM_ACE2_ATTR_M ((SYSCON_SRAM_ACE2_ATTR_V) << (SYSCON_SRAM_ACE2_ATTR_S))
+#define SYSCON_SRAM_ACE2_ATTR_V 0xFF
+#define SYSCON_SRAM_ACE2_ATTR_S 0
+
+#define SYSCON_SRAM_ACE3_ATTR_REG (DR_REG_SYSCON_BASE + 0x060)
+
+/* SYSCON_SRAM_ACE3_ATTR : R/W ;bitpos:[7:0] ;default: 8'hff ; */
+
+#define SYSCON_SRAM_ACE3_ATTR 0x000000FF
+#define SYSCON_SRAM_ACE3_ATTR_M ((SYSCON_SRAM_ACE3_ATTR_V) << (SYSCON_SRAM_ACE3_ATTR_S))
+#define SYSCON_SRAM_ACE3_ATTR_V 0xFF
+#define SYSCON_SRAM_ACE3_ATTR_S 0
+
+#define SYSCON_SRAM_ACE0_ADDR_REG (DR_REG_SYSCON_BASE + 0x064)
+
+/* SYSCON_SRAM_ACE0_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_SRAM_ACE0_ADDR_S 0xFFFFFFFF
+#define SYSCON_SRAM_ACE0_ADDR_S_M ((SYSCON_SRAM_ACE0_ADDR_S_V) << (SYSCON_SRAM_ACE0_ADDR_S_S))
+#define SYSCON_SRAM_ACE0_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_SRAM_ACE0_ADDR_S_S 0
+
+#define SYSCON_SRAM_ACE1_ADDR_REG (DR_REG_SYSCON_BASE + 0x068)
+
+/* SYSCON_SRAM_ACE1_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h10000000 ; */
+
+#define SYSCON_SRAM_ACE1_ADDR_S 0xFFFFFFFF
+#define SYSCON_SRAM_ACE1_ADDR_S_M ((SYSCON_SRAM_ACE1_ADDR_S_V) << (SYSCON_SRAM_ACE1_ADDR_S_S))
+#define SYSCON_SRAM_ACE1_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_SRAM_ACE1_ADDR_S_S 0
+
+#define SYSCON_SRAM_ACE2_ADDR_REG (DR_REG_SYSCON_BASE + 0x06C)
+
+/* SYSCON_SRAM_ACE2_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h20000000 ; */
+
+#define SYSCON_SRAM_ACE2_ADDR_S 0xFFFFFFFF
+#define SYSCON_SRAM_ACE2_ADDR_S_M ((SYSCON_SRAM_ACE2_ADDR_S_V) << (SYSCON_SRAM_ACE2_ADDR_S_S))
+#define SYSCON_SRAM_ACE2_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_SRAM_ACE2_ADDR_S_S 0
+
+#define SYSCON_SRAM_ACE3_ADDR_REG (DR_REG_SYSCON_BASE + 0x070)
+
+/* SYSCON_SRAM_ACE3_ADDR_S : R/W ;bitpos:[31:0] ;default: 32'h30000000 ; */
+
+#define SYSCON_SRAM_ACE3_ADDR_S 0xFFFFFFFF
+#define SYSCON_SRAM_ACE3_ADDR_S_M ((SYSCON_SRAM_ACE3_ADDR_S_V) << (SYSCON_SRAM_ACE3_ADDR_S_S))
+#define SYSCON_SRAM_ACE3_ADDR_S_V 0xFFFFFFFF
+#define SYSCON_SRAM_ACE3_ADDR_S_S 0
+
+#define SYSCON_SRAM_ACE0_SIZE_REG (DR_REG_SYSCON_BASE + 0x074)
+
+/* SYSCON_SRAM_ACE0_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_SRAM_ACE0_SIZE 0x0000FFFF
+#define SYSCON_SRAM_ACE0_SIZE_M ((SYSCON_SRAM_ACE0_SIZE_V) << (SYSCON_SRAM_ACE0_SIZE_S))
+#define SYSCON_SRAM_ACE0_SIZE_V 0xFFFF
+#define SYSCON_SRAM_ACE0_SIZE_S 0
+
+#define SYSCON_SRAM_ACE1_SIZE_REG (DR_REG_SYSCON_BASE + 0x078)
+
+/* SYSCON_SRAM_ACE1_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_SRAM_ACE1_SIZE 0x0000FFFF
+#define SYSCON_SRAM_ACE1_SIZE_M ((SYSCON_SRAM_ACE1_SIZE_V) << (SYSCON_SRAM_ACE1_SIZE_S))
+#define SYSCON_SRAM_ACE1_SIZE_V 0xFFFF
+#define SYSCON_SRAM_ACE1_SIZE_S 0
+
+#define SYSCON_SRAM_ACE2_SIZE_REG (DR_REG_SYSCON_BASE + 0x07C)
+
+/* SYSCON_SRAM_ACE2_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_SRAM_ACE2_SIZE 0x0000FFFF
+#define SYSCON_SRAM_ACE2_SIZE_M ((SYSCON_SRAM_ACE2_SIZE_V) << (SYSCON_SRAM_ACE2_SIZE_S))
+#define SYSCON_SRAM_ACE2_SIZE_V 0xFFFF
+#define SYSCON_SRAM_ACE2_SIZE_S 0
+
+#define SYSCON_SRAM_ACE3_SIZE_REG (DR_REG_SYSCON_BASE + 0x080)
+
+/* SYSCON_SRAM_ACE3_SIZE : R/W ;bitpos:[15:0] ;default: 16'h1000 ; */
+
+#define SYSCON_SRAM_ACE3_SIZE 0x0000FFFF
+#define SYSCON_SRAM_ACE3_SIZE_M ((SYSCON_SRAM_ACE3_SIZE_V) << (SYSCON_SRAM_ACE3_SIZE_S))
+#define SYSCON_SRAM_ACE3_SIZE_V 0xFFFF
+#define SYSCON_SRAM_ACE3_SIZE_S 0
+
+#define SYSCON_SPI_MEM_PMS_CTRL_REG (DR_REG_SYSCON_BASE + 0x084)
+
+/* SYSCON_SPI_MEM_REJECT_CDE : RO ;bitpos:[6:2] ;default: 5'h0 ; */
+
+#define SYSCON_SPI_MEM_REJECT_CDE 0x0000001F
+#define SYSCON_SPI_MEM_REJECT_CDE_M ((SYSCON_SPI_MEM_REJECT_CDE_V) << (SYSCON_SPI_MEM_REJECT_CDE_S))
+#define SYSCON_SPI_MEM_REJECT_CDE_V 0x1F
+#define SYSCON_SPI_MEM_REJECT_CDE_S 2
+
+/* SYSCON_SPI_MEM_REJECT_CLR : WOD ;bitpos:[1] ;default: 1'b0 ; */
+
+#define SYSCON_SPI_MEM_REJECT_CLR (BIT(1))
+#define SYSCON_SPI_MEM_REJECT_CLR_M (BIT(1))
+#define SYSCON_SPI_MEM_REJECT_CLR_V 0x1
+#define SYSCON_SPI_MEM_REJECT_CLR_S 1
+
+/* SYSCON_SPI_MEM_REJECT_INT : RO ;bitpos:[0] ;default: 1'b0 ; */
+
+#define SYSCON_SPI_MEM_REJECT_INT (BIT(0))
+#define SYSCON_SPI_MEM_REJECT_INT_M (BIT(0))
+#define SYSCON_SPI_MEM_REJECT_INT_V 0x1
+#define SYSCON_SPI_MEM_REJECT_INT_S 0
+
+#define SYSCON_SPI_MEM_REJECT_ADDR_REG (DR_REG_SYSCON_BASE + 0x088)
+
+/* SYSCON_SPI_MEM_REJECT_ADDR : RO ;bitpos:[31:0] ;default: 32'h0 ; */
+
+#define SYSCON_SPI_MEM_REJECT_ADDR 0xFFFFFFFF
+#define SYSCON_SPI_MEM_REJECT_ADDR_M ((SYSCON_SPI_MEM_REJECT_ADDR_V) << (SYSCON_SPI_MEM_REJECT_ADDR_S))
+#define SYSCON_SPI_MEM_REJECT_ADDR_V 0xFFFFFFFF
+#define SYSCON_SPI_MEM_REJECT_ADDR_S 0
+
+#define SYSCON_SDIO_CTRL_REG (DR_REG_SYSCON_BASE + 0x08C)
+
+/* SYSCON_SDIO_WIN_ACCESS_EN : R/W ;bitpos:[0] ;default: 1'h0 ; */
+
+#define SYSCON_SDIO_WIN_ACCESS_EN (BIT(0))
+#define SYSCON_SDIO_WIN_ACCESS_EN_M (BIT(0))
+#define SYSCON_SDIO_WIN_ACCESS_EN_V 0x1
+#define SYSCON_SDIO_WIN_ACCESS_EN_S 0
+
+#define SYSCON_REDCY_SIG0_REG (DR_REG_SYSCON_BASE + 0x090)
+
+/* SYSCON_REDCY_ANDOR : RO ;bitpos:[31] ;default: 1'h0 ; */
+
+#define SYSCON_REDCY_ANDOR (BIT(31))
+#define SYSCON_REDCY_ANDOR_M (BIT(31))
+#define SYSCON_REDCY_ANDOR_V 0x1
+#define SYSCON_REDCY_ANDOR_S 31
+
+/* SYSCON_REDCY_SIG0 : R/W ;bitpos:[30:0] ;default: 31'h0 ; */
+
+#define SYSCON_REDCY_SIG0 0x7FFFFFFF
+#define SYSCON_REDCY_SIG0_M ((SYSCON_REDCY_SIG0_V) << (SYSCON_REDCY_SIG0_S))
+#define SYSCON_REDCY_SIG0_V 0x7FFFFFFF
+#define SYSCON_REDCY_SIG0_S 0
+
+#define SYSCON_REDCY_SIG1_REG (DR_REG_SYSCON_BASE + 0x094)
+
+/* SYSCON_REDCY_NANDOR : RO ;bitpos:[31] ;default: 1'h0 ; */
+
+#define SYSCON_REDCY_NANDOR (BIT(31))
+#define SYSCON_REDCY_NANDOR_M (BIT(31))
+#define SYSCON_REDCY_NANDOR_V 0x1
+#define SYSCON_REDCY_NANDOR_S 31
+
+/* SYSCON_REDCY_SIG1 : R/W ;bitpos:[30:0] ;default: 31'h0 ; */
+
+#define SYSCON_REDCY_SIG1 0x7FFFFFFF
+#define SYSCON_REDCY_SIG1_M ((SYSCON_REDCY_SIG1_V) << (SYSCON_REDCY_SIG1_S))
+#define SYSCON_REDCY_SIG1_V 0x7FFFFFFF
+#define SYSCON_REDCY_SIG1_S 0
+
+#define SYSCON_FRONT_END_MEM_PD_REG (DR_REG_SYSCON_BASE + 0x098)
+
+/* SYSCON_DC_MEM_FORCE_PD : R/W ;bitpos:[5] ;default: 1'b0 ; */
+
+#define SYSCON_DC_MEM_FORCE_PD (BIT(5))
+#define SYSCON_DC_MEM_FORCE_PD_M (BIT(5))
+#define SYSCON_DC_MEM_FORCE_PD_V 0x1
+#define SYSCON_DC_MEM_FORCE_PD_S 5
+
+/* SYSCON_DC_MEM_FORCE_PU : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+#define SYSCON_DC_MEM_FORCE_PU (BIT(4))
+#define SYSCON_DC_MEM_FORCE_PU_M (BIT(4))
+#define SYSCON_DC_MEM_FORCE_PU_V 0x1
+#define SYSCON_DC_MEM_FORCE_PU_S 4
+
+/* SYSCON_PBUS_MEM_FORCE_PD : R/W ;bitpos:[3] ;default: 1'b0 ; */
+
+#define SYSCON_PBUS_MEM_FORCE_PD (BIT(3))
+#define SYSCON_PBUS_MEM_FORCE_PD_M (BIT(3))
+#define SYSCON_PBUS_MEM_FORCE_PD_V 0x1
+#define SYSCON_PBUS_MEM_FORCE_PD_S 3
+
+/* SYSCON_PBUS_MEM_FORCE_PU : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+#define SYSCON_PBUS_MEM_FORCE_PU (BIT(2))
+#define SYSCON_PBUS_MEM_FORCE_PU_M (BIT(2))
+#define SYSCON_PBUS_MEM_FORCE_PU_V 0x1
+#define SYSCON_PBUS_MEM_FORCE_PU_S 2
+
+/* SYSCON_AGC_MEM_FORCE_PD : R/W ;bitpos:[1] ;default: 1'b0 ; */
+
+#define SYSCON_AGC_MEM_FORCE_PD (BIT(1))
+#define SYSCON_AGC_MEM_FORCE_PD_M (BIT(1))
+#define SYSCON_AGC_MEM_FORCE_PD_V 0x1
+#define SYSCON_AGC_MEM_FORCE_PD_S 1
+
+/* SYSCON_AGC_MEM_FORCE_PU : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+#define SYSCON_AGC_MEM_FORCE_PU (BIT(0))
+#define SYSCON_AGC_MEM_FORCE_PU_M (BIT(0))
+#define SYSCON_AGC_MEM_FORCE_PU_V 0x1
+#define SYSCON_AGC_MEM_FORCE_PU_S 0
+
+#define SYSCON_DATE_REG (DR_REG_SYSCON_BASE + 0x3FC)
+
+/* SYSCON_DATE : R/W ;bitpos:[31:0] ;default: 32'h1907100 ; */
+
+#define SYSCON_DATE 0xFFFFFFFF
+#define SYSCON_DATE_M ((SYSCON_DATE_V) << (SYSCON_DATE_S))
+#define SYSCON_DATE_V 0xFFFFFFFF
+#define SYSCON_DATE_S 0
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_SYSCON_H */
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
new file mode 100644
index 0000000000..c92539467f
--- /dev/null
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/wapi/defconfig
@@ -0,0 +1,66 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="esp32c3-devkit"
+CONFIG_ARCH_BOARD_ESP32C3_DEVKIT=y
+CONFIG_ARCH_CHIP="esp32c3"
+CONFIG_ARCH_CHIP_ESP32C3=y
+CONFIG_ARCH_CHIP_ESP32C3WROOM02=y
+CONFIG_ARCH_INTERRUPTSTACK=1536
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=16717
+CONFIG_BUILTIN=y
+CONFIG_DRIVERS_IEEE80211=y
+CONFIG_DRIVERS_WIRELESS=y
+CONFIG_ESP32C3_WIRELESS=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXX=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_IDLETHREAD_STACKSIZE=3072
+CONFIG_INTELHEX_BINARY=y
+CONFIG_NAME_MAX=48
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NETDEV_LATEINIT=y
+CONFIG_NETDEV_PHY_IOCTL=y
+CONFIG_NETDEV_WIRELESS_IOCTL=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NET_ETH_PKTSIZE=1514
+CONFIG_NET_ICMP=y
+CONFIG_NET_ICMP_SOCKET=y
+CONFIG_NET_SOCKOPTS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_UDP=y
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PTHREAD_MUTEX_TYPES=y
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_SIG_DEFAULT=y
+CONFIG_START_DAY=6
+CONFIG_START_MONTH=12
+CONFIG_START_YEAR=2011
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_SYSTEM_NSH=y
+CONFIG_SYSTEM_PING=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_WAPI=y
+CONFIG_WIRELESS_WAPI_CMDTOOL=y
+CONFIG_WIRELESS_WAPI_STACKSIZE=4096
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld
index a29d8e35b1..90dbd7a175 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3.ld
@@ -36,6 +36,11 @@ SECTIONS
     *(.iram1)
     *(.iram1.*)
 
+    *(.wifi0iram .wifi0iram.*)
+    *(.wifirxiram .wifirxiram.*)
+    *(.wifislpiram .wifislpiram.*)
+    *(.wifislprxiram .wifislprxiram.*)
+
   } >iram0_0_seg
 
   /* This section is required to skip .iram0.text area because iram0_0_seg
@@ -134,6 +139,9 @@ SECTIONS
 
     *(.rodata)
     *(.rodata.*)
+
+    *(.srodata.*)
+
     *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
     *(.gnu.linkonce.r.*)
     *(.rodata1)
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
index 91e1cf5fb9..c9680ca72c 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
@@ -1527,7 +1527,6 @@ lmacReachShortLimit = 0x4000161c;
 lmacRecycleMPDU = 0x40001620;
 lmacRxDone = 0x40001624;
 lmacSetTxFrame = 0x40001628;
-lmacTxDone = 0x4000162c;
 lmacTxFrame = 0x40001630;
 mac_tx_set_duration = 0x40001634;
 mac_tx_set_htsig = 0x40001638;
@@ -1933,3 +1932,28 @@ rom_pll_correct_dcap = 0x40001b1c;
 rom_phy_en_hw_set_freq = 0x40001b20;
 rom_phy_dis_hw_set_freq = 0x40001b24;
 rom_pll_vol_cal = 0x40001b28;
+
+/***************************************
+ Group memory and string
+ ***************************************/
+
+memset = 0x40000354;
+memcpy = 0x40000358;
+memmove = 0x4000035c;
+memcmp = 0x40000360;
+memccpy = 0x400003c4;
+memchr = 0x400003c8;
+memrchr = 0x400003cc;
+strcpy = 0x40000364;
+strncpy = 0x40000368;
+strcmp = 0x4000036c;
+strncmp = 0x40000370;
+strlen = 0x40000374;
+strstr = 0x40000378;
+bzero = 0x4000037c;
+
+/***************************************
+ Redefine functions
+ ***************************************/
+
+PROVIDE ( esp_rom_delay_us = ets_delay_us );
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
index acc5965851..029d81ef2a 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_bringup.c
@@ -37,6 +37,8 @@
 
 #include <nuttx/fs/fs.h>
 
+#include "esp32c3_wlan.h"
+
 #include "esp32c3-devkit.h"
 
 /****************************************************************************
@@ -143,6 +145,15 @@ int esp32c3_bringup(void)
     }
 #endif
 
+#ifdef CONFIG_ESP32C3_WIRELESS
+  ret = esp32c3_wlan_sta_initialize();
+  if (ret)
+    {
+      syslog(LOG_ERR, "ERROR: Failed to initialize Wi-Fi\n");
+      return ret;
+    }
+#endif
+
   /* If we got here then perhaps not all initialization was successful, but
    * at least enough succeeded to bring-up NSH with perhaps reduced
    * capabilities.
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_timer.c b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_timer.c
index b88b3d37a5..dc37c220ff 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_timer.c
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/src/esp32c3_timer.c
@@ -56,7 +56,7 @@ int board_tim_init(void)
 {
   int ret = OK;
 
-#ifdef CONFIG_ESP32C3_TIMER0
+#if defined(CONFIG_ESP32C3_TIMER0) && !defined(CONFIG_ESP32C3_RT_TIMER)
   ret = esp32c3_timer_initialize("/dev/timer0", ESP32C3_TIMER0);
   if (ret < 0)
     {