From 24b71a7fbe5e917ef0838d7686e6adca5e7da1db Mon Sep 17 00:00:00 2001
From: Gunar Schorcht <gunar@schorcht.net>
Date: Thu, 24 Jan 2019 17:26:43 +0100
Subject: [PATCH] cpu/esp8266: call _recv directly in esp_wifi

Since _esp_wifi_recv_cb is not executed in interrupt context but in the context of the `ets` thread, it is not necessary to pass the`NETDEV_EVENT_ISR` event first. Instead, the receive function can be called directly which result in much faster handling, a less frame lost rate and more robustness.
---
 cpu/esp8266/esp-wifi/esp_wifi_netdev.c | 35 +++++++++-----------------
 1 file changed, 12 insertions(+), 23 deletions(-)

diff --git a/cpu/esp8266/esp-wifi/esp_wifi_netdev.c b/cpu/esp8266/esp-wifi/esp_wifi_netdev.c
index 29ea56c563..edda6f418f 100644
--- a/cpu/esp8266/esp-wifi/esp_wifi_netdev.c
+++ b/cpu/esp8266/esp-wifi/esp_wifi_netdev.c
@@ -161,9 +161,9 @@ void IRAM _esp_wifi_recv_cb(struct pbuf *pb, struct netif *netif)
     assert(netif != NULL);
 
     /*
-     * The function `esp_wifi_recv_cb` is executed in the context of the `ets`
-     * thread. The ISRs handling the hardware interrupts from the WiFi
-     * interface pass events to a message queue of the `ets` thread which is
+     * Function `esp_wifi_recv_cb` is executed in the context of the `ets`
+     * thread. ISRs which handle hardware interrupts from the WiFi interface
+     * simply pass events to a message queue of the `ets` thread which are then
      * sequentially processed by the `ets` thread to asynchronously execute
      * callback functions such as `esp_wifi_recv_cb`.
      *
@@ -211,30 +211,25 @@ void IRAM _esp_wifi_recv_cb(struct pbuf *pb, struct netif *netif)
         return;
     }
 
-    /* store the frame in the buffer and free lwIP pbuf */
+    /* we have to store the frame in the buffer and free lwIP pbuf immediatly */
     _esp_wifi_dev.rx_len = pb->tot_len;
     pbuf_copy_partial(pb, _esp_wifi_dev.rx_buf, _esp_wifi_dev.rx_len, 0);
     pbuf_free(pb);
 
     /*
-     * Because this function is not executed in interrupt context but in thread
-     * context, following msg_send could block on heavy network load, if frames
-     * are coming in faster than the ISR events can be handled. To avoid
-     * blocking during msg_send, we pretend we are in an ISR by incrementing
-     * the IRQ nesting counter. If IRQ nesting counter is greater 0, function
-     * irq_is_in returns true and the non-blocking version of msg_send is used.
+     * Since _esp_wifi_recv_cb is not executed in interrupt context but in
+     * the context of the `ets` thread, it is not necessary to pass the
+     * `NETDEV_EVENT_ISR` event first. Instead, the receive function can be
+     * called directly which result in much faster handling, a less frame lost
+     * rate and more robustness. There is no need for a mutex anymore to
+     * synchronize the access to the receive buffer between _esp_wifi_recv_cb
+     * and _recv function.
      */
-    irq_interrupt_nesting++;
-
-    /* trigger netdev event to read the data */
     if (_esp_wifi_dev.netdev.event_callback) {
         _esp_wifi_dev.netdev.event_callback(&_esp_wifi_dev.netdev,
-                                            NETDEV_EVENT_ISR);
+                                            NETDEV_EVENT_RX_COMPLETE);
     }
 
-    /* reset IRQ nesting counter */
-    irq_interrupt_nesting--;
-
     _in_esp_wifi_recv_cb = false;
     critical_exit();
 }
@@ -565,12 +560,6 @@ static void _isr(netdev_t *netdev)
     ESP_WIFI_DEBUG("%p", netdev);
 
     assert(netdev != NULL);
-
-    esp_wifi_netdev_t *dev = (esp_wifi_netdev_t *)netdev;
-
-    if (dev->rx_len) {
-        dev->netdev.event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
-    }
 }
 
 /** override lwIP ethernet_intput to get ethernet frames */
-- 
GitLab