#include "../wlcore/debug.h"
#include "../wlcore/io.h"
#include "../wlcore/acx.h"
+#include "../wlcore/tx.h"
#include "../wlcore/boot.h"
#include "reg.h"
#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
+#define WL12XX_TX_HW_BLOCK_SIZE 252
static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
}
+static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
+{
+ u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
+ u32 align_len = wlcore_calc_packet_alignment(wl, len);
+
+ return (align_len + blk_size - 1) / blk_size + spare_blks;
+}
+
static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
{
bool supported = false;
.boot = wl12xx_boot,
.trigger_cmd = wl12xx_trigger_cmd,
.ack_event = wl12xx_ack_event,
+ .calc_tx_blocks = wl12xx_calc_tx_blocks,
.get_pg_ver = wl12xx_get_pg_ver,
.get_mac = wl12xx_get_mac,
};
--- /dev/null
+/*
+ * This file is part of wlcore
+ *
+ * Copyright (C) 2011 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WLCORE_HW_OPS_H__
+#define __WLCORE_HW_OPS_H__
+
+#include "wlcore.h"
+
+static inline u32
+wlcore_hw_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
+{
+ if (!wl->ops->calc_tx_blocks)
+ BUG_ON(1);
+
+ return wl->ops->calc_tx_blocks(wl, len, spare_blks);
+}
+
+#endif
#include "ps.h"
#include "tx.h"
#include "event.h"
+#include "hw_ops.h"
/*
* TODO: this is here just for now, it must be removed when the data
return wlvif->dev_hlid;
}
-static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
- unsigned int packet_length)
+unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
+ unsigned int packet_length)
{
if (wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
else
return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
}
+EXPORT_SYMBOL(wlcore_calc_packet_alignment);
static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct sk_buff *skb, u32 extra, u32 buf_offset,
{
struct wl1271_tx_hw_descr *desc;
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
- u32 len;
u32 total_blocks;
int id, ret = -EBUSY, ac;
u32 spare_blocks = wl->normal_tx_spare;
if (id < 0)
return id;
- /* approximate the number of blocks required for this packet
- in the firmware */
- len = wl12xx_calc_packet_alignment(wl, total_len);
-
if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
is_dummy = true;
else if (wlvif->is_gem)
spare_blocks = wl->gem_tx_spare;
- total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
- spare_blocks;
+ total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
if (total_blocks <= wl->tx_blocks_available) {
desc = (struct wl1271_tx_hw_descr *)skb_push(
tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
desc->reserved = 0;
- aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
+ 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;
* In special cases, we want to align to a specific block size
* (eg. for wl128x with SDIO we align to 256).
*/
- total_len = wl12xx_calc_packet_alignment(wl, skb->len);
+ total_len = wlcore_calc_packet_alignment(wl, 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);
#ifndef __TX_H__
#define __TX_H__
-#define TX_HW_BLOCK_SIZE 252
-
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
+unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
+ unsigned int packet_length);
/* from main.c */
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
int (*boot)(struct wl1271 *wl);
void (*trigger_cmd)(struct wl1271 *wl);
void (*ack_event)(struct wl1271 *wl);
+ u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks);
s8 (*get_pg_ver)(struct wl1271 *wl);
void (*get_mac)(struct wl1271 *wl);
};