wlcore/wl12xx: add prepare_read hw op for Rx data
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>
This commit is contained in:
@@ -32,6 +32,7 @@
|
|||||||
#include "../wlcore/acx.h"
|
#include "../wlcore/acx.h"
|
||||||
#include "../wlcore/tx.h"
|
#include "../wlcore/tx.h"
|
||||||
#include "../wlcore/rx.h"
|
#include "../wlcore/rx.h"
|
||||||
|
#include "../wlcore/io.h"
|
||||||
#include "../wlcore/boot.h"
|
#include "../wlcore/boot.h"
|
||||||
|
|
||||||
#include "reg.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_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
|
||||||
#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.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)
|
static int wl12xx_identify_chip(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -253,6 +277,10 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
|
|||||||
wl->plt_fw_name = WL127X_PLT_FW_NAME;
|
wl->plt_fw_name = WL127X_PLT_FW_NAME;
|
||||||
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
|
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
|
||||||
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
|
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
|
||||||
|
|
||||||
|
/* read data preparation is only needed by wl127x */
|
||||||
|
wl->ops->prepare_read = wl127x_prepare_read;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHIP_ID_1271_PG20:
|
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->plt_fw_name = WL127X_PLT_FW_NAME;
|
||||||
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
|
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
|
||||||
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
|
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
|
||||||
|
|
||||||
|
/* read data preparation is only needed by wl127x */
|
||||||
|
wl->ops->prepare_read = wl127x_prepare_read;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CHIP_ID_1283_PG20:
|
case CHIP_ID_1283_PG20:
|
||||||
|
@@ -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);
|
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
|
#endif
|
||||||
|
@@ -38,13 +38,6 @@
|
|||||||
*/
|
*/
|
||||||
#include "../wl12xx/reg.h"
|
#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,
|
static u32 wlcore_rx_get_buf_size(struct wl1271 *wl,
|
||||||
u32 rx_pkt_desc)
|
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)
|
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};
|
unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
|
||||||
u32 buf_size;
|
u32 buf_size;
|
||||||
u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
|
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 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
|
||||||
u32 rx_counter;
|
u32 rx_counter;
|
||||||
u32 mem_block;
|
|
||||||
u32 pkt_len, align_pkt_len;
|
u32 pkt_len, align_pkt_len;
|
||||||
u32 pkt_offset, des;
|
u32 pkt_offset, des;
|
||||||
u8 hlid;
|
u8 hlid;
|
||||||
@@ -234,27 +225,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
|
|||||||
break;
|
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 */
|
/* 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,
|
wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
|
||||||
buf_size, true);
|
buf_size, true);
|
||||||
|
|
||||||
|
@@ -47,6 +47,7 @@ struct wlcore_ops {
|
|||||||
struct sk_buff *skb);
|
struct sk_buff *skb);
|
||||||
enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
|
enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
|
||||||
u32 rx_desc);
|
u32 rx_desc);
|
||||||
|
void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
|
||||||
s8 (*get_pg_ver)(struct wl1271 *wl);
|
s8 (*get_pg_ver)(struct wl1271 *wl);
|
||||||
void (*get_mac)(struct wl1271 *wl);
|
void (*get_mac)(struct wl1271 *wl);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user