wlcore/wl12xx: add hw op for calculating hw block count per packet
Each chip family has a different block size and calculates the total number of HW blocks differently, with respect to alignment. Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
This commit is contained in:
committed by
Luciano Coelho
parent
3edab305df
commit
b3b4b4b812
@@ -30,12 +30,14 @@
|
|||||||
#include "../wlcore/debug.h"
|
#include "../wlcore/debug.h"
|
||||||
#include "../wlcore/io.h"
|
#include "../wlcore/io.h"
|
||||||
#include "../wlcore/acx.h"
|
#include "../wlcore/acx.h"
|
||||||
|
#include "../wlcore/tx.h"
|
||||||
#include "../wlcore/boot.h"
|
#include "../wlcore/boot.h"
|
||||||
|
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
|
|
||||||
#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
|
#define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
|
||||||
#define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
|
#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] = {
|
static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
|
||||||
@@ -587,6 +589,14 @@ static void wl12xx_ack_event(struct wl1271 *wl)
|
|||||||
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
|
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)
|
static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
|
||||||
{
|
{
|
||||||
bool supported = false;
|
bool supported = false;
|
||||||
@@ -655,6 +665,7 @@ static struct wlcore_ops wl12xx_ops = {
|
|||||||
.boot = wl12xx_boot,
|
.boot = wl12xx_boot,
|
||||||
.trigger_cmd = wl12xx_trigger_cmd,
|
.trigger_cmd = wl12xx_trigger_cmd,
|
||||||
.ack_event = wl12xx_ack_event,
|
.ack_event = wl12xx_ack_event,
|
||||||
|
.calc_tx_blocks = wl12xx_calc_tx_blocks,
|
||||||
.get_pg_ver = wl12xx_get_pg_ver,
|
.get_pg_ver = wl12xx_get_pg_ver,
|
||||||
.get_mac = wl12xx_get_mac,
|
.get_mac = wl12xx_get_mac,
|
||||||
};
|
};
|
||||||
|
36
drivers/net/wireless/ti/wlcore/hw_ops.h
Normal file
36
drivers/net/wireless/ti/wlcore/hw_ops.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
@@ -31,6 +31,7 @@
|
|||||||
#include "ps.h"
|
#include "ps.h"
|
||||||
#include "tx.h"
|
#include "tx.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "hw_ops.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: this is here just for now, it must be removed when the data
|
* TODO: this is here just for now, it must be removed when the data
|
||||||
@@ -172,14 +173,15 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
return wlvif->dev_hlid;
|
return wlvif->dev_hlid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
|
unsigned int wlcore_calc_packet_alignment(struct wl1271 *wl,
|
||||||
unsigned int packet_length)
|
unsigned int packet_length)
|
||||||
{
|
{
|
||||||
if (wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
|
if (wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
|
||||||
return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
|
return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
|
||||||
else
|
else
|
||||||
return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
|
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,
|
static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
||||||
struct sk_buff *skb, u32 extra, u32 buf_offset,
|
struct sk_buff *skb, u32 extra, u32 buf_offset,
|
||||||
@@ -187,7 +189,6 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
{
|
{
|
||||||
struct wl1271_tx_hw_descr *desc;
|
struct wl1271_tx_hw_descr *desc;
|
||||||
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
|
u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
|
||||||
u32 len;
|
|
||||||
u32 total_blocks;
|
u32 total_blocks;
|
||||||
int id, ret = -EBUSY, ac;
|
int id, ret = -EBUSY, ac;
|
||||||
u32 spare_blocks = wl->normal_tx_spare;
|
u32 spare_blocks = wl->normal_tx_spare;
|
||||||
@@ -201,17 +202,12 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
if (id < 0)
|
if (id < 0)
|
||||||
return id;
|
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)))
|
if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
|
||||||
is_dummy = true;
|
is_dummy = true;
|
||||||
else if (wlvif->is_gem)
|
else if (wlvif->is_gem)
|
||||||
spare_blocks = wl->gem_tx_spare;
|
spare_blocks = wl->gem_tx_spare;
|
||||||
|
|
||||||
total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
|
total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks);
|
||||||
spare_blocks;
|
|
||||||
|
|
||||||
if (total_blocks <= wl->tx_blocks_available) {
|
if (total_blocks <= wl->tx_blocks_available) {
|
||||||
desc = (struct wl1271_tx_hw_descr *)skb_push(
|
desc = (struct wl1271_tx_hw_descr *)skb_push(
|
||||||
@@ -335,7 +331,7 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
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;
|
||||||
|
|
||||||
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) {
|
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;
|
||||||
@@ -436,7 +432,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
|
|||||||
* 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).
|
||||||
*/
|
*/
|
||||||
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);
|
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);
|
||||||
|
@@ -25,8 +25,6 @@
|
|||||||
#ifndef __TX_H__
|
#ifndef __TX_H__
|
||||||
#define __TX_H__
|
#define __TX_H__
|
||||||
|
|
||||||
#define TX_HW_BLOCK_SIZE 252
|
|
||||||
|
|
||||||
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
|
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
|
||||||
#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
|
#define TX_HW_AP_MODE_PKT_LIFETIME_TU 8000
|
||||||
|
|
||||||
@@ -223,6 +221,8 @@ void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid);
|
|||||||
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
|
void wl1271_handle_tx_low_watermark(struct wl1271 *wl);
|
||||||
bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
|
bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb);
|
||||||
void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids);
|
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 */
|
/* from main.c */
|
||||||
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
|
void wl1271_free_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 hlid);
|
||||||
|
@@ -35,6 +35,7 @@ struct wlcore_ops {
|
|||||||
int (*boot)(struct wl1271 *wl);
|
int (*boot)(struct wl1271 *wl);
|
||||||
void (*trigger_cmd)(struct wl1271 *wl);
|
void (*trigger_cmd)(struct wl1271 *wl);
|
||||||
void (*ack_event)(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);
|
s8 (*get_pg_ver)(struct wl1271 *wl);
|
||||||
void (*get_mac)(struct wl1271 *wl);
|
void (*get_mac)(struct wl1271 *wl);
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user