Skip to content

Commit

Permalink
wl12xx: Moved wl1251 TX path implementation into chip specific files
Browse files Browse the repository at this point in the history
Moved wl1251 TX path implementation into chip specific files to enable
parallel implementation for the wl1271 TX path.

Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Juuso Oikarinen authored and John W. Linville committed Jul 10, 2009
1 parent 9f483dc commit 9f2ad4f
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 51 deletions.
4 changes: 2 additions & 2 deletions drivers/net/wireless/wl12xx/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
wl12xx-objs = main.o spi.o event.o tx.o rx.o \
ps.o cmd.o acx.o boot.o init.o wl1251.o \
wl12xx-objs = main.o spi.o event.o wl1251_tx.o rx.o \
ps.o cmd.o acx.o boot.o init.o wl1251.o \
debugfs.o
obj-$(CONFIG_WL12XX) += wl12xx.o
13 changes: 8 additions & 5 deletions drivers/net/wireless/wl12xx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include "wl1251.h"
#include "spi.h"
#include "event.h"
#include "tx.h"
#include "wl1251_tx.h"
#include "rx.h"
#include "ps.h"
#include "init.h"
Expand Down Expand Up @@ -303,6 +303,11 @@ static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)

skb_queue_tail(&wl->tx_queue, skb);

/*
* The chip specific setup must run before the first TX packet -
* before that, the tx_work will not be initialized!
*/

schedule_work(&wl->tx_work);

/*
Expand Down Expand Up @@ -400,8 +405,7 @@ static void wl12xx_op_stop(struct ieee80211_hw *hw)
mutex_lock(&wl->mutex);

/* let's notify MAC80211 about the remaining pending TX frames */
wl12xx_tx_flush(wl);

wl->chip.op_tx_flush(wl);
wl12xx_power_off(wl);

memset(wl->bssid, 0, ETH_ALEN);
Expand Down Expand Up @@ -1176,7 +1180,7 @@ static int wl12xx_init_ieee80211(struct wl12xx *wl)
{
/* The tx descriptor buffer and the TKIP space */
wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+ WL12XX_TKIP_IV_SPACE;
+ WL1251_TKIP_IV_SPACE;

/* unit us */
/* FIXME: find a proper value */
Expand Down Expand Up @@ -1226,7 +1230,6 @@ static int __devinit wl12xx_probe(struct spi_device *spi)

skb_queue_head_init(&wl->tx_queue);

INIT_WORK(&wl->tx_work, wl12xx_tx_work);
INIT_WORK(&wl->filter_work, wl12xx_filter_work);
wl->channel = WL12XX_DEFAULT_CHANNEL;
wl->scanning = false;
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/wl12xx/wl1251.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include "boot.h"
#include "event.h"
#include "acx.h"
#include "tx.h"
#include "wl1251_tx.h"
#include "rx.h"
#include "ps.h"
#include "init.h"
Expand Down Expand Up @@ -471,7 +471,7 @@ static void wl1251_irq_work(struct work_struct *work)

if (intr & WL1251_ACX_INTR_TX_RESULT) {
wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
wl12xx_tx_complete(wl);
wl1251_tx_complete(wl);
}

if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
Expand Down Expand Up @@ -712,9 +712,12 @@ void wl1251_setup(struct wl12xx *wl)
wl->chip.op_hw_init = wl1251_hw_init;
wl->chip.op_plt_init = wl1251_plt_init;
wl->chip.op_fw_version = wl1251_fw_version;
wl->chip.op_tx_flush = wl1251_tx_flush;

wl->chip.p_table = wl1251_part_table;
wl->chip.acx_reg_table = wl1251_acx_reg_table;

INIT_WORK(&wl->irq_work, wl1251_irq_work);
INIT_WORK(&wl->tx_work, wl1251_tx_work);

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
#include "wl12xx.h"
#include "reg.h"
#include "spi.h"
#include "tx.h"
#include "wl1251_tx.h"
#include "ps.h"

static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
static bool wl1251_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
{
int used, data_in_count;

Expand All @@ -52,23 +52,23 @@ static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
return false;
}

static int wl12xx_tx_path_status(struct wl12xx *wl)
static int wl1251_tx_path_status(struct wl12xx *wl)
{
u32 status, addr, data_out_count;
bool busy;

addr = wl->data_path->tx_control_addr;
status = wl12xx_mem_read32(wl, addr);
data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
busy = wl1251_tx_double_buffer_busy(wl, data_out_count);

if (busy)
return -EBUSY;

return 0;
}

static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
static int wl1251_tx_id(struct wl12xx *wl, struct sk_buff *skb)
{
int i;

Expand All @@ -81,7 +81,7 @@ static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
return -EBUSY;
}

static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
static void wl1251_tx_control(struct tx_double_buffer_desc *tx_hdr,
struct ieee80211_tx_info *control, u16 fc)
{
*(u16 *)&tx_hdr->control = 0;
Expand Down Expand Up @@ -109,7 +109,7 @@ static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
#define MAX_MPDU_HEADER_AND_SECURITY (MAX_MPDU_SECURITY_LENGTH + \
WLAN_QOS_HDR_LEN)
#define HW_BLOCK_SIZE 252
static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
static void wl1251_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
{
u16 payload_len, frag_threshold, mem_blocks;
u16 num_mpdus, mem_blocks_per_frag;
Expand Down Expand Up @@ -142,7 +142,7 @@ static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
tx_hdr->num_mem_blocks = mem_blocks;
}

static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
static int wl1251_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
struct ieee80211_tx_info *control)
{
struct tx_double_buffer_desc *tx_hdr;
Expand All @@ -153,7 +153,7 @@ static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
if (!skb)
return -EINVAL;

id = wl12xx_tx_id(wl, skb);
id = wl1251_tx_id(wl, skb);
if (id < 0)
return id;

Expand All @@ -170,14 +170,14 @@ static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
/* FIXME: how to get the correct queue id? */
tx_hdr->xmit_queue = 0;

wl12xx_tx_control(tx_hdr, control, fc);
wl12xx_tx_frag_block_num(tx_hdr);
wl1251_tx_control(tx_hdr, control, fc);
wl1251_tx_frag_block_num(tx_hdr);

return 0;
}

/* We copy the packet to the target */
static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
static int wl1251_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
struct ieee80211_tx_info *control)
{
struct tx_double_buffer_desc *tx_hdr;
Expand All @@ -196,12 +196,12 @@ static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
u8 *pos;

fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
tx_hdr->length += WL12XX_TKIP_IV_SPACE;
tx_hdr->length += WL1251_TKIP_IV_SPACE;

hdrlen = ieee80211_hdrlen(fc);

pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
pos = skb_push(skb, WL1251_TKIP_IV_SPACE);
memmove(pos, pos + WL1251_TKIP_IV_SPACE,
sizeof(*tx_hdr) + hdrlen);
}

Expand All @@ -227,7 +227,7 @@ static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
}

/* Our skb->data at this point includes the HW header */
len = WL12XX_TX_ALIGN(skb->len);
len = WL1251_TX_ALIGN(skb->len);

if (wl->data_in_count & 0x1)
addr = wl->data_path->tx_packet_ring_addr +
Expand All @@ -243,7 +243,7 @@ static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
return 0;
}

static void wl12xx_tx_trigger(struct wl12xx *wl)
static void wl1251_tx_trigger(struct wl12xx *wl)
{
u32 data, addr;

Expand All @@ -263,7 +263,7 @@ static void wl12xx_tx_trigger(struct wl12xx *wl)
}

/* caller must hold wl->mutex */
static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
static int wl1251_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
{
struct ieee80211_tx_info *info;
int ret = 0;
Expand All @@ -280,24 +280,24 @@ static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
}
}

ret = wl12xx_tx_path_status(wl);
ret = wl1251_tx_path_status(wl);
if (ret < 0)
return ret;

ret = wl12xx_tx_fill_hdr(wl, skb, info);
ret = wl1251_tx_fill_hdr(wl, skb, info);
if (ret < 0)
return ret;

ret = wl12xx_tx_send_packet(wl, skb, info);
ret = wl1251_tx_send_packet(wl, skb, info);
if (ret < 0)
return ret;

wl12xx_tx_trigger(wl);
wl1251_tx_trigger(wl);

return ret;
}

void wl12xx_tx_work(struct work_struct *work)
void wl1251_tx_work(struct work_struct *work)
{
struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
struct sk_buff *skb;
Expand All @@ -315,7 +315,7 @@ void wl12xx_tx_work(struct work_struct *work)
woken_up = true;
}

ret = wl12xx_tx_frame(wl, skb);
ret = wl1251_tx_frame(wl, skb);
if (ret == -EBUSY) {
/* firmware buffer is full, stop queues */
wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
Expand All @@ -337,7 +337,7 @@ void wl12xx_tx_work(struct work_struct *work)
mutex_unlock(&wl->mutex);
}

static const char *wl12xx_tx_parse_status(u8 status)
static const char *wl1251_tx_parse_status(u8 status)
{
/* 8 bit status field, one character per bit plus null */
static char buf[9];
Expand Down Expand Up @@ -365,7 +365,7 @@ static const char *wl12xx_tx_parse_status(u8 status)
return buf;
}

static void wl12xx_tx_packet_cb(struct wl12xx *wl,
static void wl1251_tx_packet_cb(struct wl12xx *wl,
struct tx_result *result)
{
struct ieee80211_tx_info *info;
Expand Down Expand Up @@ -396,14 +396,14 @@ static void wl12xx_tx_packet_cb(struct wl12xx *wl,
if (info->control.hw_key &&
info->control.hw_key->alg == ALG_TKIP) {
hdrlen = ieee80211_get_hdrlen_from_skb(skb);
memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
skb_pull(skb, WL12XX_TKIP_IV_SPACE);
memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen);
skb_pull(skb, WL1251_TKIP_IV_SPACE);
}

wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
" status 0x%x (%s)",
result->id, skb, result->ack_failures, result->rate,
result->status, wl12xx_tx_parse_status(result->status));
result->status, wl1251_tx_parse_status(result->status));


ieee80211_tx_status(wl->hw, skb);
Expand All @@ -420,7 +420,7 @@ static void wl12xx_tx_packet_cb(struct wl12xx *wl,
queue empty */

if (skb) {
ret = wl12xx_tx_frame(wl, skb);
ret = wl1251_tx_frame(wl, skb);
if (ret == -EBUSY) {
/* firmware buffer is still full */
wl12xx_debug(DEBUG_TX, "cb: fw buffer "
Expand All @@ -440,7 +440,7 @@ static void wl12xx_tx_packet_cb(struct wl12xx *wl,
}

/* Called upon reception of a TX complete interrupt */
void wl12xx_tx_complete(struct wl12xx *wl)
void wl1251_tx_complete(struct wl12xx *wl)
{
int i, result_index, num_complete = 0;
struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
Expand All @@ -459,7 +459,7 @@ void wl12xx_tx_complete(struct wl12xx *wl)

if (result_ptr->done_1 == 1 &&
result_ptr->done_2 == 1) {
wl12xx_tx_packet_cb(wl, result_ptr);
wl1251_tx_packet_cb(wl, result_ptr);

result_ptr->done_1 = 0;
result_ptr->done_2 = 0;
Expand Down Expand Up @@ -523,7 +523,7 @@ void wl12xx_tx_complete(struct wl12xx *wl)
}

/* caller must hold wl->mutex */
void wl12xx_tx_flush(struct wl12xx *wl)
void wl1251_tx_flush(struct wl12xx *wl)
{
int i;
struct sk_buff *skb;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
*
*/

#ifndef __WL12XX_TX_H__
#define __WL12XX_TX_H__
#ifndef __WL1251_TX_H__
#define __WL1251_TX_H__

#include <linux/bitops.h>

Expand Down Expand Up @@ -73,10 +73,11 @@

#define TX_COMPLETE_REQUIRED_BIT 0x80
#define TX_STATUS_DATA_OUT_COUNT_MASK 0xf
#define WL12XX_TX_ALIGN_TO 4
#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
~(WL12XX_TX_ALIGN_TO - 1))
#define WL12XX_TKIP_IV_SPACE 4

#define WL1251_TX_ALIGN_TO 4
#define WL1251_TX_ALIGN(len) (((len) + WL1251_TX_ALIGN_TO - 1) & \
~(WL1251_TX_ALIGN_TO - 1))
#define WL1251_TKIP_IV_SPACE 4

struct tx_control {
/* Rate Policy (class) index */
Expand Down Expand Up @@ -208,8 +209,8 @@ struct tx_result {
u8 done_2;
} __attribute__ ((packed));

void wl12xx_tx_work(struct work_struct *work);
void wl12xx_tx_complete(struct wl12xx *wl);
void wl12xx_tx_flush(struct wl12xx *wl);
void wl1251_tx_work(struct work_struct *work);
void wl1251_tx_complete(struct wl12xx *wl);
void wl1251_tx_flush(struct wl12xx *wl);

#endif
1 change: 1 addition & 0 deletions drivers/net/wireless/wl12xx/wl12xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ struct wl12xx_chip {
void (*op_target_enable_interrupts)(struct wl12xx *wl);
int (*op_hw_init)(struct wl12xx *wl);
int (*op_plt_init)(struct wl12xx *wl);
void (*op_tx_flush)(struct wl12xx *wl);
void (*op_fw_version)(struct wl12xx *wl);

struct wl12xx_partition_set *p_table;
Expand Down

0 comments on commit 9f2ad4f

Please sign in to comment.