diff --git a/src/shared/drivers/WIZ5500/WIZ5500.cpp b/src/shared/drivers/WIZ5500/WIZ5500.cpp
index 43dc983def415ad9796306a4b59d02d6f046241c..4f0159743bc43a917a714c73d498321b966bf7c4 100644
--- a/src/shared/drivers/WIZ5500/WIZ5500.cpp
+++ b/src/shared/drivers/WIZ5500/WIZ5500.cpp
@@ -407,18 +407,15 @@ void Wiz5500::close(int sock_n, int timeout)
     socket_infos[sock_n].mode = Wiz5500::SocketMode::CLOSED;
 }
 
-void Wiz5500::waitForINTn(Lock<FastMutex>& l)
+TimedWaitResult Wiz5500::waitForINTn(Lock<FastMutex>& l, long long until)
 {
-    long long start        = Kernel::getOldTick();
     TimedWaitResult result = TimedWaitResult::NoTimeout;
 
     Unlock<FastMutex> ul(l);
     FastInterruptDisableLock il;
     while (intn.value() != 0 && result == TimedWaitResult::NoTimeout)
-    {
-        result = Kernel::Thread::IRQenableIrqAndTimedWaitMs(
-            il, start + INTN_TIMEOUT);
-    }
+        result = Kernel::Thread::IRQenableIrqAndTimedWaitMs(il, until);
+    return result;
 }
 
 int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
@@ -488,25 +485,34 @@ int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
     while (interrupt_service_thread == this_thread)
     {
         // Run a single step of the ISR
-        runInterruptServiceRoutine(l);
+        if (timeout == -1)
+            result = runInterruptServiceRoutine(l, -1);
+        else
+            result = runInterruptServiceRoutine(l, start + timeout);
 
         // Check if we woke up ourself, then we need to elect a new interrupt
         // service thread
-        if (wait_infos[i].irq != 0)
+        if (wait_infos[i].irq != 0 || result == TimedWaitResult::Timeout)
         {
+            Thread* new_interrupt_service_thread = nullptr;
+
             for (int j = 0; j < NUM_THREAD_WAIT_INFOS; j++)
             {
-                if (wait_infos[j].irq == 0)
+                if (wait_infos[j].irq == 0 && wait_infos[j].sock_n != -1 &&
+                    j != i)
                 {
-                    {
-                        FastInterruptDisableLock il;
-                        interrupt_service_thread = wait_infos[j].thread;
-                    }
-
-                    wait_infos[j].thread->wakeup();
+                    new_interrupt_service_thread = wait_infos[j].thread;
                     break;
                 }
             }
+
+            {
+                FastInterruptDisableLock il;
+                interrupt_service_thread = new_interrupt_service_thread;
+            }
+
+            if (new_interrupt_service_thread)
+                new_interrupt_service_thread->wakeup();
         }
     }
 
@@ -521,10 +527,24 @@ int Wiz5500::waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
     return wait_infos[i].irq;
 }
 
-void Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l)
+TimedWaitResult Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l,
+                                                    long long until)
 {
     // Other threads might wake us up in order to
-    waitForINTn(l);
+    long long start = Kernel::getOldTick();
+    if (until == -1)
+    {
+        // Wait for interrupts and check if we run out of time
+        if (waitForINTn(l, start + INTN_TIMEOUT) == TimedWaitResult::Timeout)
+            return TimedWaitResult::Timeout;
+    }
+    else
+    {
+        // Wait for interrupts and check if we run out of time
+        if (waitForINTn(l, std::min(start + INTN_TIMEOUT, until)) ==
+            TimedWaitResult::Timeout)
+            return TimedWaitResult::Timeout;
+    }
 
     // Ok something happened!
 
@@ -584,6 +604,8 @@ void Wiz5500::runInterruptServiceRoutine(Lock<FastMutex>& l)
             cb(ip, port);
         }
     }
+
+    return TimedWaitResult::NoTimeout;
 }
 
 void Wiz5500::spiRead(uint8_t block, uint16_t address, uint8_t* data,
diff --git a/src/shared/drivers/WIZ5500/WIZ5500.h b/src/shared/drivers/WIZ5500/WIZ5500.h
index 728b50916e96847d2affe2e284bdbb4a68d50e8c..c28d1b005e23785bd76336ef5c63684535f9532a 100644
--- a/src/shared/drivers/WIZ5500/WIZ5500.h
+++ b/src/shared/drivers/WIZ5500/WIZ5500.h
@@ -252,11 +252,13 @@ private:
     static constexpr int NUM_THREAD_WAIT_INFOS = 16;
     static constexpr int NUM_SOCKETS           = 8;
 
-    void waitForINTn(miosix::Lock<miosix::FastMutex>& l);
+    miosix::TimedWaitResult waitForINTn(miosix::Lock<miosix::FastMutex>& l,
+                                        long long until);
     int waitForSocketIrq(miosix::Lock<miosix::FastMutex>& l, int sock_n,
                          uint8_t irq_mask, int timeout);
 
-    void runInterruptServiceRoutine(miosix::Lock<miosix::FastMutex>& l);
+    miosix::TimedWaitResult runInterruptServiceRoutine(
+        miosix::Lock<miosix::FastMutex>& l, long long until);
 
     void spiRead(uint8_t block, uint16_t address, uint8_t* data, size_t len);
     void spiWrite(uint8_t block, uint16_t address, const uint8_t* data,