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