提交 5766435e 编写于 作者: A Arik Nemtsov 提交者: Luciano Coelho

wlcore: introduce Rx block-size alignment HW quirk

For chip-families that support aligned buffers in the Rx side. The Rx
flow changes slightly for these chips.

Currently these modifications rely on a hard-coded block-size of 256.
Signed-off-by: NArik Nemtsov <arik@wizery.com>
Signed-off-by: NLuciano Coelho <coelho@ti.com>
上级 43a8bc5a
...@@ -44,11 +44,22 @@ static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status, ...@@ -44,11 +44,22 @@ static u8 wl12xx_rx_get_mem_block(struct wl12xx_fw_status *status,
RX_MEM_BLOCK_MASK; RX_MEM_BLOCK_MASK;
} }
static u32 wl12xx_rx_get_buf_size(struct wl12xx_fw_status *status, static u32 wlcore_rx_get_buf_size(struct wl1271 *wl,
u32 drv_rx_counter) u32 rx_pkt_desc)
{ {
return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV; return (rx_pkt_desc & ALIGNED_RX_BUF_SIZE_MASK) >>
ALIGNED_RX_BUF_SIZE_SHIFT;
return (rx_pkt_desc & RX_BUF_SIZE_MASK) >> RX_BUF_SIZE_SHIFT_DIV;
}
static u32 wlcore_rx_get_align_buf_size(struct wl1271 *wl, u32 pkt_len)
{
if (wl->quirks & WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN)
return ALIGN(pkt_len, WL12XX_BUS_BLOCK_SIZE);
return pkt_len;
} }
static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status, static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status,
...@@ -199,8 +210,8 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -199,8 +210,8 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
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 mem_block;
u32 pkt_length; u32 pkt_len, align_pkt_len;
u32 pkt_offset; u32 pkt_offset, des;
u8 hlid; u8 hlid;
bool unaligned = false; bool unaligned = false;
...@@ -208,10 +219,13 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -208,10 +219,13 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
buf_size = 0; buf_size = 0;
rx_counter = drv_rx_counter; rx_counter = drv_rx_counter;
while (rx_counter != fw_rx_counter) { while (rx_counter != fw_rx_counter) {
pkt_length = wl12xx_rx_get_buf_size(status, rx_counter); des = le32_to_cpu(status->rx_pkt_descs[rx_counter]);
if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) pkt_len = wlcore_rx_get_buf_size(wl, des);
align_pkt_len = wlcore_rx_get_align_buf_size(wl,
pkt_len);
if (buf_size + align_pkt_len > WL1271_AGGR_BUFFER_SIZE)
break; break;
buf_size += pkt_length; buf_size += align_pkt_len;
rx_counter++; rx_counter++;
rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
} }
...@@ -248,9 +262,8 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -248,9 +262,8 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
/* Split data into separate packets */ /* Split data into separate packets */
pkt_offset = 0; pkt_offset = 0;
while (pkt_offset < buf_size) { while (pkt_offset < buf_size) {
pkt_length = wl12xx_rx_get_buf_size(status, des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
drv_rx_counter); pkt_len = wlcore_rx_get_buf_size(wl, des);
unaligned = wl12xx_rx_get_unaligned(status, unaligned = wl12xx_rx_get_unaligned(status,
drv_rx_counter); drv_rx_counter);
...@@ -261,7 +274,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -261,7 +274,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
*/ */
if (wl1271_rx_handle_data(wl, if (wl1271_rx_handle_data(wl,
wl->aggr_buf + pkt_offset, wl->aggr_buf + pkt_offset,
pkt_length, unaligned, pkt_len, unaligned,
&hlid) == 1) { &hlid) == 1) {
if (hlid < WL12XX_MAX_LINKS) if (hlid < WL12XX_MAX_LINKS)
__set_bit(hlid, active_hlids); __set_bit(hlid, active_hlids);
...@@ -274,7 +287,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -274,7 +287,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
wl->rx_counter++; wl->rx_counter++;
drv_rx_counter++; drv_rx_counter++;
drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK;
pkt_offset += pkt_length; pkt_offset += wlcore_rx_get_align_buf_size(wl, pkt_len);
} }
} }
......
...@@ -96,6 +96,9 @@ ...@@ -96,6 +96,9 @@
#define RX_MEM_BLOCK_MASK 0xFF #define RX_MEM_BLOCK_MASK 0xFF
#define RX_BUF_SIZE_MASK 0xFFF00 #define RX_BUF_SIZE_MASK 0xFFF00
#define RX_BUF_SIZE_SHIFT_DIV 6 #define RX_BUF_SIZE_SHIFT_DIV 6
#define ALIGNED_RX_BUF_SIZE_MASK 0xFFFF00
#define ALIGNED_RX_BUF_SIZE_SHIFT 8
/* If set, the start of IP payload is not 4 bytes aligned */ /* If set, the start of IP payload is not 4 bytes aligned */
#define RX_BUF_UNALIGNED_PAYLOAD BIT(20) #define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
......
...@@ -346,6 +346,9 @@ int wlcore_free_hw(struct wl1271 *wl); ...@@ -346,6 +346,9 @@ int wlcore_free_hw(struct wl1271 *wl);
/* wl127x and SPI don't support SDIO block size alignment */ /* wl127x and SPI don't support SDIO block size alignment */
#define WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2) #define WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
/* means aggregated Rx packets are aligned to a SDIO block */
#define WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN BIT(3)
/* Older firmwares did not implement the FW logger over bus feature */ /* Older firmwares did not implement the FW logger over bus feature */
#define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4) #define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册