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>
This commit is contained in:
committed by
Luciano Coelho
parent
d29633b40e
commit
0da13da767
@@ -514,7 +514,7 @@ int wl1271_chip_specific_init(struct wl1271 *wl)
|
|||||||
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||||
u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
|
u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
|
||||||
|
|
||||||
if (wl1271_set_block_size(wl))
|
if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
|
||||||
/* Enable SDIO padding */
|
/* Enable SDIO padding */
|
||||||
host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
|
host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
|
||||||
|
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
#include "wl12xx.h"
|
#include "wl12xx.h"
|
||||||
#include "wl12xx_80211.h"
|
#include "wl12xx_80211.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "tx.h"
|
||||||
|
|
||||||
#define OCP_CMD_LOOP 32
|
#define OCP_CMD_LOOP 32
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
bool wl1271_set_block_size(struct wl1271 *wl)
|
bool wl1271_set_block_size(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
if (wl->if_ops->set_block_size) {
|
if (wl->if_ops->set_block_size) {
|
||||||
wl->if_ops->set_block_size(wl);
|
wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1017,6 +1017,8 @@ static int wl1271_chip_wakeup(struct wl1271 *wl)
|
|||||||
ret = wl1271_setup(wl);
|
ret = wl1271_setup(wl);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
if (wl1271_set_block_size(wl))
|
||||||
|
wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT;
|
||||||
break;
|
break;
|
||||||
case CHIP_ID_1283_PG10:
|
case CHIP_ID_1283_PG10:
|
||||||
default:
|
default:
|
||||||
@@ -1487,7 +1489,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
|
|||||||
memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
|
memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
|
||||||
wl->ap_fw_ps_map = 0;
|
wl->ap_fw_ps_map = 0;
|
||||||
wl->ap_ps_map = 0;
|
wl->ap_ps_map = 0;
|
||||||
wl->block_size = 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this is performed after the cancel_work calls and the associated
|
* this is performed after the cancel_work calls and the associated
|
||||||
@@ -3632,7 +3633,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
|||||||
wl->ap_ps_map = 0;
|
wl->ap_ps_map = 0;
|
||||||
wl->ap_fw_ps_map = 0;
|
wl->ap_fw_ps_map = 0;
|
||||||
wl->quirks = 0;
|
wl->quirks = 0;
|
||||||
wl->block_size = 0;
|
|
||||||
|
|
||||||
memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
|
memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
|
||||||
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
|
for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
|
||||||
|
@@ -51,15 +51,10 @@ static const struct sdio_device_id wl1271_devices[] = {
|
|||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(sdio, wl1271_devices);
|
MODULE_DEVICE_TABLE(sdio, wl1271_devices);
|
||||||
|
|
||||||
/* The max SDIO block size is 256 when working with tx padding to SDIO block */
|
static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
|
||||||
#define TX_PAD_SDIO_BLK_SIZE 256
|
|
||||||
|
|
||||||
static void wl1271_sdio_set_block_size(struct wl1271 *wl)
|
|
||||||
{
|
{
|
||||||
wl->block_size = TX_PAD_SDIO_BLK_SIZE;
|
|
||||||
|
|
||||||
sdio_claim_host(wl->if_priv);
|
sdio_claim_host(wl->if_priv);
|
||||||
sdio_set_block_size(wl->if_priv, TX_PAD_SDIO_BLK_SIZE);
|
sdio_set_block_size(wl->if_priv, blksz);
|
||||||
sdio_release_host(wl->if_priv);
|
sdio_release_host(wl->if_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,9 +173,6 @@ static int wl1271_sdio_power_on(struct wl1271 *wl)
|
|||||||
sdio_claim_host(func);
|
sdio_claim_host(func);
|
||||||
sdio_enable_func(func);
|
sdio_enable_func(func);
|
||||||
|
|
||||||
/* Set the default block size in case it was modified */
|
|
||||||
sdio_set_block_size(func, 0);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -149,6 +149,15 @@ u8 wl1271_tx_get_hlid(struct sk_buff *skb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
|
||||||
|
unsigned int packet_length)
|
||||||
|
{
|
||||||
|
if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
|
||||||
|
return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
|
||||||
|
else
|
||||||
|
return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
|
||||||
|
}
|
||||||
|
|
||||||
static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
|
static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
|
||||||
u32 buf_offset, u8 hlid)
|
u32 buf_offset, u8 hlid)
|
||||||
{
|
{
|
||||||
@@ -174,10 +183,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
|
|||||||
|
|
||||||
/* approximate the number of blocks required for this packet
|
/* approximate the number of blocks required for this packet
|
||||||
in the firmware */
|
in the firmware */
|
||||||
if (wl->block_size)
|
len = wl12xx_calc_packet_alignment(wl, total_len);
|
||||||
len = ALIGN(total_len, wl->block_size);
|
|
||||||
else
|
|
||||||
len = total_len;
|
|
||||||
|
|
||||||
total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
|
total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
|
||||||
spare_blocks;
|
spare_blocks;
|
||||||
@@ -291,9 +297,9 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
|
|||||||
tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
|
tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
|
||||||
desc->reserved = 0;
|
desc->reserved = 0;
|
||||||
|
|
||||||
if (wl->block_size) {
|
aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
|
||||||
aligned_len = ALIGN(skb->len, wl->block_size);
|
|
||||||
|
|
||||||
|
if (wl->chip.id == CHIP_ID_1283_PG20) {
|
||||||
desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
|
desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
|
||||||
desc->length = cpu_to_le16(aligned_len >> 2);
|
desc->length = cpu_to_le16(aligned_len >> 2);
|
||||||
|
|
||||||
@@ -306,8 +312,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
|
|||||||
} else {
|
} else {
|
||||||
int pad;
|
int pad;
|
||||||
|
|
||||||
/* align the length (and store in terms of words) */
|
/* Store the aligned length in terms of words */
|
||||||
aligned_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
|
|
||||||
desc->length = cpu_to_le16(aligned_len >> 2);
|
desc->length = cpu_to_le16(aligned_len >> 2);
|
||||||
|
|
||||||
/* calculate number of padding bytes */
|
/* calculate number of padding bytes */
|
||||||
@@ -386,10 +391,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb,
|
|||||||
* In special cases, we want to align to a specific block size
|
* In special cases, we want to align to a specific block size
|
||||||
* (eg. for wl128x with SDIO we align to 256).
|
* (eg. for wl128x with SDIO we align to 256).
|
||||||
*/
|
*/
|
||||||
if (wl->block_size)
|
total_len = wl12xx_calc_packet_alignment(wl, skb->len);
|
||||||
total_len = ALIGN(skb->len, wl->block_size);
|
|
||||||
else
|
|
||||||
total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
|
|
||||||
|
|
||||||
memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
|
memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
|
||||||
memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
|
memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
|
||||||
|
@@ -89,6 +89,15 @@ struct wl128x_tx_mem {
|
|||||||
u8 extra_bytes;
|
u8 extra_bytes;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On wl128x based devices, when TX packets are aggregated, each packet
|
||||||
|
* size must be aligned to the SDIO block size. The maximum block size
|
||||||
|
* is bounded by the type of the padded bytes field that is sent to the
|
||||||
|
* FW. Currently the type is u8, so the maximum block size is 256 bytes.
|
||||||
|
*/
|
||||||
|
#define WL12XX_BUS_BLOCK_SIZE min(512u, \
|
||||||
|
(1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
|
||||||
|
|
||||||
struct wl1271_tx_hw_descr {
|
struct wl1271_tx_hw_descr {
|
||||||
/* Length of packet in words, including descriptor+header+data */
|
/* Length of packet in words, including descriptor+header+data */
|
||||||
__le16 length;
|
__le16 length;
|
||||||
|
@@ -323,7 +323,7 @@ struct wl1271_if_operations {
|
|||||||
struct device* (*dev)(struct wl1271 *wl);
|
struct device* (*dev)(struct wl1271 *wl);
|
||||||
void (*enable_irq)(struct wl1271 *wl);
|
void (*enable_irq)(struct wl1271 *wl);
|
||||||
void (*disable_irq)(struct wl1271 *wl);
|
void (*disable_irq)(struct wl1271 *wl);
|
||||||
void (*set_block_size) (struct wl1271 *wl);
|
void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_NUM_KEYS 14
|
#define MAX_NUM_KEYS 14
|
||||||
@@ -558,7 +558,6 @@ struct wl1271 {
|
|||||||
bool ba_support;
|
bool ba_support;
|
||||||
u8 ba_rx_bitmap;
|
u8 ba_rx_bitmap;
|
||||||
|
|
||||||
u32 block_size;
|
|
||||||
int tcxo_clock;
|
int tcxo_clock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -610,12 +609,15 @@ int wl1271_plt_stop(struct wl1271 *wl);
|
|||||||
/* Quirks */
|
/* Quirks */
|
||||||
|
|
||||||
/* Each RX/TX transaction requires an end-of-transaction transfer */
|
/* Each RX/TX transaction requires an end-of-transaction transfer */
|
||||||
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
|
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Older firmwares use 2 spare TX blocks
|
* Older firmwares use 2 spare TX blocks
|
||||||
* (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
|
* (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
|
||||||
*/
|
*/
|
||||||
#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
|
#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS BIT(1)
|
||||||
|
|
||||||
|
/* WL128X requires aggregated packets to be aligned to the SDIO block size */
|
||||||
|
#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT BIT(2)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user