summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ti/wl18xx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ti/wl18xx/main.c')
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 1e0719c..c47f52c 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/ip.h>
#include "../wlcore/wlcore.h"
#include "../wlcore/debug.h"
@@ -501,9 +502,38 @@ static int wl18xx_hw_init(struct wl1271 *wl)
if (ret < 0)
return ret;
+ ret = wl18xx_acx_set_checksum_state(wl);
+ if (ret != 0)
+ return ret;
+
return ret;
}
+static void wl18xx_set_tx_desc_csum(struct wl1271 *wl,
+ struct wl1271_tx_hw_descr *desc,
+ struct sk_buff *skb)
+{
+ u32 ip_hdr_offset;
+ struct iphdr *ip_hdr;
+
+ if (skb->ip_summed != CHECKSUM_PARTIAL) {
+ desc->wl18xx_checksum_data = 0;
+ return;
+ }
+
+ ip_hdr_offset = skb_network_header(skb) - skb_mac_header(skb);
+ if (WARN_ON(ip_hdr_offset >= (1<<7))) {
+ desc->wl18xx_checksum_data = 0;
+ return;
+ }
+
+ desc->wl18xx_checksum_data = ip_hdr_offset << 1;
+
+ /* FW is interested only in the LSB of the protocol TCP=0 UDP=1 */
+ ip_hdr = (void *)skb_network_header(skb);
+ desc->wl18xx_checksum_data |= (ip_hdr->protocol & 0x01);
+}
+
static struct wlcore_ops wl18xx_ops = {
.identify_chip = wl18xx_identify_chip,
.boot = wl18xx_boot,
@@ -517,6 +547,7 @@ static struct wlcore_ops wl18xx_ops = {
.tx_immediate_compl = wl18xx_tx_immediate_completion,
.tx_delayed_compl = NULL,
.hw_init = wl18xx_hw_init,
+ .set_tx_desc_csum = wl18xx_set_tx_desc_csum,
};
int __devinit wl18xx_probe(struct platform_device *pdev)