summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h11
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.c26
-rw-r--r--drivers/net/wireless/ti/wlcore/rx.h7
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h7
5 files changed, 46 insertions, 16 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 790c622afba7..43c2c7fcd4bd 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -31,6 +31,7 @@
#include "../wlcore/io.h"
#include "../wlcore/acx.h"
#include "../wlcore/tx.h"
+#include "../wlcore/rx.h"
#include "../wlcore/boot.h"
#include "reg.h"
@@ -734,6 +735,15 @@ wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
}
}
+static enum wl_rx_buf_align
+wl12xx_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
+{
+ if (rx_desc & RX_BUF_UNALIGNED_PAYLOAD)
+ return WLCORE_RX_BUF_UNALIGNED;
+
+ return WLCORE_RX_BUF_ALIGNED;
+}
+
static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
{
bool supported = false;
@@ -805,6 +815,7 @@ static struct wlcore_ops wl12xx_ops = {
.calc_tx_blocks = wl12xx_calc_tx_blocks,
.set_tx_desc_blocks = wl12xx_set_tx_desc_blocks,
.set_tx_desc_data_len = wl12xx_set_tx_desc_data_len,
+ .get_rx_buf_align = wl12xx_get_rx_buf_align,
.get_pg_ver = wl12xx_get_pg_ver,
.get_mac = wl12xx_get_mac,
};
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 7342f86020ce..fe6b83924294 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -23,6 +23,7 @@
#define __WLCORE_HW_OPS_H__
#include "wlcore.h"
+#include "rx.h"
static inline u32
wlcore_hw_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
@@ -54,4 +55,14 @@ wlcore_hw_set_tx_desc_data_len(struct wl1271 *wl,
wl->ops->set_tx_desc_data_len(wl, desc, skb);
}
+static inline enum wl_rx_buf_align
+wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc)
+{
+
+ if (!wl->ops->get_rx_buf_align)
+ BUG_ON(1);
+
+ return wl->ops->get_rx_buf_align(wl, rx_desc);
+}
+
#endif
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);
diff --git a/drivers/net/wireless/ti/wlcore/rx.h b/drivers/net/wireless/ti/wlcore/rx.h
index b30b1534637c..18eb38be7aa2 100644
--- a/drivers/net/wireless/ti/wlcore/rx.h
+++ b/drivers/net/wireless/ti/wlcore/rx.h
@@ -102,6 +102,13 @@
/* If set, the start of IP payload is not 4 bytes aligned */
#define RX_BUF_UNALIGNED_PAYLOAD BIT(20)
+/* Describes the alignment state of a Rx buffer */
+enum wl_rx_buf_align {
+ WLCORE_RX_BUF_ALIGNED,
+ WLCORE_RX_BUF_UNALIGNED,
+ WLCORE_RX_BUF_PADDED,
+};
+
enum {
WL12XX_RX_CLASS_UNKNOWN,
WL12XX_RX_CLASS_MANAGEMENT,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 9fc57e863eb5..3c2ded57c0d9 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -27,11 +27,12 @@
#include "wl12xx.h"
#include "event.h"
-struct wl1271_tx_hw_descr;
-
/* The maximum number of Tx descriptors in all chip families */
#define WLCORE_MAX_TX_DESCRIPTORS 32
+/* forward declaration */
+struct wl1271_tx_hw_descr;
+enum wl_rx_buf_align;
struct wlcore_ops {
int (*identify_chip)(struct wl1271 *wl);
int (*boot)(struct wl1271 *wl);
@@ -44,6 +45,8 @@ struct wlcore_ops {
void (*set_tx_desc_data_len)(struct wl1271 *wl,
struct wl1271_tx_hw_descr *desc,
struct sk_buff *skb);
+ enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl,
+ u32 rx_desc);
s8 (*get_pg_ver)(struct wl1271 *wl);
void (*get_mac)(struct wl1271 *wl);
};