This patch fixes up some issues with patch 03/15 in the wl128x support series: * Fix endianess issues; * Simplify sdio-specific block_size handling; * Minor changes in comments This has been compile-tested only. I will test this changes after I go through the whole series and, if everything is still ok, I'll merge this patch into 03/15. Cc: Shahar Levi <shahar_levi@xxxxxx> Signed-off-by: Luciano Coelho <coelho@xxxxxx> --- drivers/net/wireless/wl12xx/acx.c | 4 +- drivers/net/wireless/wl12xx/acx.h | 8 +++--- drivers/net/wireless/wl12xx/init.c | 42 ++++++++++++++++++++------------- drivers/net/wireless/wl12xx/init.h | 1 + drivers/net/wireless/wl12xx/io.c | 9 +++++- drivers/net/wireless/wl12xx/io.h | 2 +- drivers/net/wireless/wl12xx/main.c | 19 +++++---------- drivers/net/wireless/wl12xx/sdio.c | 3 ++ drivers/net/wireless/wl12xx/spi.c | 10 +------- drivers/net/wireless/wl12xx/tx.c | 41 +++++++++++++------------------- drivers/net/wireless/wl12xx/tx.h | 24 +++++++++--------- drivers/net/wireless/wl12xx/wl12xx.h | 4 +-- 12 files changed, 80 insertions(+), 87 deletions(-) diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index aa0fc12..50676b3 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c @@ -1019,7 +1019,7 @@ out: return ret; } -int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl) +int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap) { struct wl1271_acx_host_config_bitmap *bitmap_conf; int ret; @@ -1030,7 +1030,7 @@ int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl) goto out; } - bitmap_conf->host_cfg_bitmap = wl->host_cfg_bitmap; + bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap); ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP, bitmap_conf, sizeof(*bitmap_conf)); diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 2d0bbfe..0a40cae 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h @@ -939,9 +939,9 @@ struct wl1271_acx_keep_alive_config { u8 padding; } __packed; -#define HOST_IF_CFG_BITMAP_RX_FIFO_ENABLE BIT(0) -#define HOST_IF_CFG_BITMAP_TX_EXTRA_BLKS_SWAP BIT(1) -#define HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK BIT(3) +#define HOST_IF_CFG_RX_FIFO_ENABLE BIT(0) +#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1) +#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3) struct wl1271_acx_host_config_bitmap { struct acx_header header; @@ -1285,7 +1285,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl); int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); int wl1271_acx_init_mem_config(struct wl1271 *wl); -int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl); +int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap); int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); int wl1271_acx_smart_reflex(struct wl1271 *wl); int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable); diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 2f31d14..34c4108 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c @@ -505,6 +505,27 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) return ret; } +int wl1271_chip_specific_init(struct wl1271 *wl) +{ + int ret = 0; + + if (wl->chip.id == CHIP_ID_1283_PG20) { + u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; + + if (wl1271_set_block_size(wl)) + /* Enable SDIO padding */ + host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; + + /* Must be before wl1271_acx_init_mem_config() */ + ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap); + if (ret < 0) + goto out; + } +out: + return ret; +} + + int wl1271_hw_init(struct wl1271 *wl) { struct conf_tx_ac_category *conf_ac; @@ -520,23 +541,10 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) return ret; - if (wl->chip.id == CHIP_ID_1283_PG20) { - wl1271_set_block_size(wl); - - wl->host_cfg_bitmap = HOST_IF_CFG_BITMAP_RX_FIFO_ENABLE; - - if (wl->block_size) - wl->host_cfg_bitmap |= - HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK; - - /* - * Host interface configuration must be before - * wl1271_acx_init_mem_config ! - */ - ret = wl1271_acx_host_if_cfg_bitmap(wl); - if (ret < 0) - return ret; - } + /* Chip-specific init */ + ret = wl1271_chip_specific_init(wl); + if (ret < 0) + return ret; /* Mode specific init */ if (is_ap) diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h index 3a8bd3f..4975270 100644 --- a/drivers/net/wireless/wl12xx/init.h +++ b/drivers/net/wireless/wl12xx/init.h @@ -31,6 +31,7 @@ int wl1271_sta_init_templates_config(struct wl1271 *wl); int wl1271_init_phy_config(struct wl1271 *wl); int wl1271_init_pta(struct wl1271 *wl); int wl1271_init_energy_detection(struct wl1271 *wl); +int wl1271_chip_specific_init(struct wl1271 *wl); int wl1271_hw_init(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/io.c b/drivers/net/wireless/wl12xx/io.c index ca7229f..aa40c98 100644 --- a/drivers/net/wireless/wl12xx/io.c +++ b/drivers/net/wireless/wl12xx/io.c @@ -43,9 +43,14 @@ #define OCP_STATUS_REQ_FAILED 0x20000 #define OCP_STATUS_RESP_ERROR 0x30000 -void wl1271_set_block_size(struct wl1271 *wl) +bool wl1271_set_block_size(struct wl1271 *wl) { - wl->if_ops->set_block_size(wl); + if (wl->if_ops->set_block_size) { + wl->if_ops->set_block_size(wl); + return true; + } + + return false; } void wl1271_disable_interrupts(struct wl1271 *wl) diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index 9ae2f4a..84454f6 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h @@ -169,6 +169,6 @@ int wl1271_init_ieee80211(struct wl1271 *wl); struct ieee80211_hw *wl1271_alloc_hw(void); int wl1271_free_hw(struct wl1271 *wl); irqreturn_t wl1271_irq(int irq, void *data); -void wl1271_set_block_size(struct wl1271 *wl); +bool wl1271_set_block_size(struct wl1271 *wl); #endif diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index ac0513a..f24906f 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -450,19 +450,10 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) return ret; - if (wl->chip.id == CHIP_ID_1283_PG20) { - wl1271_set_block_size(wl); - - wl->host_cfg_bitmap = HOST_IF_CFG_BITMAP_RX_FIFO_ENABLE; - - if (wl->block_size) - wl->host_cfg_bitmap |= - HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK; - - ret = wl1271_acx_host_if_cfg_bitmap(wl); - if (ret < 0) - return ret; - } + /* Chip-specific initializations */ + ret = wl1271_chip_specific_init(wl); + if (ret < 0) + return ret; ret = wl1271_sta_init_templates_config(wl); if (ret < 0) @@ -1349,6 +1340,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); wl->ap_fw_ps_map = 0; wl->ap_ps_map = 0; + wl->block_size = 0; for (i = 0; i < NUM_TX_QUEUES; i++) wl->tx_blocks_freed[i] = 0; @@ -3472,6 +3464,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; wl->quirks = 0; + wl->block_size = 0; memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); 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 ed0f37e..55dc6e3 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c @@ -178,6 +178,9 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) sdio_claim_host(func); sdio_enable_func(func); + /* Set the default block size in case it was modified */ + sdio_set_block_size(func, 0); + out: return ret; } diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index d6e566e..2a57583 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c @@ -68,14 +68,6 @@ #define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) -/* When working with SPI block size not relevent*/ -#define TX_PAD_SDIO_BLK_SIZE 0 - -void wl1271_spi_set_block_size(struct wl1271 *wl) -{ - wl->block_size = TX_PAD_SDIO_BLK_SIZE; -} - static inline struct spi_device *wl_to_spi(struct wl1271 *wl) { return wl->if_priv; @@ -364,7 +356,7 @@ static struct wl1271_if_operations spi_ops = { .dev = wl1271_spi_wl_to_dev, .enable_irq = wl1271_spi_enable_interrupts, .disable_irq = wl1271_spi_disable_interrupts, - .set_block_size = wl1271_spi_set_block_size, + .set_block_size = NULL, }; static int __devinit wl1271_probe(struct spi_device *spi) diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 542b785..30dc45a 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c @@ -145,14 +145,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, /* approximate the number of blocks required for this packet in the firmware */ - if (wl->host_cfg_bitmap & HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK) { - u32 sdio_block_mask = wl->block_size - 1; - int pad = (total_len + sdio_block_mask) & (~sdio_block_mask); - - total_blocks = pad + TX_HW_BLOCK_SIZE - 1; - } else { + if (wl->block_size) + total_blocks = ALIGN(total_len, wl->block_size) + + TX_HW_BLOCK_SIZE - 1; + else total_blocks = total_len + TX_HW_BLOCK_SIZE - 1; - } total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE; if (total_blocks <= wl->tx_blocks_available) { @@ -245,13 +242,10 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; desc->reserved = 0; - if (wl->host_cfg_bitmap & HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK) { - u32 sdio_block_mask = wl->block_size - 1; - int pad = (skb->len + sdio_block_mask) & - (~sdio_block_mask); + if (wl->block_size) { + pad = ALIGN(skb->len, wl->block_size); desc->wl128x_mem.extra_bytes = pad - skb->len; - desc->length = cpu_to_le16(pad >> 2); } else { /* align the length (and store in terms of words) */ @@ -323,19 +317,18 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, wl1271_tx_fill_hdr(wl, skb, extra, info, hlid); - if (wl->host_cfg_bitmap & HOST_IF_CFG_BITMAP_TX_PAD_TO_SDIO_BLK) { - unsigned sdio_block_mask = wl->block_size - 1; - - total_len = (skb->len + sdio_block_mask) & (~sdio_block_mask); - } else { - /* - * The length of each packet is stored in terms of words. Thus, - * we must pad the skb data to make sure its length is aligned. - * The number of padding bytes is computed and set in - * wl1271_tx_fill_hdr - */ + /* + * The length of each packet is stored in terms of + * words. Thus, we must pad the skb data to make sure its + * length is aligned. The number of padding bytes is computed + * and set in wl1271_tx_fill_hdr. + * In special cases, we want to align to a specific block size + * (eg. for wl128x with SDIO we align to 256). + */ + if (wl->block_size) + 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); 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 3072f95..e313177 100644 --- a/drivers/net/wireless/wl12xx/tx.h +++ b/drivers/net/wireless/wl12xx/tx.h @@ -57,29 +57,29 @@ struct wl127x_tx_mem { /* - * on wl127x: Number of extra memory blocks to allocate - * for this packet in addition to the number of blocks - * derived from the packet length + * Number of extra memory blocks to allocate for this packet + * in addition to the number of blocks derived from the packet + * length. */ u8 extra_blocks; /* - * on wl127x: Total number of memory blocks allocated by - * the host for this packet. Must be equal or greater - * than the actual blocks number allocated by HW!! + * Total number of memory blocks allocated by the host for + * this packet. Must be equal or greater than the actual + * blocks number allocated by HW. */ u8 total_mem_blocks; } __packed; struct wl128x_tx_mem { /* - * on wl128x: Total number of memory blocks allocated by - * the host for this packet. + * Total number of memory blocks allocated by the host for + * this packet. */ u8 total_mem_blocks; /* - * on wl128x: Number of extra bytes, at the end of the - * frame. the host uses this padding to complete each - * frame to integer number of SDIO blocks. + * Number of extra bytes, at the end of the frame. the host + * uses this padding to complete each frame to integer number + * of SDIO blocks. */ u8 extra_bytes; } __packed; @@ -95,7 +95,7 @@ struct wl1271_tx_hw_descr { __le32 start_time; /* * Max delay in TUs until transmission. The last device time the - * packet can be transmitted is: startTime+(1024*LifeTime) + * packet can be transmitted is: start_time + (1024 * life_time) */ __le16 life_time; /* Bitwise fields - see TX_ATTR... definitions above. */ diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 94b4062..959b338 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -534,9 +534,7 @@ struct wl1271 { bool ba_support; u8 ba_rx_bitmap; - /* wl128x features only */ - __le32 host_cfg_bitmap; - u32 block_size; + u32 block_size; /* * AP-mode - links indexed by HLID. The global and broadcast links -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html