aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ti/wl18xx
diff options
context:
space:
mode:
authorIdo Reis <idor@ti.com>2012-05-13 07:53:40 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-07 11:11:06 -0400
commit9fccc82e19db0d63741cd6c3d2a8829fc8854406 (patch)
tree7fb6f942dc178c9bc648b736927206b2ce7eac95 /drivers/net/wireless/ti/wl18xx
parentf5755fe96cb010031a50458e6d1391377d94c275 (diff)
wl18xx: pad only last frame in aggregration buffer for PG2
In PG2 only the last frame in the aggregate buffer should be aligned to the sdio block size. This frame's header msb should be set to 0, while in all the previous frames in the aggregation buffer, this bit should be set to 1. [Add a HW op for setting the frame ctrl bit only for 18xx. Other minor cleanups - Arik] [Make the pre_pkt_send operation optional -- Luca] Signed-off-by: Ido Reis <idor@ti.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless/ti/wl18xx')
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c30
-rw-r--r--drivers/net/wireless/ti/wl18xx/tx.h3
2 files changed, 31 insertions, 2 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 84f8e27c29ab..fd02795f830c 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -600,7 +600,8 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
600 wl->plt_fw_name = WL18XX_FW_NAME; 600 wl->plt_fw_name = WL18XX_FW_NAME;
601 wl->quirks |= WLCORE_QUIRK_NO_ELP | 601 wl->quirks |= WLCORE_QUIRK_NO_ELP |
602 WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | 602 WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED |
603 WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN; 603 WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN |
604 WLCORE_QUIRK_TX_PAD_LAST_FRAME;
604 605
605 break; 606 break;
606 case CHIP_ID_185x_PG10: 607 case CHIP_ID_185x_PG10:
@@ -847,7 +848,6 @@ wl18xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
847 u32 blks, u32 spare_blks) 848 u32 blks, u32 spare_blks)
848{ 849{
849 desc->wl18xx_mem.total_mem_blocks = blks; 850 desc->wl18xx_mem.total_mem_blocks = blks;
850 desc->wl18xx_mem.reserved = 0;
851} 851}
852 852
853static void 853static void
@@ -856,6 +856,12 @@ wl18xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc,
856{ 856{
857 desc->length = cpu_to_le16(skb->len); 857 desc->length = cpu_to_le16(skb->len);
858 858
859 /* if only the last frame is to be padded, we unset this bit on Tx */
860 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME)
861 desc->wl18xx_mem.ctrl = WL18XX_TX_CTRL_NOT_PADDED;
862 else
863 desc->wl18xx_mem.ctrl = 0;
864
859 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " 865 wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
860 "len: %d life: %d mem: %d", desc->hlid, 866 "len: %d life: %d mem: %d", desc->hlid,
861 le16_to_cpu(desc->length), 867 le16_to_cpu(desc->length),
@@ -1152,6 +1158,25 @@ out:
1152 return ret; 1158 return ret;
1153} 1159}
1154 1160
1161static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1162 u32 buf_offset, u32 last_len)
1163{
1164 if (wl->quirks & WLCORE_QUIRK_TX_PAD_LAST_FRAME) {
1165 struct wl1271_tx_hw_descr *last_desc;
1166
1167 /* get the last TX HW descriptor written to the aggr buf */
1168 last_desc = (struct wl1271_tx_hw_descr *)(wl->aggr_buf +
1169 buf_offset - last_len);
1170
1171 /* the last frame is padded up to an SDIO block */
1172 last_desc->wl18xx_mem.ctrl &= ~WL18XX_TX_CTRL_NOT_PADDED;
1173 return ALIGN(buf_offset, WL12XX_BUS_BLOCK_SIZE);
1174 }
1175
1176 /* no modifications */
1177 return buf_offset;
1178}
1179
1155static struct wlcore_ops wl18xx_ops = { 1180static struct wlcore_ops wl18xx_ops = {
1156 .identify_chip = wl18xx_identify_chip, 1181 .identify_chip = wl18xx_identify_chip,
1157 .boot = wl18xx_boot, 1182 .boot = wl18xx_boot,
@@ -1176,6 +1201,7 @@ static struct wlcore_ops wl18xx_ops = {
1176 .handle_static_data = wl18xx_handle_static_data, 1201 .handle_static_data = wl18xx_handle_static_data,
1177 .get_spare_blocks = wl18xx_get_spare_blocks, 1202 .get_spare_blocks = wl18xx_get_spare_blocks,
1178 .set_key = wl18xx_set_key, 1203 .set_key = wl18xx_set_key,
1204 .pre_pkt_send = wl18xx_pre_pkt_send,
1179}; 1205};
1180 1206
1181/* HT cap appropriate for wide channels */ 1207/* HT cap appropriate for wide channels */
diff --git a/drivers/net/wireless/ti/wl18xx/tx.h b/drivers/net/wireless/ti/wl18xx/tx.h
index 8aecaf09da9c..ccddc548e44a 100644
--- a/drivers/net/wireless/ti/wl18xx/tx.h
+++ b/drivers/net/wireless/ti/wl18xx/tx.h
@@ -32,6 +32,9 @@
32#define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F 32#define WL18XX_TX_STATUS_DESC_ID_MASK 0x7F
33#define WL18XX_TX_STATUS_STAT_BIT_IDX 7 33#define WL18XX_TX_STATUS_STAT_BIT_IDX 7
34 34
35/* Indicates this TX HW frame is not padded to SDIO block size */
36#define WL18XX_TX_CTRL_NOT_PADDED BIT(7)
37
35/* 38/*
36 * The FW uses a special bit to indicate a wide channel should be used in 39 * The FW uses a special bit to indicate a wide channel should be used in
37 * the rate policy. 40 * the rate policy.