wifi: wilc1000: add back-off algorithm to balance tx queue packets
authorPrasurjya Rohan Saikia <prasurjya.rohansaikia@microchip.com>
Fri, 15 Sep 2023 18:00:40 +0000 (18:00 +0000)
committerKalle Valo <kvalo@kernel.org>
Thu, 21 Sep 2023 06:30:11 +0000 (09:30 +0300)
Add an algorithm to backoff the Tx Task when low memory scenario is
triggered at firmware. During high data transfer from host, the firmware
runs out of VMM memory, which is used to hold the frames from the host.
So, adding the flow control delays the transmit from host side when
there is not enough space to accommodate frames in firmware side.

Signed-off-by: Prasurjya Rohan Saikia <prasurjya.rohansaikia@microchip.com>
Acked-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20230915175946.4361-1-prasurjya.rohansaikia@microchip.com
drivers/net/wireless/microchip/wilc1000/netdev.c
drivers/net/wireless/microchip/wilc1000/netdev.h

index e9f59de31b0b9559c7f8a43619a71b755b9e44b3..91d71e0f7ef2332354a0b950eea3e8795387ed7b 100644 (file)
@@ -148,8 +148,8 @@ static int wilc_txq_task(void *vp)
 
        complete(&wl->txq_thread_started);
        while (1) {
-               wait_for_completion(&wl->txq_event);
-
+               if (wait_for_completion_interruptible(&wl->txq_event))
+                       continue;
                if (wl->close) {
                        complete(&wl->txq_thread_started);
 
@@ -166,12 +166,24 @@ static int wilc_txq_task(void *vp)
                                srcu_idx = srcu_read_lock(&wl->srcu);
                                list_for_each_entry_rcu(ifc, &wl->vif_list,
                                                        list) {
-                                       if (ifc->mac_opened && ifc->ndev)
+                                       if (ifc->mac_opened &&
+                                           netif_queue_stopped(ifc->ndev))
                                                netif_wake_queue(ifc->ndev);
                                }
                                srcu_read_unlock(&wl->srcu, srcu_idx);
                        }
-               } while (ret == WILC_VMM_ENTRY_FULL_RETRY && !wl->close);
+                       if (ret != WILC_VMM_ENTRY_FULL_RETRY)
+                               break;
+                       /* Back off TX task from sending packets for some time.
+                        * msleep_interruptible will allow RX task to run and
+                        * free buffers. TX task will be in TASK_INTERRUPTIBLE
+                        * state which will put the thread back to CPU running
+                        * queue when it's signaled even if the timeout isn't
+                        * elapsed. This gives faster chance for reserved SK
+                        * buffers to be free.
+                        */
+                       msleep_interruptible(TX_BACKOFF_WEIGHT_MS);
+               } while (!wl->close);
        }
        return 0;
 }
index bb1a315a7b7ead76bbdf252286e637b5a1f1b7bc..aafe3dc44ac6c2fa3429dd496799f263f32e3e77 100644 (file)
@@ -27,6 +27,8 @@
 #define TCP_ACK_FILTER_LINK_SPEED_THRESH       54
 #define DEFAULT_LINK_SPEED                     72
 
+#define TX_BACKOFF_WEIGHT_MS                   1
+
 struct wilc_wfi_stats {
        unsigned long rx_packets;
        unsigned long tx_packets;