wl12xx: Moved wl1251 TX path implementation into chip specific files

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>
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
index d43de27..7e05ea3 100644
--- a/drivers/net/wireless/wl12xx/Makefile
+++ b/drivers/net/wireless/wl12xx/Makefile
@@ -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
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 73232db..8feba36 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -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"
@@ -303,6 +303,11 @@
 
 	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);
 
 	/*
@@ -400,8 +405,7 @@
 	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);
@@ -1176,7 +1180,7 @@
 {
 	/* 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 */
@@ -1226,7 +1230,6 @@
 
 	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;
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
index b793325..903624a 100644
--- a/drivers/net/wireless/wl12xx/wl1251.c
+++ b/drivers/net/wireless/wl12xx/wl1251.c
@@ -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"
@@ -471,7 +471,7 @@
 
 	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)) {
@@ -712,9 +712,12 @@
 	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);
+
 }
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/wl1251_tx.c
similarity index 88%
rename from drivers/net/wireless/wl12xx/tx.c
rename to drivers/net/wireless/wl12xx/wl1251_tx.c
index 62145e2..c42c43d 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.c
@@ -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;
 
@@ -52,7 +52,7 @@
 		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;
@@ -60,7 +60,7 @@
 	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;
@@ -68,7 +68,7 @@
 	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;
 
@@ -81,7 +81,7 @@
 	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;
@@ -109,7 +109,7 @@
 #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;
@@ -142,7 +142,7 @@
 	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;
@@ -153,7 +153,7 @@
 	if (!skb)
 		return -EINVAL;
 
-	id = wl12xx_tx_id(wl, skb);
+	id = wl1251_tx_id(wl, skb);
 	if (id < 0)
 		return id;
 
@@ -170,14 +170,14 @@
 	/* 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;
@@ -196,12 +196,12 @@
 		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);
 	}
 
@@ -227,7 +227,7 @@
 	}
 
 	/* 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 +
@@ -243,7 +243,7 @@
 	return 0;
 }
 
-static void wl12xx_tx_trigger(struct wl12xx *wl)
+static void wl1251_tx_trigger(struct wl12xx *wl)
 {
 	u32 data, addr;
 
@@ -263,7 +263,7 @@
 }
 
 /* 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;
@@ -280,24 +280,24 @@
 		}
 	}
 
-	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;
@@ -315,7 +315,7 @@
 			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, "
@@ -337,7 +337,7 @@
 	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];
@@ -365,7 +365,7 @@
 	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;
@@ -396,14 +396,14 @@
 	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);
@@ -420,7 +420,7 @@
 		   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 "
@@ -440,7 +440,7 @@
 }
 
 /* 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;
@@ -459,7 +459,7 @@
 
 		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;
@@ -523,7 +523,7 @@
 }
 
 /* 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;
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/wl1251_tx.h
similarity index 93%
rename from drivers/net/wireless/wl12xx/tx.h
rename to drivers/net/wireless/wl12xx/wl1251_tx.h
index dc82691..a5d4c82 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_tx.h
@@ -22,8 +22,8 @@
  *
  */
 
-#ifndef __WL12XX_TX_H__
-#define __WL12XX_TX_H__
+#ifndef __WL1251_TX_H__
+#define __WL1251_TX_H__
 
 #include <linux/bitops.h>
 
@@ -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 */
@@ -208,8 +209,8 @@
 	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
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index c1d00c01..c38aa54 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -163,6 +163,7 @@
 	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;