diff options
author | Ido Reis <idor@ti.com> | 2012-05-13 07:53:40 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-06-07 11:11:06 -0400 |
commit | 9fccc82e19db0d63741cd6c3d2a8829fc8854406 (patch) | |
tree | 7fb6f942dc178c9bc648b736927206b2ce7eac95 /drivers/net/wireless/ti/wl18xx | |
parent | f5755fe96cb010031a50458e6d1391377d94c275 (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.c | 30 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/tx.h | 3 |
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 | ||
853 | static void | 853 | static 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 | ||
1161 | static 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 | |||
1155 | static struct wlcore_ops wl18xx_ops = { | 1180 | static 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. |