Unverified Commit 12702717 authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Undo #1864, fix LWIP offline error (#1979)

Fixes #1973

The periodic LWIP pump/Ethernet packet reader async_context stopped
firing occasionally under high packet loads, causing the LWIP stack
to become unresponsive to any incoming data.

Re-implement the 2-step process for polling (like the CYW43 driver
from the RPI folks does) and undoes #1864 change.
parent 9c66d973
......@@ -31,6 +31,7 @@ bool __ethernetContextInitted = false;
// Async context that pumps the ethernet controllers
static async_context_threadsafe_background_t lwip_ethernet_async_context_threadsafe_background;
static async_when_pending_worker_t always_pending_update_timeout_worker;
static async_at_time_worker_t ethernet_timeout_worker;
static async_context_t *_context = nullptr;
......@@ -127,10 +128,12 @@ static async_context_t *lwip_ethernet_init_default_async_context(void) {
return NULL;
}
uint32_t __ethernet_timeout_reached_calls = 0;
static uint32_t _pollingPeriod = 20;
// This will only be called under the protection of the async context mutex, so no re-entrancy checks needed
static void ethernet_timeout_reached(async_context_t *context, __unused async_at_time_worker_t *worker) {
static void ethernet_timeout_reached(__unused async_context_t *context, __unused async_at_time_worker_t *worker) {
assert(worker == &ethernet_timeout_worker);
__ethernet_timeout_reached_calls++;
for (auto handlePacket : _handlePacketList) {
handlePacket.second();
}
......@@ -141,6 +144,11 @@ static void ethernet_timeout_reached(async_context_t *context, __unused async_at
#else
sys_check_timeouts();
#endif
}
static void update_next_timeout(async_context_t *context, async_when_pending_worker_t *worker) {
assert(worker == &always_pending_update_timeout_worker);
worker->work_pending = true;
async_context_add_at_time_worker_in_ms(context, &ethernet_timeout_worker, _pollingPeriod);
}
......@@ -158,7 +166,9 @@ void __startEthernetContext() {
_context = lwip_ethernet_init_default_async_context();
#endif
ethernet_timeout_worker.do_work = ethernet_timeout_reached;
async_context_add_at_time_worker_in_ms(_context, &ethernet_timeout_worker, _pollingPeriod);
always_pending_update_timeout_worker.work_pending = true;
always_pending_update_timeout_worker.do_work = update_next_timeout;
async_context_add_when_pending_worker(_context, &always_pending_update_timeout_worker);
__ethernetContextInitted = true;
}
......
......@@ -137,6 +137,13 @@ public:
_spiSettings = s;
}
uint32_t packetsReceived() {
return _packetsReceived;
}
uint32_t packetsSent() {
return _packetsSent;
}
// ESP8266WiFi API compatibility
wl_status_t status();
......@@ -172,6 +179,9 @@ protected:
// Packet handler number
int _phID = -1;
uint32_t _packetsReceived = 0;
uint32_t _packetsSent = 0;
};
......@@ -416,7 +426,7 @@ err_t LwipIntfDev<RawDev>::linkoutput_s(netif* netif, struct pbuf* pbuf) {
LwipIntfDev* lid = (LwipIntfDev*)netif->state;
ethernet_arch_lwip_begin();
uint16_t len = lid->sendFrame((const uint8_t*)pbuf->payload, pbuf->len);
lid->_packetsSent++;
#if PHY_HAS_CAPTURE
if (phy_capture) {
phy_capture(lid->_netif.num, (const char*)pbuf->payload, pbuf->len, /*out*/ 1,
......@@ -530,6 +540,8 @@ err_t LwipIntfDev<RawDev>::handlePackets() {
return ERR_BUF;
}
_packetsReceived++;
err_t err = _netif.input(pbuf, &_netif);
#if PHY_HAS_CAPTURE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment