aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti/wlcore/rx.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-12-12 12:11:43 +0200
committerLuciano Coelho <coelho@ti.com>2012-04-12 08:43:59 +0300
commitcd70f6a48b3fbb841a127361ee4ac0752f9d29a2 (patch)
treefebdd2ba7cafd3115837b70c028e6f39b59d9493 /drivers/net/wireless/ti/wlcore/rx.c
parentwlcore: introduce Rx block-size alignment HW quirk (diff)
downloadlinux-dev-cd70f6a48b3fbb841a127361ee4ac0752f9d29a2.tar.xz
linux-dev-cd70f6a48b3fbb841a127361ee4ac0752f9d29a2.zip
wlcore/wl12xx: add hw op for getting rx buffer data alignment
An aligned data buffer is such where the Ethernet portion of the packet starts on a 4-byte boundary. Some chip families support padding the Rx data buffer to achieve such alignment, others rely on the host to perform it. Implement the HW op for getting alignment state in wl12xx. Add support for HW-padded alignment in the Rx flow. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/rx.c')
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c26
1 files changed, 12 insertions, 14 deletions
diff --git a/drivers/net/wireless/ti/wlcore/rx.c b/drivers/net/wireless/ti/wlcore/rx.c
index f5811d63c79a..d1e420649d31 100644
--- a/drivers/net/wireless/ti/wlcore/rx.c
+++ b/drivers/net/wireless/ti/wlcore/rx.c
@@ -30,6 +30,7 @@
#include "rx.h"
#include "tx.h"
#include "io.h"
+#include "hw_ops.h"
/*
* TODO: this is here just for now, it must be removed when the data
@@ -62,14 +63,6 @@ static u32 wlcore_rx_get_align_buf_size(struct wl1271 *wl, u32 pkt_len)
return pkt_len;
}
-static bool wl12xx_rx_get_unaligned(struct wl12xx_fw_status *status,
- u32 drv_rx_counter)
-{
- /* Convert the value to bool */
- return !!(le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) &
- RX_BUF_UNALIGNED_PAYLOAD);
-}
-
static void wl1271_rx_status(struct wl1271 *wl,
struct wl1271_rx_descriptor *desc,
struct ieee80211_rx_status *status,
@@ -114,7 +107,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
}
static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
- bool unaligned, u8 *hlid)
+ enum wl_rx_buf_align rx_align, u8 *hlid)
{
struct wl1271_rx_descriptor *desc;
struct sk_buff *skb;
@@ -122,7 +115,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
u8 *buf;
u8 beacon = 0;
u8 is_data = 0;
- u8 reserved = unaligned ? NET_IP_ALIGN : 0;
+ u8 reserved = 0;
u16 seq_num;
/*
@@ -132,6 +125,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
if (unlikely(wl->plt))
return -EINVAL;
+ if (rx_align == WLCORE_RX_BUF_UNALIGNED)
+ reserved = NET_IP_ALIGN;
+
/* the data read starts with the descriptor */
desc = (struct wl1271_rx_descriptor *) data;
@@ -177,6 +173,9 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
* payload aligned to 4 bytes.
*/
memcpy(buf, data + sizeof(*desc), length - sizeof(*desc));
+ if (rx_align == WLCORE_RX_BUF_PADDED)
+ skb_pull(skb, NET_IP_ALIGN);
+
*hlid = desc->hlid;
hdr = (struct ieee80211_hdr *)skb->data;
@@ -213,7 +212,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
u32 pkt_len, align_pkt_len;
u32 pkt_offset, des;
u8 hlid;
- bool unaligned = false;
+ enum wl_rx_buf_align rx_align;
while (drv_rx_counter != fw_rx_counter) {
buf_size = 0;
@@ -264,8 +263,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
while (pkt_offset < buf_size) {
des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
pkt_len = wlcore_rx_get_buf_size(wl, des);
- unaligned = wl12xx_rx_get_unaligned(status,
- drv_rx_counter);
+ rx_align = wlcore_hw_get_rx_buf_align(wl, des);
/*
* the handle data call can only fail in memory-outage
@@ -274,7 +272,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
*/
if (wl1271_rx_handle_data(wl,
wl->aggr_buf + pkt_offset,
- pkt_len, unaligned,
+ pkt_len, rx_align,
&hlid) == 1) {
if (hlid < WL12XX_MAX_LINKS)
__set_bit(hlid, active_hlids);