wlcore/wl12xx: split Tx completion to immediate/delayed
authorArik Nemtsov <arik@wizery.com>
Mon, 12 Dec 2011 09:32:37 +0000 (11:32 +0200)
committerLuciano Coelho <coelho@ti.com>
Thu, 12 Apr 2012 05:44:00 +0000 (08:44 +0300)
One chip family employs immediate Tx completion, where knowledge of
completed packets is given as part of the FW status. Another is only
notified of Tx completion via the FW status, and has to read the
completion status of the packets from a different location.

Implement the wl12xx tx completion as a delayed Tx completion.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
drivers/net/wireless/ti/wl12xx/main.c
drivers/net/wireless/ti/wlcore/hw_ops.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 5f81aaf19d97f1e3c0f533f78ca60cb0ebc7d859..6b187d066c512c531eadcda93bcadd8e36ec27c8 100644 (file)
@@ -789,6 +789,14 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
        return data_len - sizeof(*desc) - desc->pad_len;
 }
 
+static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
+{
+       if (wl->fw_status->tx_results_counter == (wl->tx_results_count & 0xff))
+               return;
+
+       wl1271_tx_complete(wl);
+}
+
 static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
 {
        bool supported = false;
@@ -862,6 +870,8 @@ static struct wlcore_ops wl12xx_ops = {
        .set_tx_desc_data_len   = wl12xx_set_tx_desc_data_len,
        .get_rx_buf_align       = wl12xx_get_rx_buf_align,
        .get_rx_packet_len      = wl12xx_get_rx_packet_len,
+       .tx_immediate_compl     = NULL,
+       .tx_delayed_compl       = wl12xx_tx_delayed_compl,
        .get_pg_ver             = wl12xx_get_pg_ver,
        .get_mac                = wl12xx_get_mac,
 };
index 22615a8f1a403a3e641b9d90e47a311c18d6d5ec..9fc64295293f4345b695702963a39379e2235b30 100644 (file)
@@ -81,4 +81,16 @@ wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len)
        return wl->ops->get_rx_packet_len(wl, rx_data, data_len);
 }
 
+static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl)
+{
+       if (wl->ops->tx_delayed_compl)
+               wl->ops->tx_delayed_compl(wl);
+}
+
+static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl)
+{
+       if (wl->ops->tx_immediate_compl)
+               wl->ops->tx_immediate_compl(wl);
+}
+
 #endif
index 3f558d5a43e3e4a210a3e0b4930562439b85858f..0392166c430965c2eaafa4ff4637f4f237a5ad1a 100644 (file)
@@ -49,6 +49,7 @@
 #include "boot.h"
 #include "testmode.h"
 #include "scan.h"
+#include "hw_ops.h"
 
 #define WL1271_BOOT_RETRIES 3
 
@@ -933,6 +934,9 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
                smp_mb__after_clear_bit();
 
                wl12xx_fw_status(wl, wl->fw_status);
+
+               wlcore_hw_tx_immediate_compl(wl);
+
                intr = le32_to_cpu(wl->fw_status->intr);
                intr &= WL1271_INTR_MASK;
                if (!intr) {
@@ -969,9 +973,7 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
                        }
 
                        /* check for tx results */
-                       if (wl->fw_status->tx_results_counter !=
-                           (wl->tx_results_count & 0xff))
-                               wl1271_tx_complete(wl);
+                       wlcore_hw_tx_delayed_compl(wl);
 
                        /* Make sure the deferred queues don't get too long */
                        defer_count = skb_queue_len(&wl->deferred_tx_queue) +
index 1fabc482ca2bb757e1c40052546e783f55985a6f..d1811b8b5146624cce7ec3ddab58111e9afa1d54 100644 (file)
@@ -905,6 +905,7 @@ void wl1271_tx_complete(struct wl1271 *wl)
                wl->tx_results_count++;
        }
 }
+EXPORT_SYMBOL(wl1271_tx_complete);
 
 void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
 {
index 664df3216bbfaf900b988f1935ac1bb331391ed3..29b39f9b746af717eed1ef54349e354ef4248a79 100644 (file)
@@ -51,6 +51,8 @@ struct wlcore_ops {
        void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
        u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data,
                                 u32 data_len);
+       void (*tx_delayed_compl)(struct wl1271 *wl);
+       void (*tx_immediate_compl)(struct wl1271 *wl);
        s8 (*get_pg_ver)(struct wl1271 *wl);
        void (*get_mac)(struct wl1271 *wl);
 };