diff options
author | Ido Yariv <ido@wizery.com> | 2011-03-31 04:06:58 -0400 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2011-04-19 09:49:18 -0400 |
commit | 0da13da767cd568c1fe2a7b5b936e86e521b5ae7 (patch) | |
tree | 7c629a516bb90567e60041b4273d4dd92395d0e8 /drivers/net | |
parent | d29633b40e6afc6b4276a4e381bc532cc84be104 (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')
-rw-r--r-- | drivers/net/wireless/wl12xx/init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/io.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/sdio.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 10 |
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 @@ | |||
46 | bool wl1271_set_block_size(struct wl1271 *wl) | 47 | bool 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 | }; |
52 | MODULE_DEVICE_TABLE(sdio, wl1271_devices); | 52 | MODULE_DEVICE_TABLE(sdio, wl1271_devices); |
53 | 53 | ||
54 | /* The max SDIO block size is 256 when working with tx padding to SDIO block */ | 54 | static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz) |
55 | #define TX_PAD_SDIO_BLK_SIZE 256 | ||
56 | |||
57 | static 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 | |||
184 | out: | 176 | out: |
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 | ||
152 | static 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 | |||
152 | static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, | 161 | static 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 | |||
92 | struct wl1271_tx_hw_descr { | 101 | struct 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 |