aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorIdo Yariv <ido@wizery.com>2011-03-31 04:06:58 -0400
committerLuciano Coelho <coelho@ti.com>2011-04-19 09:49:18 -0400
commit0da13da767cd568c1fe2a7b5b936e86e521b5ae7 (patch)
tree7c629a516bb90567e60041b4273d4dd92395d0e8 /drivers/net/wireless
parentd29633b40e6afc6b4276a4e381bc532cc84be104 (diff)
wl12xx: Clean up the block size alignment code
Simplify and clean up the block size alignment code: 1. Set the block size according to the padding field type, as it cannot exceed the maximum value this field can hold. 2. Move the alignment code into a function instead of duplicating it in multiple places. 3. In the current implementation, the block_size member can be misleading because a zero value actually means that there's no need to align. Declare a block size alignment quirk instead. Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/init.c2
-rw-r--r--drivers/net/wireless/wl12xx/io.c3
-rw-r--r--drivers/net/wireless/wl12xx/main.c4
-rw-r--r--drivers/net/wireless/wl12xx/sdio.c12
-rw-r--r--drivers/net/wireless/wl12xx/tx.c26
-rw-r--r--drivers/net/wireless/wl12xx/tx.h9
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h10
7 files changed, 36 insertions, 30 deletions
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 2dbc08331ca9..cf466074237d 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -514,7 +514,7 @@ int wl1271_chip_specific_init(struct wl1271 *wl)
514 if (wl->chip.id == CHIP_ID_1283_PG20) { 514 if (wl->chip.id == CHIP_ID_1283_PG20) {
515 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; 515 u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
516 516
517 if (wl1271_set_block_size(wl)) 517 if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
518 /* Enable SDIO padding */ 518 /* Enable SDIO padding */
519 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; 519 host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
520 520
diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c
index aa40c98e8fd3..da5c1ad942a4 100644
--- a/drivers/net/wireless/wl12xx/io.c
+++ b/drivers/net/wireless/wl12xx/io.c
@@ -29,6 +29,7 @@
29#include "wl12xx.h" 29#include "wl12xx.h"
30#include "wl12xx_80211.h" 30#include "wl12xx_80211.h"
31#include "io.h" 31#include "io.h"
32#include "tx.h"
32 33
33#define OCP_CMD_LOOP 32 34#define OCP_CMD_LOOP 32
34 35
@@ -46,7 +47,7 @@
46bool wl1271_set_block_size(struct wl1271 *wl) 47bool wl1271_set_block_size(struct wl1271 *wl)
47{ 48{
48 if (wl->if_ops->set_block_size) { 49 if (wl->if_ops->set_block_size) {
49 wl->if_ops->set_block_size(wl); 50 wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE);
50 return true; 51 return true;
51 } 52 }
52 53
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 01205ea5e7e4..1cd396306e7b 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -1017,6 +1017,8 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
1017 ret = wl1271_setup(wl); 1017 ret = wl1271_setup(wl);
1018 if (ret < 0) 1018 if (ret < 0)
1019 goto out; 1019 goto out;
1020 if (wl1271_set_block_size(wl))
1021 wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT;
1020 break; 1022 break;
1021 case CHIP_ID_1283_PG10: 1023 case CHIP_ID_1283_PG10:
1022 default: 1024 default:
@@ -1487,7 +1489,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
1487 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); 1489 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
1488 wl->ap_fw_ps_map = 0; 1490 wl->ap_fw_ps_map = 0;
1489 wl->ap_ps_map = 0; 1491 wl->ap_ps_map = 0;
1490 wl->block_size = 0;
1491 1492
1492 /* 1493 /*
1493 * this is performed after the cancel_work calls and the associated 1494 * this is performed after the cancel_work calls and the associated
@@ -3632,7 +3633,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
3632 wl->ap_ps_map = 0; 3633 wl->ap_ps_map = 0;
3633 wl->ap_fw_ps_map = 0; 3634 wl->ap_fw_ps_map = 0;
3634 wl->quirks = 0; 3635 wl->quirks = 0;
3635 wl->block_size = 0;
3636 3636
3637 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 3637 memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
3638 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 3638 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index 2ade222f7cbb..8246e9de4306 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -51,15 +51,10 @@ static const struct sdio_device_id wl1271_devices[] = {
51}; 51};
52MODULE_DEVICE_TABLE(sdio, wl1271_devices); 52MODULE_DEVICE_TABLE(sdio, wl1271_devices);
53 53
54/* The max SDIO block size is 256 when working with tx padding to SDIO block */ 54static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
55#define TX_PAD_SDIO_BLK_SIZE 256
56
57static void wl1271_sdio_set_block_size(struct wl1271 *wl)
58{ 55{
59 wl->block_size = TX_PAD_SDIO_BLK_SIZE;
60
61 sdio_claim_host(wl->if_priv); 56 sdio_claim_host(wl->if_priv);
62 sdio_set_block_size(wl->if_priv, TX_PAD_SDIO_BLK_SIZE); 57 sdio_set_block_size(wl->if_priv, blksz);
63 sdio_release_host(wl->if_priv); 58 sdio_release_host(wl->if_priv);
64} 59}
65 60
@@ -178,9 +173,6 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)
178 sdio_claim_host(func); 173 sdio_claim_host(func);
179 sdio_enable_func(func); 174 sdio_enable_func(func);
180 175
181 /* Set the default block size in case it was modified */
182 sdio_set_block_size(func, 0);
183
184out: 176out:
185 return ret; 177 return ret;
186} 178}
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 7686bc1ff16a..ba69ba7051fa 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -149,6 +149,15 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
149 } 149 }
150} 150}
151 151
152static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
153 unsigned int packet_length)
154{
155 if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
156 return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
157 else
158 return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
159}
160
152static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, 161static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
153 u32 buf_offset, u8 hlid) 162 u32 buf_offset, u8 hlid)
154{ 163{
@@ -174,10 +183,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
174 183
175 /* approximate the number of blocks required for this packet 184 /* approximate the number of blocks required for this packet
176 in the firmware */ 185 in the firmware */
177 if (wl->block_size) 186 len = wl12xx_calc_packet_alignment(wl, total_len);
178 len = ALIGN(total_len, wl->block_size);
179 else
180 len = total_len;
181 187
182 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + 188 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
183 spare_blocks; 189 spare_blocks;
@@ -291,9 +297,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
291 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; 297 tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
292 desc->reserved = 0; 298 desc->reserved = 0;
293 299
294 if (wl->block_size) { 300 aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
295 aligned_len = ALIGN(skb->len, wl->block_size);
296 301
302 if (wl->chip.id == CHIP_ID_1283_PG20) {
297 desc->wl128x_mem.extra_bytes = aligned_len - skb->len; 303 desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
298 desc->length = cpu_to_le16(aligned_len >> 2); 304 desc->length = cpu_to_le16(aligned_len >> 2);
299 305
@@ -306,8 +312,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
306 } else { 312 } else {
307 int pad; 313 int pad;
308 314
309 /* align the length (and store in terms of words) */ 315 /* Store the aligned length in terms of words */
310 aligned_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
311 desc->length = cpu_to_le16(aligned_len >> 2); 316 desc->length = cpu_to_le16(aligned_len >> 2);
312 317
313 /* calculate number of padding bytes */ 318 /* calculate number of padding bytes */
@@ -386,10 +391,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
386 * In special cases, we want to align to a specific block size 391 * In special cases, we want to align to a specific block size
387 * (eg. for wl128x with SDIO we align to 256). 392 * (eg. for wl128x with SDIO we align to 256).
388 */ 393 */
389 if (wl->block_size) 394 total_len = wl12xx_calc_packet_alignment(wl, skb->len);
390 total_len = ALIGN(skb->len, wl->block_size);
391 else
392 total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
393 395
394 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); 396 memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
395 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); 397 memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index a3877ba32d37..d6b05d980626 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -89,6 +89,15 @@ struct wl128x_tx_mem {
89 u8 extra_bytes; 89 u8 extra_bytes;
90} __packed; 90} __packed;
91 91
92/*
93 * On wl128x based devices, when TX packets are aggregated, each packet
94 * size must be aligned to the SDIO block size. The maximum block size
95 * is bounded by the type of the padded bytes field that is sent to the
96 * FW. Currently the type is u8, so the maximum block size is 256 bytes.
97 */
98#define WL12XX_BUS_BLOCK_SIZE min(512u, \
99 (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
100
92struct wl1271_tx_hw_descr { 101struct wl1271_tx_hw_descr {
93 /* Length of packet in words, including descriptor+header+data */ 102 /* Length of packet in words, including descriptor+header+data */
94 __le16 length; 103 __le16 length;
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index c12945958848..c7c42b687f5e 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -323,7 +323,7 @@ struct wl1271_if_operations {
323 struct device* (*dev)(struct wl1271 *wl); 323 struct device* (*dev)(struct wl1271 *wl);
324 void (*enable_irq)(struct wl1271 *wl); 324 void (*enable_irq)(struct wl1271 *wl);
325 void (*disable_irq)(struct wl1271 *wl); 325 void (*disable_irq)(struct wl1271 *wl);
326 void (*set_block_size) (struct wl1271 *wl); 326 void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
327}; 327};
328 328
329#define MAX_NUM_KEYS 14 329#define MAX_NUM_KEYS 14
@@ -558,7 +558,6 @@ struct wl1271 {
558 bool ba_support; 558 bool ba_support;
559 u8 ba_rx_bitmap; 559 u8 ba_rx_bitmap;
560 560
561 u32 block_size;
562 int tcxo_clock; 561 int tcxo_clock;
563 562
564 /* 563 /*
@@ -610,12 +609,15 @@ int wl1271_plt_stop(struct wl1271 *wl);
610/* Quirks */ 609/* Quirks */
611 610
612/* Each RX/TX transaction requires an end-of-transaction transfer */ 611/* Each RX/TX transaction requires an end-of-transaction transfer */
613#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) 612#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
614 613
615/* 614/*
616 * Older firmwares use 2 spare TX blocks 615 * Older firmwares use 2 spare TX blocks
617 * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47) 616 * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
618 */ 617 */
619#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1) 618#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
619
620/* WL128X requires aggregated packets to be aligned to the SDIO block size */
621#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
620 622
621#endif 623#endif