diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index c8f314814e5dc7a69fe60d62d6a37f964245f2b3..eafa02006bcca07e76dcc9c57a1e1cd37529870b 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -609,6 +609,41 @@ wl12xx_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, } } +static void +wl12xx_set_tx_desc_data_len(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + u32 aligned_len = wlcore_calc_packet_alignment(wl, skb->len); + + if (wl->chip.id == CHIP_ID_1283_PG20) { + desc->wl128x_mem.extra_bytes = aligned_len - skb->len; + desc->length = cpu_to_le16(aligned_len >> 2); + + wl1271_debug(DEBUG_TX, + "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d", + desc->hlid, + le16_to_cpu(desc->length), + le16_to_cpu(desc->life_time), + desc->wl128x_mem.total_mem_blocks, + desc->wl128x_mem.extra_bytes); + } else { + /* calculate number of padding bytes */ + int pad = aligned_len - skb->len; + desc->tx_attr |= + cpu_to_le16(pad << TX_HW_ATTR_OFST_LAST_WORD_PAD); + + /* Store the aligned length in terms of words */ + desc->length = cpu_to_le16(aligned_len >> 2); + + wl1271_debug(DEBUG_TX, + "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d", + pad, desc->hlid, + le16_to_cpu(desc->length), + le16_to_cpu(desc->life_time), + desc->wl127x_mem.total_mem_blocks); + } +} + static bool wl12xx_mac_in_fuse(struct wl1271 *wl) { bool supported = false; @@ -679,6 +714,7 @@ static struct wlcore_ops wl12xx_ops = { .ack_event = wl12xx_ack_event, .calc_tx_blocks = wl12xx_calc_tx_blocks, .set_tx_desc_blocks = wl12xx_set_tx_desc_blocks, + .set_tx_desc_data_len = wl12xx_set_tx_desc_data_len, .get_pg_ver = wl12xx_get_pg_ver, .get_mac = wl12xx_get_mac, }; diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 02b55936aaab6dba6dd7a0b8812584ffde702321..7342f86020cec68b2e238efa9bb1300349d4125c 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -43,4 +43,15 @@ wlcore_hw_set_tx_desc_blocks(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, return wl->ops->set_tx_desc_blocks(wl, desc, blks, spare_blks); } +static inline void +wlcore_hw_set_tx_desc_data_len(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb) +{ + if (!wl->ops->set_tx_desc_data_len) + BUG_ON(1); + + wl->ops->set_tx_desc_data_len(wl, desc, skb); +} + #endif diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index d834758b1a375880b127268d3c155daecaf4a6c2..be8fcfd95b3f12533b3dd7c63733dadcefe66214 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -251,7 +251,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, { struct timespec ts; struct wl1271_tx_hw_descr *desc; - int aligned_len, ac, rate_idx; + int ac, rate_idx; s64 hosttime; u16 tx_attr = 0; __le16 frame_control; @@ -324,44 +324,16 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, } tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY; - desc->reserved = 0; - - aligned_len = wlcore_calc_packet_alignment(wl, skb->len); - - if (wl->chip.id == CHIP_ID_1283_PG20) { - desc->wl128x_mem.extra_bytes = aligned_len - skb->len; - desc->length = cpu_to_le16(aligned_len >> 2); - - wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d " - "tx_attr: 0x%x len: %d life: %d mem: %d", - desc->hlid, tx_attr, - le16_to_cpu(desc->length), - le16_to_cpu(desc->life_time), - desc->wl128x_mem.total_mem_blocks); - } else { - int pad; - - /* Store the aligned length in terms of words */ - desc->length = cpu_to_le16(aligned_len >> 2); - - /* calculate number of padding bytes */ - pad = aligned_len - skb->len; - tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; - - wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d " - "tx_attr: 0x%x len: %d life: %d mem: %d", pad, - desc->hlid, tx_attr, - le16_to_cpu(desc->length), - le16_to_cpu(desc->life_time), - desc->wl127x_mem.total_mem_blocks); - } /* for WEP shared auth - no fw encryption is needed */ if (ieee80211_is_auth(frame_control) && ieee80211_has_protected(frame_control)) tx_attr |= TX_HW_ATTR_HOST_ENCRYPT; + desc->reserved = 0; desc->tx_attr = cpu_to_le16(tx_attr); + + wlcore_hw_set_tx_desc_data_len(wl, desc, skb); } /* caller must hold wl->mutex */ diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index f0ce69dd13ab37ca7183ee5662eefd01a48e77d1..fa636e2cd20f05a99e1e7ac9a17c9c63d47a45f0 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -41,6 +41,9 @@ struct wlcore_ops { void (*set_tx_desc_blocks)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, u32 blks, u32 spare_blks); + void (*set_tx_desc_data_len)(struct wl1271 *wl, + struct wl1271_tx_hw_descr *desc, + struct sk_buff *skb); s8 (*get_pg_ver)(struct wl1271 *wl); void (*get_mac)(struct wl1271 *wl); };