wlcore/wl12xx: add prepare_read hw op for Rx data
authorLuciano Coelho <coelho@ti.com>
Mon, 12 Dec 2011 10:15:08 +0000 (12:15 +0200)
committerLuciano Coelho <coelho@ti.com>
Thu, 12 Apr 2012 05:44:00 +0000 (08:44 +0300)
The only difference in the read_data operations is that some chips
need to prepare the data to be read before reading.  So instead of
having a mandatory read_data operation, we now have an option
prepare_data operation that only needs to be implemented for chips
that require it.

In the wl12xx lower driver, we only set the prepare_data operation for
wl127x chips.

Signed-off-by: Luciano Coelho <coelho@ti.com>
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/rx.c
drivers/net/wireless/ti/wlcore/wlcore.h

index 43c2c7f..e4fab26 100644 (file)
@@ -32,6 +32,7 @@
 #include "../wlcore/acx.h"
 #include "../wlcore/tx.h"
 #include "../wlcore/rx.h"
+#include "../wlcore/io.h"
 #include "../wlcore/boot.h"
 
 #include "reg.h"
@@ -239,6 +240,29 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = {
 #define WL128X_FW_NAME_SINGLE  "ti-connectivity/wl128x-fw-4-sr.bin"
 #define WL128X_PLT_FW_NAME     "ti-connectivity/wl128x-fw-4-plt.bin"
 
+static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
+{
+       if (wl->chip.id != CHIP_ID_1283_PG20) {
+               struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
+               struct wl1271_rx_mem_pool_addr rx_mem_addr;
+
+               /*
+                * Choose the block we want to read
+                * For aggregated packets, only the first memory block
+                * should be retrieved. The FW takes care of the rest.
+                */
+               u32 mem_block = rx_desc & RX_MEM_BLOCK_MASK;
+
+               rx_mem_addr.addr = (mem_block << 8) +
+                       le32_to_cpu(wl_mem_map->packet_memory_pool_start);
+
+               rx_mem_addr.addr_extra = rx_mem_addr.addr + 4;
+
+               wl1271_write(wl, WL1271_SLV_REG_DATA,
+                            &rx_mem_addr, sizeof(rx_mem_addr), false);
+       }
+}
+
 static int wl12xx_identify_chip(struct wl1271 *wl)
 {
        int ret = 0;
@@ -253,6 +277,10 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
                wl->plt_fw_name = WL127X_PLT_FW_NAME;
                wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
                wl->mr_fw_name = WL127X_FW_NAME_MULTI;
+
+               /* read data preparation is only needed by wl127x */
+               wl->ops->prepare_read = wl127x_prepare_read;
+
                break;
 
        case CHIP_ID_1271_PG20:
@@ -264,6 +292,10 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
                wl->plt_fw_name = WL127X_PLT_FW_NAME;
                wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
                wl->mr_fw_name = WL127X_FW_NAME_MULTI;
+
+               /* read data preparation is only needed by wl127x */
+               wl->ops->prepare_read = wl127x_prepare_read;
+
                break;
 
        case CHIP_ID_1283_PG20:
index fe6b839..148dc4e 100644 (file)
@@ -65,4 +65,11 @@ wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
        return wl->ops->get_rx_buf_align(wl, rx_desc);
 }
 
+static inline void
+wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len)
+{
+       if (wl->ops->prepare_read)
+               wl->ops->prepare_read(wl, rx_desc, len);
+}
+
 #endif
index d1e4206..3f504d1 100644 (file)
  */
 #include "../wl12xx/reg.h"
 
-static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
-                                 u32 drv_rx_counter)
-{
-       return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
-               RX_MEM_BLOCK_MASK;
-}
-
 static u32 wlcore_rx_get_buf_size(struct wl1271 *wl,
                                  u32 rx_pkt_desc)
 {
@@ -202,13 +195,11 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
 
 void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
 {
-       struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
        unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
        u32 buf_size;
        u32 fw_rx_counter  = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
        u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
        u32 rx_counter;
-       u32 mem_block;
        u32 pkt_len, align_pkt_len;
        u32 pkt_offset, des;
        u8 hlid;
@@ -234,27 +225,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
                        break;
                }
 
-               if (wl->chip.id != CHIP_ID_1283_PG20) {
-                       /*
-                        * Choose the block we want to read
-                        * For aggregated packets, only the first memory block
-                        * should be retrieved. The FW takes care of the rest.
-                        */
-                       mem_block = wl12xx_rx_get_mem_block(status,
-                                                           drv_rx_counter);
-
-                       wl->rx_mem_pool_addr.addr = (mem_block << 8) +
-                          le32_to_cpu(wl_mem_map->packet_memory_pool_start);
-
-                       wl->rx_mem_pool_addr.addr_extra =
-                               wl->rx_mem_pool_addr.addr + 4;
-
-                       wlcore_write_data(wl, REG_SLV_REG_DATA,
-                                         &wl->rx_mem_pool_addr,
-                                         sizeof(wl->rx_mem_pool_addr), false);
-               }
-
                /* Read all available packets at once */
+               des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
+               wlcore_hw_prepare_read(wl, des, buf_size);
                wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
                                 buf_size, true);
 
index 3c2ded5..79ab84e 100644 (file)
@@ -47,6 +47,7 @@ struct wlcore_ops {
                                     struct sk_buff *skb);
        enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
                                                 u32 rx_desc);
+       void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
        s8 (*get_pg_ver)(struct wl1271 *wl);
        void (*get_mac)(struct wl1271 *wl);
 };